conao3 / leaf.el

Flexible, declarative, and modern init.el package configuration
GNU General Public License v3.0
499 stars 27 forks source link

expressions inside setq #523

Open jgarte opened 2 years ago

jgarte commented 2 years ago

Hi, I get this error when opening emacs:

Error (leaf): Error occurs in leaf block: scheme
Error (leaf): Attempt modify list;  Please check your specification
Error (leaf): Error occurs in leaf block: scheme
Error (leaf): Attempt modify list;  Please check your specification

I'd like to do something like the following:

(leaf scheme
  :doc "the universe is made of atoms and pairs"
    :setq
     ((home-sweet-home . (getenv "HOME")
     (scheme-program-name . (concat home-sweet-home ".guix-profile/bin/guile"))))

This is what macroexpand outputs:

(prog1 'scheme
  (leaf-handler-leaf-path scheme)
  (leaf-handler-leaf-protect scheme
    (setq home-sweet-home nil)
    (setq getenv nil)
    (setq scheme-program-name nil)
    (setq concat nil)
    (setq home-sweet-home nil)))

Or

(prog1 'scheme
  (let
      ((file
        (leaf-this-file)))
    (if
        (boundp 'leaf--paths)
        nil
      (defvar leaf--paths nil))
    (if file
        (progn
          (add-to-list 'leaf--paths
                       (cons 'scheme file)))))
  (condition-case err
      (progn
        (setq home-sweet-home nil)
        (setq getenv nil)
        (setq scheme-program-name nil)
        (setq concat nil)
        (setq home-sweet-home nil))
    (error
     (display-warning 'leaf
                      (format "Error in `scheme' block.  Error msg: %s"
                              (error-message-string err))))))

Do you happen to know what is wrong with my code? Why are the values of setq set to nil...? 🦆

What would be the best way to debug this?

conao3 commented 2 years ago

related: https://github.com/conao3/leaf.el/issues/520 Maybe you want this leaf form

(leaf scheme
  :doc "the universe is made of atoms and pairs"
  :setq
  `((home-sweet-home . ,(getenv "HOME"))
    (scheme-program-name . ,(concat home-sweet-home ".guix-profile/bin/guile"))))

but you will get below error.

;;=> Debugger entered--Lisp error: (void-variable home-sweet-home)
;;     (concat home-sweet-home ".guix-profile/bin/guile")

cus leaf (or Elisp) 'know' valiable value at macro expansion phase.

As long as Emacs know the variables during macro expansion, it can evaluate them while expanding the desired S expression. In other words, you can use setq before it. Note that if you are want to use byte-compile your config, you need to use eval-when-compile to tell the Elisp byte compiler about the variables.

conao3 commented 2 years ago
(setq home-sweet-home (getenv "HOME"))

(leaf scheme
  :doc "the universe is made of atoms and pairs"
  :setq
  `((scheme-program-name . ,(concat home-sweet-home ".guix-profile/bin/guile"))))

or

(leaf scheme
  :doc "the universe is made of atoms and pairs"
  :setq
  `((scheme-program-name . ,(concat (getenv "HOME") ".guix-profile/bin/guile"))))
AkibAzmain commented 2 years ago

@jgarte @conao3 I have observed that Leaf can't handle any list except ones whose car is either "quote" ('()) or "backquote" ("quasiquote" in Scheme). So my hack is to backquote (or quasiquote) followed by unquote (,):

(leaf scheme
  :doc "the universe is made of atoms and pairs"
  :setq
  ((home-sweet-home . `,(getenv "HOME"))
   (scheme-program-name . `,(concat home-sweet-home ".guix-profile/bin/guile"))))
AkibAzmain commented 2 years ago

(concat home-sweet-home ".guix-profile/bin/guile")

Are you sure that $HOME ends with a slash? You ought to use (expand-file-name ".guix-profile/bin/guile" home-sweet-home). It would also make it easy to port your config any non-Unix-like (FreeDOS?) operating system.