From: "Colin Woodbury" <colin@fosskers.ca>
To: "Mattias Engdegård" <mattiase@acm.org>, Philipp <p.stephani2@gmail.com>
Cc: emacs-devel@gnu.org
Subject: Re: [PATCH] lisp/files.el: Add `file-name-set-extension`
Date: Wed, 09 Jun 2021 13:54:23 -0700 [thread overview]
Message-ID: <ca1ec698-b1cd-4406-9cf6-7d35b89b61d9@www.fastmail.com> (raw)
In-Reply-To: <26B660D9-AC76-4AFC-9FFD-2F5D4DCA16C1@acm.org>
[-- Attachment #1.1: Type: text/plain, Size: 1301 bytes --]
Hi all, thanks for the input. I've revised the patch to account for empty strings and for filenames that look like directories (i.e. that end in a slash).
I've also begun the copyright assignment process, since adding the unit tests lengthened the patch past the critical line count.
As for the naming of `set-extension`, the best I can think of as an alternative would be `with-extension` as a dual to `sans-extension`, although I think `set` still signals the intent well enough. I'll defer to others here.
Cheers,
Colin
On Fri, 4 Jun 2021, at 06:23, Mattias Engdegård wrote:
> 4 juni 2021 kl. 15.08 skrev Philipp <p.stephani2@gmail.com <mailto:p.stephani2%40gmail.com>>:
>
> > Likewise, change the docstring to clarify that a new string is returned.
>
> Actually we usually don't bother saying that a function creates a new string unless this is guaranteed and somehow important, since we don't encourage string mutation anyway. For example, functions are usually allowed to return an unchanged argument string if that would make sense.
>
> Conversely, only functions that do mutate strings need to mention that fact. By default, a user should be able to assume that no string mutation takes place.
>
> I fully agree with the rest of Philipp's excellent points.
>
>
[-- Attachment #1.2: Type: text/html, Size: 1778 bytes --]
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: file-name-set-extension.patch --]
[-- Type: text/x-patch; name="file-name-set-extension.patch", Size: 2590 bytes --]
diff --git a/lisp/files.el b/lisp/files.el
index 2450daf5bf..f37264d7d5 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -4892,6 +4892,18 @@ extension, the value is \"\"."
(if period
"")))))
+(defun file-name-set-extension (filename extension)
+ "Set the EXTENSION of a FILENAME.
+Consolidates leading/trailing dots so that either `foo' or `.foo'
+can be passed as an EXTENSION."
+ (let* ((patt "[ .]+")
+ (file (string-trim-right filename patt))
+ (extn (string-trim-left extension patt)))
+ (cond ((string-empty-p file) (error "Malformed filename: %s" filename))
+ ((string-empty-p extn) (error "Malformed extension: %s" extension))
+ ((equal ?/ (string-to-char (substring file -1))) (error "Filename is a directory: %s" filename))
+ (t (concat (file-name-sans-extension file) "." extn)))))
+
(defun file-name-base (&optional filename)
"Return the base name of the FILENAME: no directory, no extension."
(declare (advertised-calling-convention (filename) "27.1"))
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index dc96dff639..92bbd95eaf 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -1478,5 +1478,25 @@ The door of all subtleties!
(buffer-substring (point-min) (point-max))
nil nil)))))
+(ert-deftest files-tests-file-name-set-extension-good ()
+ "Test that `file-name-set-extension' succeeds with reasonable input."
+ (should (string= (file-name-set-extension "Jack" "css") "Jack.css"))
+ (should (string= (file-name-set-extension "Jack" ".css") "Jack.css"))
+ (should (string= (file-name-set-extension "Jack.scss" "css") "Jack.css"))
+ (should (string= (file-name-set-extension "Jack..." "...css") "Jack.css"))
+ (should (string= (file-name-set-extension "/path/to/Jack.md" "org") "/path/to/Jack.org")))
+
+(ert-deftest files-tests-file-name-set-extension-bad ()
+ "Test that `file-name-set-extension' fails on malformed input."
+ (should-error (file-name-set-extension nil nil))
+ (should-error (file-name-set-extension "Jack" nil))
+ (should-error (file-name-set-extension nil "css"))
+ (should-error (file-name-set-extension "" ""))
+ (should-error (file-name-set-extension "" "css"))
+ (should-error (file-name-set-extension "Jack" ""))
+ (should-error (file-name-set-extension "Jack" "..."))
+ (should-error (file-name-set-extension "..." "css"))
+ (should-error (file-name-set-extension "/is/a/directory/" "css")))
+
(provide 'files-tests)
;;; files-tests.el ends here
next prev parent reply other threads:[~2021-06-09 20:54 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-25 15:50 [PATCH] lisp/files.el: Add `file-name-set-extension` Colin Woodbury
2021-05-25 17:48 ` Andreas Schwab
2021-05-25 19:42 ` Colin Woodbury
2021-05-25 18:00 ` Basil L. Contovounesios
2021-05-25 19:45 ` Colin Woodbury
2021-05-25 20:25 ` Stefan Monnier
2021-05-25 21:21 ` Colin Woodbury
2021-05-25 21:29 ` Stefan Monnier
2021-05-25 21:44 ` Colin Woodbury
2021-05-26 7:34 ` Andreas Schwab
2021-05-26 16:31 ` Colin Woodbury
2021-05-26 17:39 ` Andreas Schwab
2021-05-31 1:16 ` Colin Woodbury
2021-06-04 13:08 ` Philipp
[not found] ` <26B660D9-AC76-4AFC-9FFD-2F5D4DCA16C1@acm.org>
2021-06-09 20:54 ` Colin Woodbury [this message]
2021-06-09 23:05 ` Stefan Monnier
2021-06-10 0:42 ` Colin Woodbury
2021-06-10 2:45 ` Colin Woodbury
2021-06-10 7:46 ` Michael Albinus
2021-06-10 14:40 ` Colin Woodbury
2021-06-16 1:15 ` Colin Woodbury
2021-06-19 9:16 ` Michael Albinus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ca1ec698-b1cd-4406-9cf6-7d35b89b61d9@www.fastmail.com \
--to=colin@fosskers.ca \
--cc=emacs-devel@gnu.org \
--cc=mattiase@acm.org \
--cc=p.stephani2@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).