aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2021-11-10 00:26:32 +0100
committerLars Ingebrigtsen2021-11-10 00:26:32 +0100
commit2e6ed253ce485698df649904bd9e5254a3f4bf94 (patch)
tree80d51ebb50d65eddd987b89e93d4d52499a48109
parentfdc00b98361300861db6402e021d335025f6e8ce (diff)
downloademacs-2e6ed253ce485698df649904bd9e5254a3f4bf94.tar.gz
emacs-2e6ed253ce485698df649904bd9e5254a3f4bf94.zip
Add new function 'file-name-split'
* doc/lispref/files.texi (File Name Components): Document it. * lisp/files.el (file-name-split): New function (bug#50572). * lisp/emacs-lisp/shortdoc.el (file-name): Mention it.
-rw-r--r--doc/lispref/files.texi13
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/emacs-lisp/shortdoc.el3
-rw-r--r--lisp/files.el23
-rw-r--r--test/lisp/files-tests.el6
5 files changed, 49 insertions, 0 deletions
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index ddc1d05c1ca..dd058b12158 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -2244,6 +2244,19 @@ and @code{file-name-nondirectory}. For example,
2244@end example 2244@end example
2245@end defun 2245@end defun
2246 2246
2247@defun file-name-split filename
2248This function splits a file name into its components, and can be
2249thought of as the inverse of @code{string-joing} with the appropriate
2250directory separator. For example,
2251
2252@example
2253(file-name-split "/tmp/foo.txt")
2254 @result{} ("" "tmp" "foo.txt")
2255(string-join (file-name-split "/tmp/foo.txt") "/")
2256 @result{} "/tmp/foo.txt"
2257@end example
2258@end defun
2259
2247@node Relative File Names 2260@node Relative File Names
2248@subsection Absolute and Relative File Names 2261@subsection Absolute and Relative File Names
2249@cindex absolute file name 2262@cindex absolute file name
diff --git a/etc/NEWS b/etc/NEWS
index 807f31fa33e..3cad0995ac5 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -613,6 +613,10 @@ Use 'exif-parse-file' and 'exif-field' instead.
613* Lisp Changes in Emacs 29.1 613* Lisp Changes in Emacs 29.1
614 614
615+++ 615+++
616*** New function 'file-name-split'.
617This returns a list of all the components of a file name.
618
619+++
616*** New macro 'with-undo-amalgamate' 620*** New macro 'with-undo-amalgamate'
617It records a particular sequence of operations as a single undo step 621It records a particular sequence of operations as a single undo step
618 622
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el
index c3d6c742940..a9f548b104e 100644
--- a/lisp/emacs-lisp/shortdoc.el
+++ b/lisp/emacs-lisp/shortdoc.el
@@ -281,6 +281,9 @@ There can be any number of :example/:result elements."
281 :eval (file-name-base "/tmp/foo.txt")) 281 :eval (file-name-base "/tmp/foo.txt"))
282 (file-relative-name 282 (file-relative-name
283 :eval (file-relative-name "/tmp/foo" "/tmp")) 283 :eval (file-relative-name "/tmp/foo" "/tmp"))
284 (file-name-split
285 :eval (file-name-split "/tmp/foo")
286 :eval (file-name-split "foo/bar"))
284 (make-temp-name 287 (make-temp-name
285 :eval (make-temp-name "/tmp/foo-")) 288 :eval (make-temp-name "/tmp/foo-"))
286 (file-name-concat 289 (file-name-concat
diff --git a/lisp/files.el b/lisp/files.el
index 0bc7a92fbea..c694df38268 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5051,6 +5051,29 @@ See also `file-name-sans-extension'."
5051 (file-name-sans-extension 5051 (file-name-sans-extension
5052 (file-name-nondirectory (or filename (buffer-file-name))))) 5052 (file-name-nondirectory (or filename (buffer-file-name)))))
5053 5053
5054(defun file-name-split (filename)
5055 "Return a list of all the components of FILENAME.
5056On most systems, this will be true:
5057
5058 (equal (string-join (file-name-split filename) \"/\") filename)"
5059 (let ((components nil))
5060 ;; If this is a directory file name, then we have a null file name
5061 ;; at the end.
5062 (when (directory-name-p filename)
5063 (push "" components)
5064 (setq filename (directory-file-name filename)))
5065 ;; Loop, chopping off components.
5066 (while (length> filename 0)
5067 (push (file-name-nondirectory filename) components)
5068 (let ((dir (file-name-directory filename)))
5069 (setq filename (and dir (directory-file-name dir)))
5070 ;; If there's nothing left to peel off, we're at the root and
5071 ;; we can stop.
5072 (when (equal dir filename)
5073 (push "" components)
5074 (setq filename nil))))
5075 components))
5076
5054(defcustom make-backup-file-name-function 5077(defcustom make-backup-file-name-function
5055 #'make-backup-file-name--default-function 5078 #'make-backup-file-name--default-function
5056 "A function that `make-backup-file-name' uses to create backup file names. 5079 "A function that `make-backup-file-name' uses to create backup file names.
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index c6d7c19279b..1e20317739a 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -1800,6 +1800,12 @@ Prompt users for any modified buffer with `buffer-offer-save' non-nil."
1800 ;; `save-some-buffers-default-predicate' (i.e. the 2nd element) is ignored. 1800 ;; `save-some-buffers-default-predicate' (i.e. the 2nd element) is ignored.
1801 (nil save-some-buffers-root ,nb-might-save)))))) 1801 (nil save-some-buffers-root ,nb-might-save))))))
1802 1802
1803(defun test-file-name-split ()
1804 (should (equal (file-name-split "foo/bar") '("foo" "bar")))
1805 (should (equal (file-name-split "/foo/bar") '("" "foo" "bar")))
1806 (should (equal (file-name-split "/foo/bar/zot") '("" "foo" "bar" "zot")))
1807 (should (equal (file-name-split "/foo/bar/") '("" "foo" "bar" "")))
1808 (should (equal (file-name-split "foo/bar/") '("foo" "bar" ""))))
1803 1809
1804(provide 'files-tests) 1810(provide 'files-tests)
1805;;; files-tests.el ends here 1811;;; files-tests.el ends here