I am manually constructing path strings in Elisp by concatenating partial paths and directory names. Unfortunately sometimes the paths end with slash, sometimes not. Therefore, I need to insert slash before concatenating a directory name when necessary but not otherwise. What's a good way to do this?
(file-name-as-directory dir)
will return directory path dir
with a trailing slash, adding one if necessary, and not otherwise.
If you had your sequence of partial paths in a list, you could do something like:
(let ((directory-list '("/foo" "bar/" "p/q/" "x/y"))
(file-name "some_file.el"))
(concat
(mapconcat 'file-name-as-directory directory-list "")
file-name))
"/foo/bar/p/q/x/y/some_file.el"
or as an alternative, if you wanted to include the file name in the list, you could utilise directory-file-name
which does the opposite of file-name-as-directory
:
(let ((path-list '("/foo" "bar/" "p/q/" "x/y/some_file.el")))
(mapconcat 'directory-file-name path-list "/"))
"/foo/bar/p/q/x/y/some_file.el"
(Someone please correct me if using directory-file-name
on a non-directory is not portable?)
The easiest way to assemble file names from parts of questionable content is with expand-file-name. For example:
(expand-file-name "foo.txt")
this common form will give you a full file name based on default-directory:
/home/me/foo.txt
but if you have a variable 'dir' whose content is "/home/them/subdir" and want to use that, do this:
(expand-file-name "foo.txt" dir)
it doesn't matter if dir ends in / or not. If you are on some other platform, and contains the other slash, it will do the right thing then too. Do you have a mix? Just stack them:
(expand-file-name "foo.txt" (expand-file-name "somesubdir" dir))
Something like this should work as a starting point, although you'd want to flesh it out a bit to make it platform independent, etc.
(defun append-path-component (path new-part)
(if (string-match ".*/$" path)
(concat path new-part)
(concat path "/" new-part)))
As per usual, there's probably some bit of elisp that already does this that I'm just not aware of.
Unless you really care about keeping relative file names as relative, then it's always much better to avoid concat
and use expand-file-name
instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With