1

I have the following command in my .emacs

(setq org-roam-directory
      (concat (getenv "BASEDIR") "/data/org-roam/"))

The purpose is to the set the directory for org-roam (but really it could be any other package) on different systems where the variable $BASEDIR has different paths. $BASEDIR is defined in .bashrc. This works well if I start emacs from the command line, but fails if emacs is started from, e.g., the file manager. Is there a way to have emacs read the shell environment variables at startup, regardless on how it is launched?

EDIT: I am running Ubuntu and Arch with GNOME. The file manager is graphical (nautilus or double commander) but of course this also happens if emacs is launched from the apps menu.

point618
  • 233
  • 1
  • 8
  • Although I understand the temptation to have *Emacs* read the variables from the file, I think that's the wrong question. The real question is how to arrange it so that *every* program has access to these variables: that however depends on what OS you are running (in particular is it systemd-based?) and what window system/graphical environment you are running. Can you edit your question and add this information? – NickD Oct 09 '21 at 14:10
  • 1
    Your issue isn't reading environment variables (you're doing that correctly), but _setting_ them. You need to understand your shell's initialization order, and how your file manager is invoking Emacs. – nega Oct 09 '21 at 16:13
  • More to the point: variables from `.bashrc` are inherited only by programs started from Bash. If by ‘file manager’ you mean a graphical file manager, then you need to look at how env vars are defined in your graphical environment (Gnome/KDE/whatever). If it's a terminal manager like Midnight Commander, launched from Bash, then the question is why it removes vars from the environment instead of passing them to the editor—you'll need to consult the manager's docs, or set its options. If everything else fails, perhaps the option is indeed to have a specific config file to be read by Emacs. – aaa Oct 10 '21 at 09:33
  • And, perhaps the simplest option is—instead of the config variable or file, just have a symlink point at the target directory. This way you actually can use the same path on all the systems and have the symlink resolve it to the actual location. – aaa Oct 10 '21 at 09:35

1 Answers1

2

aaa is right. You might try setting $BASEDIR in ~/.profile. That file is read when you log in to Gnome, while ~/.bashrc is read when you open up a terminal, basically. (Note that Bash as a login shell doesn't parse ~/.profile if either ~/.bash_profile or ~/.bash_login exists.)

Alternatively you could try is using (shell-command-to-string "$SHELL --login -c 'echo $BASEDIR'") instead of (getenv "BASEDIR"). See How to get the PATH from the SHELL

Arch Stanton
  • 1,525
  • 9
  • 22
  • It really depends: e.g. this (the `.profile` solution) does not work with Wayland. It only works on X11 through an xsession init file which sources `.profile. And the second suffers from the malady that it only potentially fixes Emacs. Neither is a comprehensive solution IMO. – NickD Oct 10 '21 at 15:11
  • 1
    @NickD My `~/.profile` works in Wayland because I `source` it in `~/.bash_profile`, I had forgot about that. (Might work for the OP too?) Thanks for the heads up. – Arch Stanton Oct 11 '21 at 07:06
  • @ArchStanton I am trying the second solution and it almost works. It seems to fail when concat joins the two strings. – point618 Oct 11 '21 at 10:11
  • This works: `(concat (string-trim (shell-command-to-string "$SHELL --login -c 'echo $BASEDIR'")) "/data/org-roam/"))` provided that `$BASEDIR` is in `.profile` as per comment above. – point618 Oct 11 '21 at 10:28