0

I'm trying to make a symbolic link to a directory, but the resulting link is always broken. For example,

(make-symbolic-link user-emacs-directory "test" t)

The first argument is TARGET, the second LINKNAME. But how do I specify them? The documentation does not say.

4
  • Check the manual, here: gnu.org/software/emacs/manual/html_node/emacs/…
    – Drew
    Commented Jan 25 at 0:31
  • Something is broken, at least in my version: in (make-symbolic-link target link ok-if-exists), the target is supposed to be expanded and ~ replaced by the user's home directory, but AFAICT it is not: the link is to ~/.config/emacs literally. Mine is a semi-recent upstream version from 2023/12/28. What version are you running?
    – NickD
    Commented Jan 25 at 1:16
  • 1
    NickD: not automatically. Read the docs again.
    – db48x
    Commented Jan 25 at 1:22
  • Ah, right: I missed the integer part - thanks!
    – NickD
    Commented Jan 25 at 2:06

1 Answer 1

2

You should examine the resulting link, and consult the man page for the symlink C library function.

I imagine that your symlink looks similar to this one:

$ ll test
lrwxrwxrwx. 1 db48x db48x 11 Jan 24 16:58 test -> '~/.emacs.d/'

Let’s see what file says about it:

$ file test
test: broken symbolic link to ~/.emacs.d/

There’s a clue for you.

Let's check the manual:

SYNOPSIS
       #include <unistd.h>

       int symlink(const char *target, const char *linkpath);

       […]

DESCRIPTION
       symlink() creates a symbolic link named  linkpath  which  con‐
       tains the string target.

       Symbolic  links are interpreted at run time as if the contents
       of the link had been substituted into the path being  followed
       to find a file or directory.

       Symbolic links may contain ..  path components, which (if used
       at the start of the link) refer to the parent  directories  of
       that in which the link resides.

So it can contain .. path components, but it says nothing about ~. In fact, if you keep reading man pages you won't find any mention of ~ until you read the man page for your shell. ~ is only interpreted as a reference to your home directory when you type a command into your shell, the file picker provided by your desktop environment, and in interactive prompts in specific applications like Emacs. Other than that, it’s not a real thing. You can’t just use it anywhere you want. In particular, it’s not valid in a symlink. Even if it were, to whose files would the link point? Yours? Mine? Bobs? It would be a bad idea. Thus, when you run ln in your shell, you know to expect the ~ to be expanded by your shell before ln is run:

$ ln -s ~/.emacs.d test2
$ ll test2
lrwxrwxrwx. 1 db48x db48x 20 Jan 24 17:04 test2 -> /home/db48x/.emacs.d

You have to do the same thing before calling make-symbolic-link. See the functions expand-file-name and file-relative-name or the details of exactly what values the third argument to make-symbolic-link can have.

1
  • 1
    C-h f file-relative-name may also be useful (depending on the intentions for the symlink).
    – phils
    Commented Jan 25 at 1:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.