From: Daanturo Date: Mon, 4 Jul 2022 11:07:51 +0000 (+0200) Subject: Add file-parent-directory function X-Git-Tag: emacs-29.0.90~1447^2~1207 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=1ac383bcb69578ac9e89ab00538d81ee8daee022;p=emacs.git Add file-parent-directory function * doc/lispref/files.texi: Document the function. * etc/NEWS: Add its entry. * lisp/emacs-lisp/shortdoc.el: Add it to 'file-name' group. * lisp/files.el: implementation (bug#56355). --- diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index ea8683a6d8e..ee4e1ec4d96 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -2445,6 +2445,12 @@ You can use this function for directory names and for file names, because it recognizes abbreviations even as part of the name. @end defun +@defun file-parent-directory filename +This function returns the parent directory of @var{filename}. If +@var{filename} is at the top level, return @code{nil}. @var{filename} +can be relative to @code{default-directory}. +@end defun + @node File Name Expansion @subsection Functions that Expand Filenames @cindex expansion of file names diff --git a/etc/NEWS b/etc/NEWS index 3836efa6927..7967190c6e7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -339,6 +339,10 @@ increase and decrease the font size globally. Additionally, the variable 'global-text-scale-adjust-resizes-frames' controls whether the frames are resized when the font size is changed. ++++ +** New function 'file-parent-directory'. +Get the parent directory of a file. + ** New config variable 'syntax-wholeline-max' to reduce the cost of long lines. This variable is used by some operations (mostly syntax-propertization and font-locking) to treat lines longer than this variable as if they diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index f53e783111c..68293931c3c 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -353,6 +353,13 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'), (abbreviate-file-name :no-eval (abbreviate-file-name "/home/some-user") :eg-result "~some-user") + (file-parent-directory + :eval (file-parent-directory "/foo/bar") + :eval (file-parent-directory "~") + :eval (file-parent-directory "/tmp/") + :eval (file-parent-directory "foo/bar") + :eval (file-parent-directory "foo") + :eval (file-parent-directory "/")) "Quoted File Names" (file-name-quote :args (name) diff --git a/lisp/files.el b/lisp/files.el index 1295c24c933..b952b08ff47 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -5145,6 +5145,23 @@ On most systems, this will be true: (setq filename nil)))) components)) +(defun file-parent-directory (filename) + "Return the parent directory of FILENAME. +If FILENAME is at the top level, return nil. FILENAME can be +relative to `default-directory'." + (let* ((expanded-filename (expand-file-name filename)) + (parent (file-name-directory (directory-file-name expanded-filename)))) + (cond + ;; filename is at top-level, therefore no parent + ((or (null parent) + (file-equal-p parent expanded-filename)) + nil) + ;; filename is relative, return relative parent + ((not (file-name-absolute-p filename)) + (file-relative-name parent)) + (t + parent)))) + (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.