diff options
| author | Lars Ingebrigtsen | 2021-11-10 00:26:32 +0100 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2021-11-10 00:26:32 +0100 |
| commit | 2e6ed253ce485698df649904bd9e5254a3f4bf94 (patch) | |
| tree | 80d51ebb50d65eddd987b89e93d4d52499a48109 | |
| parent | fdc00b98361300861db6402e021d335025f6e8ce (diff) | |
| download | emacs-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.texi | 13 | ||||
| -rw-r--r-- | etc/NEWS | 4 | ||||
| -rw-r--r-- | lisp/emacs-lisp/shortdoc.el | 3 | ||||
| -rw-r--r-- | lisp/files.el | 23 | ||||
| -rw-r--r-- | test/lisp/files-tests.el | 6 |
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 | ||
| 2248 | This function splits a file name into its components, and can be | ||
| 2249 | thought of as the inverse of @code{string-joing} with the appropriate | ||
| 2250 | directory 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 |
| @@ -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'. | ||
| 617 | This 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' |
| 617 | It records a particular sequence of operations as a single undo step | 621 | It 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. | ||
| 5056 | On 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 |