valignatev / heaven-and-hell

Emacs light/dark theme toggler
MIT License
58 stars 2 forks source link

emacs after-init issue, theme only loads with emacs-startup-hook #11

Closed tdd11235813 closed 5 years ago

tdd11235813 commented 5 years ago

(issue is just for documentation)

I have an issue with emacs and after-init hook, so it is not directly related to your package. I just wondered, why the new theme was not loaded after emacs started. Maybe it is just a stupid thing. Question is on emacs.stackexchange.

This is now my config with emacs-startup hook:

(use-package heaven-and-hell
  :ensure t
  :init
  (setq heaven-and-hell-theme-type 'dark) ;; Omit to use light by default
  (setq heaven-and-hell-themes
        '((light . tsdh-light)
          (dark . tsdh-dark))) ;; Themes can be the list: (dark . (tsdh-dark wombat))
;;:hook (after-init . heaven-and-hell-init-hook) ;; does not work
  :hook (emacs-startup . heaven-and-hell-init-hook) ;; this one does
  :bind (("C-c <f6>" . heaven-and-hell-load-default-theme)
         ("<f6>" . heaven-and-hell-toggle-theme)))

Answer: Do not use command-line argument to emacs init files. Do not use things like "-l init.el", it will mess up the init process. See emacs startup and after-init-hook issue here.

valignatev commented 5 years ago

Glad you've sorted that out :) I'm gonna close the issue, thanks for providing an alternative configuration option, it might be helpful for somebody else as well.

tdd11235813 commented 5 years ago

cannot reproduce it anymore, even when I run emacs with -Q (see updated issue). The emacs-startup had other issues like additional syntax highlighting via prog-mode-hook did not work.

tdd11235813 commented 5 years ago

sry for still posting stuff here, but issue probably is also related to custom-file loads.

;; at the end of init.el
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file 'noerror)

The last line overwrites session-temporary saved themes and, e.g., resets to the default, when the loaded custom-file is empty (because safe-theme is not present there yet). Because, when I comment (load custom-file.. then it loads the theme correctly at startup. You circumvent this issue probably because you only load, if custom-file is present, which is not the case in the first loadup. If you load an empty custom file, the first theme loadup will not work, I guess. Edit: nope, I also get that issue when using your code, have to stop digging for now.

tdd11235813 commented 5 years ago

ok, the content of custom-file created the fishy behavior. No matter what, after changing theme with heaven-and-hell, custom.el contains that line:

(custom-set-variables
;; ...
  '(custom-enabled-themes nil) ;; <-- should contain my custom themes

This is wrong, because actually there have been my own themes loaded in the previous emacs instance. So why there is always a nil for custom themes? This loads the unwanted default theme. With system themes it does not happen, maybe because heaven-and-hell only writes custom variables for custom themes, but I do not understand that code completely. (Edit: heaven-and-hell-load-default-theme() should trigger it though)

Edit: ok, then the emacs-startup-hook thing makes sense now. emacs-startup-hook comes after after-init-hook, I think also after custom-file load. The wrong behaviour has been simply overwritten by the heaven-and-hell-init-hook in the emacs-startup-hook run after the custom-file load. What do you think?

Edit-2: just workarounded this issue now for my custom themes scicpp-*:

(use-package heaven-and-hell
;; ...
  :config
  (custom-set-variables `(custom-enabled-themes (quote (scicpp-dark scicpp-light))))
)
valignatev commented 5 years ago

What this code does: it takes a theme (or themes) that you've specified in your heaven-and-hell-themes and sets them as a custom-enabled-themes (if they are not built in themes), overriding everything that was there before.

I don't exactly understand what is the issue now :) heaven-and-hell can't load your custom themes inside heaven-and-hell-init-hook or the hook itself doesn't get triggered?

tdd11235813 commented 5 years ago

hmm but why do I get a nil there in custom.el? The part, where the custom themes are set by heaven-and-hell, is not happening. I will try to get into this tomorrow again.

valignatev commented 5 years ago

Btw you can debug elisp code with breakpoints, like you would do in any other programming language: https://stackoverflow.com/a/3258205/3606603

tdd11235813 commented 5 years ago

yes, I also have checked this site. Since there is no error and the startup needs to debugged I used messages. Also care has to be taken of compiled emacs files.

Finally, this answer gave me the right clue. I used -l command-line option to load my init file (had different ones in the past).

This results in overwriting custom-enabled-themes with nil. Observed behavior at emacs startup with "-l init.el":

...
...
# initial run of init.el by emacs
>>> after (use-package heaven-and-hell... # in init.el
Loading a theme can run Lisp code.  Really load? (y or n) y
Treat this theme as safe in future sessions? (y or n) y
(New file)
Saving file ~/.emacs.d/custom.el... 
Wrote ~/.emacs.d/custom.el [2 times] # writes a nil to custom-enabled-themes, cuz after-init-hook did not run yet
> scicpp-dark # run in after-init-hook by heaven-and-hell-clean-load-themes
>> (scicpp-dark) # run in after-init-hook by heaven-and-hell-clean-load-themes
For information about GNU Emacs and the GNU system, type C-h C-a.
# init routine completed, no processing command-lines like "-l init.el"
>>> after (use-package heaven-and-hell...
>>>> loading custom file. # now the `nil` replaces the custom-enabled-themes :sigh:

Since there is only one after-init-hook (emacs startup), nil replaced the custom-enabled-themes. So I finally found the error. Thanks a lot for helping me to find this. I'll close this issue now and update the first post.

valignatev commented 5 years ago

Whoa, this was intense :popcorn: I never really liked the custom file mechanism because I don't fully understand how it works. Today I definitely learned something new.

tdd11235813 commented 5 years ago

yeah, and the week is quite over now :) A documentation at the -l argument like "Do not use for init files" or "There are no CLI options intended for loading init files" would have helped to avoid this issue. Now I also have to check the other ones as well.