[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 2e6ed25: Add new function 'file-name-split'
From: |
Lars Ingebrigtsen |
Subject: |
master 2e6ed25: Add new function 'file-name-split' |
Date: |
Tue, 9 Nov 2021 18:26:41 -0500 (EST) |
branch: master
commit 2e6ed253ce485698df649904bd9e5254a3f4bf94
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>
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.
---
doc/lispref/files.texi | 13 +++++++++++++
etc/NEWS | 4 ++++
lisp/emacs-lisp/shortdoc.el | 3 +++
lisp/files.el | 23 +++++++++++++++++++++++
test/lisp/files-tests.el | 6 ++++++
5 files changed, 49 insertions(+)
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index ddc1d05..dd058b1 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -2244,6 +2244,19 @@ and @code{file-name-nondirectory}. For example,
@end example
@end defun
+@defun file-name-split filename
+This function splits a file name into its components, and can be
+thought of as the inverse of @code{string-joing} with the appropriate
+directory separator. For example,
+
+@example
+(file-name-split "/tmp/foo.txt")
+ @result{} ("" "tmp" "foo.txt")
+(string-join (file-name-split "/tmp/foo.txt") "/")
+ @result{} "/tmp/foo.txt"
+@end example
+@end defun
+
@node Relative File Names
@subsection Absolute and Relative File Names
@cindex absolute file name
diff --git a/etc/NEWS b/etc/NEWS
index 807f31f..3cad099 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -613,6 +613,10 @@ Use 'exif-parse-file' and 'exif-field' instead.
* Lisp Changes in Emacs 29.1
+++
+*** New function 'file-name-split'.
+This returns a list of all the components of a file name.
+
++++
*** New macro 'with-undo-amalgamate'
It records a particular sequence of operations as a single undo step
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el
index c3d6c74..a9f548b 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."
:eval (file-name-base "/tmp/foo.txt"))
(file-relative-name
:eval (file-relative-name "/tmp/foo" "/tmp"))
+ (file-name-split
+ :eval (file-name-split "/tmp/foo")
+ :eval (file-name-split "foo/bar"))
(make-temp-name
:eval (make-temp-name "/tmp/foo-"))
(file-name-concat
diff --git a/lisp/files.el b/lisp/files.el
index 0bc7a92..c694df3 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5051,6 +5051,29 @@ See also `file-name-sans-extension'."
(file-name-sans-extension
(file-name-nondirectory (or filename (buffer-file-name)))))
+(defun file-name-split (filename)
+ "Return a list of all the components of FILENAME.
+On most systems, this will be true:
+
+ (equal (string-join (file-name-split filename) \"/\") filename)"
+ (let ((components nil))
+ ;; If this is a directory file name, then we have a null file name
+ ;; at the end.
+ (when (directory-name-p filename)
+ (push "" components)
+ (setq filename (directory-file-name filename)))
+ ;; Loop, chopping off components.
+ (while (length> filename 0)
+ (push (file-name-nondirectory filename) components)
+ (let ((dir (file-name-directory filename)))
+ (setq filename (and dir (directory-file-name dir)))
+ ;; If there's nothing left to peel off, we're at the root and
+ ;; we can stop.
+ (when (equal dir filename)
+ (push "" components)
+ (setq filename nil))))
+ components))
+
(defcustom make-backup-file-name-function
#'make-backup-file-name--default-function
"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 c6d7c19..1e20317 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."
;; `save-some-buffers-default-predicate' (i.e. the 2nd element) is
ignored.
(nil save-some-buffers-root ,nb-might-save))))))
+(defun test-file-name-split ()
+ (should (equal (file-name-split "foo/bar") '("foo" "bar")))
+ (should (equal (file-name-split "/foo/bar") '("" "foo" "bar")))
+ (should (equal (file-name-split "/foo/bar/zot") '("" "foo" "bar" "zot")))
+ (should (equal (file-name-split "/foo/bar/") '("" "foo" "bar" "")))
+ (should (equal (file-name-split "foo/bar/") '("foo" "bar" ""))))
(provide 'files-tests)
;;; files-tests.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 2e6ed25: Add new function 'file-name-split',
Lars Ingebrigtsen <=