4

I use the monokai theme by default in my Emacs configurations. But sometimes I use other themes too, particularly light themes like leuven if the light in the room is more suitable for that. But I don't like the face that monokai uses for org-block (the background exactly), thus I want to override it.

My first attempt was this (I use use-package):

(use-package monokai-theme
  :ensure t
  :config
  (custom-theme-set-faces
   'monokai
   '(org-block ((t (:foreground "#F8F8F0" :background "#171717"))))))

And works perfectly fine at the start, but if I switch to another theme and then go back to monokai the org-block face is the default one of the theme again, ignoring my customization. The same happens if I try to wrap that in a (with-eval-after-load "monokai-theme" ... ) function (as in How to change face in particular theme locally?).

So, I tried another approach, using a hook that I use to reset my smart-mode-line theme every time that I change the theme. The entire solution is this:

(use-package monokai-theme
  :ensure t
  :config
  (progn
    (defvar after-load-theme-hook nil
      "Hook run after a color theme is loaded using `load-theme'.")
    (defadvice load-theme (after run-after-load-theme-hook activate)
      "Run `after-load-theme-hook'."
      (run-hooks 'after-load-theme-hook))
    (defun customize-monokai ()
      "customize monokai theme"
      (custom-theme-set-faces
       'monokai
       '(org-block ((t (:foreground "#F8F8F0" :background "#171717"))))))
    (add-hook 'after-load-theme-hook 'customize-monokai)))

And this works, now every time that I change themes and go back to monokai my custom face is applied as expected. But this also is not a perfect solution because it has side effects, like to switch to a light theme like leuven and have the org-block background in a dark grey instead of the theme default. If you reload the leuven theme again, then seems to apply the theme default and ignore my customization. But this is not a desirable solution, and in the other hand, in a light theme like leuven is easy to see that something went wrong, but it could not be that easier in another dark themes.

I have looked for another solutions but either didn't work, or are generic solutions (for all the themes, not a particular one) or seems too cumbersome.

Is there a properly way to persistently overwrite a face only for a particular theme?

2
  • 2
    How about modifying lines 4132 to 4136 instead of trying to get fancy? github.com/oneKelvinSmith/monokai-emacs/blob/master/… If it is byte-complied, then M-x byte-compile-file when you are finished modifying monokai-theme.el.
    – lawlist
    Commented Nov 26, 2016 at 20:48
  • 1
    @lawlist Well, that's a workaround, but I should have to make the same change every time that the theme is updated. And also it would have to make the same in all the machines where I use the same Emacs configuration or do a dirty workaround and load the theme from a specific folder in my dotfiles' Emacs directory (instead of the Elpa one). I try to do it right and avoid that. Anyway, thanks for your suggestion :) Commented Nov 26, 2016 at 20:53

2 Answers 2

5

Well, finally I have a working solution, actually it was so obvious that I don't understand why it took me so long to find out. The answer is to use my previous solution that make use of the custom hook, but only overwrite the face if the monokai theme is loaded. And works perfectly fine.

(use-package monokai-theme
  :ensure t
  :config
  (progn
    (defvar after-load-theme-hook nil
      "Hook run after a color theme is loaded using `load-theme'.")
    (defadvice load-theme (after run-after-load-theme-hook activate)
      "Run `after-load-theme-hook'."
      (run-hooks 'after-load-theme-hook))
    (defun customize-monokai ()
      "Customize monokai theme"
      (if (member 'monokai custom-enabled-themes)
          (custom-theme-set-faces
           'monokai
           '(org-block ((t (:foreground "#F8F8F0" :background "#171717")))))))
    (add-hook 'after-load-theme-hook 'customize-monokai)))

I still don't know if this is the better or proper way to do it, If you have a better one, please don't hesitate to share it. Thanks!

0

I ran into this same problem. Here's how I was able to do it (Emacs 30):

(use-package monokai-theme
  :ensure t
  :config
  (load-theme 'monokai) ;; <----- load the theme before custom-theme-set-faces
  (custom-theme-set-faces
   'monokai
   '(org-block ((t (:foreground "#F8F8F0" :background "#171717")))))
  (enable-theme 'monokai) ;; <---- call enable theme after
)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.