0
(eval-after-load "dired" 
  '(progn
     (define-key dired-mode-map "c" 'dired-create-empty-file)
     (define-key dired-mode-map "r" 'dired-do-compress-to)))

Why is the eval-after-load necessary when this is an init file? From my understanding, it makes it only run when dired is loaded, but isn't the init file also loaded once? I was getting "symbol's value as variable is void" warning for dired-mode-map but it was working fine without.

Is this because the warning is emitted before dired is loaded, but the symbol is resolved by the time emacs is started up?

Drew
  • 75,699
  • 9
  • 109
  • 225
  • I believe you may have edited it to be that way, from the history. – user129393192 Jul 08 '23 at 18:33
  • Oh sorry, I copied your code to my Emacs to format it. Perhaps I deleted a word by mistake and rewrote it. Sorry again. – shynur Jul 08 '23 at 18:35
  • Ah. I actually had that formatted from emacs. Strange. I have `indent-tabs-mode` off with the `tab-width 4`. – user129393192 Jul 08 '23 at 18:39
  • Note that you should prefer the macro `with-eval-after-load` over `eval-after-load`. If you look at its code, you'll see that `with-eval-after-load` avoids explicit quoting by using `lambda`. Maybe, that does not play such a great role for the init file which is usually not byte-compiled but for byte-compiled library files, explicitly quoted sexps are not byte-compiled, but lambda-expressions (and sharp-quoted expressions) are. There is more (also about lexical scoping) at https://discourse.doomemacs.org/t/why-are-some-function-symbols-sharp-quoted/125 – Tobias Jul 09 '23 at 01:24

1 Answers1

1

isn't the init file also loaded once?

Yes, it is loaded once. Loaded when you launch Emacs.

See <https://www.gnu.org/software/emacs/manual/html_node/elisp/Startup-Summary.html>.

Why is the eval-after-load necessary when this is an init file?

To make sure that before executing the following code:

(progn
  (define-key dired-mode-map "c" 'dired-create-empty-file)
  (define-key dired-mode-map "r" 'dired-do-compress-to))

variable dired-mode-map has already been defined / set with a value, IOW, to avoid

"symbol's value as variable is void"

After "dired" is loaded, dired-mode-map will get its own value. Since you don't know when dired will be loaded, use eval-after-load is a good choice.

shynur
  • 4,065
  • 1
  • 3
  • 23
  • I see, but since this is in `init` and `dired` will always be loaded by the time I'm typing, it's not incorrect, but it gets a warning since the variable is not defined yet – user129393192 Jul 08 '23 at 19:09
  • 1
    @user129393192: What do you mean by "*`dired` will always be loaded by the time I'm typing*"? – shynur Jul 08 '23 at 19:24
  • I mean that wrapping it like this only avoids the warning, but functionality would not be affected ,since the symbol is resolved, by the time I am typing. – user129393192 Jul 08 '23 at 20:33
  • 1
    @user129393192: What do you mean by "*the symbol is resolved*"? Variable `dired-mode-map` is defined in package `dired` and it is initialized only when Emacs loads that package. – shynur Jul 08 '23 at 20:37
  • Yes exactly. I was just saying that by the time I am typing that that package will be loaded, so that's why there was no issues with me using it without `eval-after-load` in my init.file, except for the warning. – user129393192 Jul 08 '23 at 20:39
  • @user129393192: "*by the time I am typing that that package will be loaded*" -- Why? Is this a behavior defined in documentation? |||| "*except for the warning.*" -- My Emacs just signals an **error** if I don't write `eval-after-load` unless it `require`s `dired` somehow. I think your Emacs `require`s `dired` in *other* way instead of your typing. Anyway, if you know less about ELisp, use `eval-after-load` please. – shynur Jul 08 '23 at 20:50
  • I have, I was just curious how it didn't seem to be required. – user129393192 Jul 08 '23 at 22:05
  • You stated explicitly in your question "I was getting "symbol's value as variable is void" warning for dired-mode-map" which is clear evidence that dired has not yet been loaded at the point in time that this code in your init file is evaluated. Which is normal -- dired is not a standard pre-loaded library. So why are you saying "it didn't seem to be required" when you are getting that error? Clearly it *is* required. The only reason it might not be is if something *earlier* in your init file was already loading dired (but if that was the case, you would not see the error). – phils Jul 09 '23 at 02:37