0

I am using Chemacs2 and I want to set an environment variable in the .emacs-profiles.el, eg

To clarify the problem .emacs-profiles.el is not executed it is read and I have updated the post with a proper sample, ie a list of lists. It does not provide and is not required

    (
      ("vanilla" .((user-emacs-directory . "~/emacsen/vanilla/.emacs.d")))
      ("doom01" . ((user-emacs-directory . "~/emacsen/doom01/.emacs.d")
                   (env . (("DOOMDIR" . "~/emacsen/doom01/doomdir")
                           ("PATH" . (concat "~/emacsen/doom01/.emacs.d/bin/doom" ":" (getenv "PATH")))
                           ))))
    )

The file that processes it is https://github.com/plexus/chemacs2/blob/master/chemacs.el.

The profile eg vanilla or doom01 is passed on the command line and its values such as user-emacs-directory and env used for that Emacs session.

The function which sets the environment variables is

    (mapcar (lambda (env)
              (setenv (car env) (cdr env)))
            (chemacs-profile-get 'env))

and it fails on the pair ("PATH" . (concat "~/emacsen/doom01/.emacs.d/bin/doom" ":" (getenv "PATH"))) because (cdr env) which is (concat "~/emacsen/doom01/.emacs.d/bin/doom" ":" (getenv "PATH")) gets passed to the setenv call as it is without being evaluated first.

I have tried some of the splicing techniques listed at Backquote to no avail.

If the expression in the .emacs-profiles.el can't be written in a better way then is there a way to rewrite (cdr env) in (setenv (car env) (cdr env)) in such a way that it gets evaluated to a string before setenv tries to apply it?

vfclists
  • 1,347
  • 1
  • 11
  • 28
  • Use `backquote` - see e.g. [this question and answers](https://emacs.stackexchange.com/questions/7481/how-to-evaluate-the-variables-before-adding-them-to-a-list) – NickD Nov 05 '21 at 15:39
  • 1
    Never mind :-) Can you show the context? What is the relation between the code in the first box and the code in the second box? Bear in mind that I know nothing about Chemacs2 or Doom (if that is even relevant). – NickD Nov 05 '21 at 15:42
  • You say you've tried using backquote to no avail. What have you tried? – Drew Nov 05 '21 at 16:21
  • @NickD `env` is a list of environment variables for that Chemacs configuration and the setenv function requires the second parameter ie `(cdr env)` to be a string so `(concat "~/emacsen/doom01/.emacs.d/bin/doom" ":" (getenv "PATH"))` must be evaluated before it gets passed to `setenv`. I think the problem comes from the fact that `.emacs-profile.el` is not executed, it is `read` and that is probably why it is not evaluated. `setenv` probably reads the raw expression then evaluates it. I will update the question. – vfclists Nov 05 '21 at 16:37
  • Please do: this sounds like a typical problem where `backquote` is the solution, so more details will help. – NickD Nov 05 '21 at 17:12
  • 1
    When I start with `--debug-init` the error the debugger displays is `Debugger entered--Lisp error: (wrong-type-argument characterp concat)`. My conclusion is that the Chemacs code `reads` the expression and does not evaluate it, so the `(cdr env)` value passed to `setenv` is the raw symbol from the `read` and thus fails because it is not a string expression. – vfclists Nov 06 '21 at 12:23
  • 1
    That is a correct diagnosis I think. – NickD Nov 06 '21 at 22:05

1 Answers1

1

I suggest that what you need is a generator function that will run your code and generate a file in the proper format. One way to do this is with literate programming in Org mode. A simple org document can run your lisp and produce the proper output, and updating the document for new values can automatically create the new file for you. Essentially, you never touch the .el file itself.

naugiedoggie
  • 334
  • 1
  • 8