reddit / emacs
When I execute eval-defun on a (defun...) within my init.el, it doesn't execute it as expected. It outputs "Input Serif".
Status-Detective-783 · 2022-02-22 23:29
I am trying to get this to work to immediately activate a defun that I just added to my init.el (instead of closing and reopening emacs). I thought eval-defun should work. Alternatively, C-x C-e worked fine. So first question is why doesn't this work, and a second question, I guess, is when should I use each version?
I don't know if it matters, but my init.el indicates it's an "(Emacs-Lisp Eldoc)". Here's the function:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; help with parens
(show-paren-mode t)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; emacs needs an unfill
;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun unfill-paragraph (&optional region)
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive (progn (barf-if-buffer-read-only) '(t)))
(let ((fill-column (point-max))
;; This would override `fill-column' if it's an integer.
(emacs-lisp-docstring-fill-column t))
(fill-paragraph nil region)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Some font choices
(setq myfont "InputSerif")
With the point in or immediately after the defun, executing `C-M-x` aka `M-x eval-defun` prints `"InputSerif"` in the minibuffer.
EDIT: Added extra context to my snippet, command above and below.
ieure · 2022-02-22 23:59
`eval-defun` evaluates the form point is inside, which is the `defun`. Evaluating the `defun` macro *defines the function*, it doesn't evaluate the function *being defined*.
Define the function, then use `M-x unfill-paragraph` to evaluate it.
Status-Detective-783 · 2022-02-23 00:24
Thanks! I'm sorry but I didn't explain myself well enough. I've added the following clarification to my question:
> I am trying to get this to work to immediately activate a defun that I just added to my init.el (instead of closing and reopening emacs).
That is, `C-M-x` eval-defun did not define the new defun into my current session, but `C-x C-e` eval-last-sexp worked. Thanks for helping me to clarify!
ieure · 2022-02-23 00:55
I see, thanks for clarifying.
Either `eval-defun` or `eval-last-sexp` should do what you want. Maybe `unfill-paragraph` is wrapped in another form? Or a form earlier in your init file is missing a closing paren?
Status-Detective-783 · 2022-02-23 01:50
I don't think so. I'm a beginner with a fairly small and simple init.el file. I checked all parens.
Link to my init.el file: https://0bin.net/paste/R-e9X-ZH#6y2ab2a8czGiOYzK0g02HfBAYeKloHt7MUzIA4jjIDu
Or if you prefer, pastebin: https://pastebin.com/Sf1eD0Ce.
(The problem with pastebin is I had to make it "private" because pastebin thinks my simple little init.el is "offensive" for some reason, but I can assure you that it's not!)
ieure · 2022-02-23 03:19
Okay, I understand now.
`eval-defun` is bound to `C-M-x` by default, and is there so you can eval the function definition *while you're editing it* -- while point is somewhere inside the body of the definition. `eval-last-sexp` evaluates the sexp *preceding* point, so for it to eval the defun, you have to put point on its closing paren, or in between the closing paren and the next sexp.
Another way of thinking of it is that `eval-defun` moves point to the end of the current function definition, runs `eval-last-sexp`, and moves point back.
The only way I can reproduce your issue is by putting point on the blank line after the function definition. That causes `eval-defun` to look *forward* for the next sexp. In your init.el, that's this:
(setq myfont "InputSerif")
And because `setq` evaluates to the new value of the variable being set, that's why you see "InputSerif" in the echo area.
Status-Detective-783 · 2022-02-23 03:47
Ahh well that's where the InputSerif is coming from! And thanks for looking at my file, I've updated the main post with that extra context.
But yes, I can put the point anywhere immediately before or inside the `(defun unfill-paragraph...)` statement and `M-x eval-defun` reports `"InputSerif"`.
My `M-x eval-defun` seems to work fine on the other statements, such as the one immediately preceding, and others. I guess I'll need to divide and conquer if I want to debug this more.
ieure · 2022-02-23 04:44
> But yes, I can put the point anywhere immediately before or inside the (defun unfill-paragraph...) statement and M-x eval-defun reports "InputSerif".
That's very weird. I can't reproduce it.
andreyorst · 2022-02-23 07:28
I believe `eval-defun` only treats expressions as "defuns" if the opening parenhesis is at the very start of the line:
(progn
(defun f ()
<I>
42)
27)
Calling `eval-defun` at cursor position marked as `<I>` will evaluate the `progn` form.
But if we change indentation of defun like this:
(progn
(defun f ()
<I>
42)
27)
Calling `eval-defun` will only evaluate the function definition.
In the example you've included in the post the definition of `unfill-paragraph` is indented. Not sure if it is just incorrect formatting from reddit, or actual indentation in your file
Status-Detective-783 · 2022-02-23 07:53
That worked, thanks!
Status-Detective-783 · 2022-02-23 07:56
Thanks again for helping. /u/andreyorst figured it out, for eval_defun, the line
>(defun unfill-paragraph...
must not have any spaces before the left paren.