Emacs: How to Set a Theme Depending on Mode?

By Xah Lee. Date: . Last updated: .

there's no way to do this properly, because background color is associated with window (what emacs calls “frame”), not mode.

Here's how you can set background color depending on the file name extension.

;; sample code for setting a background color depending on file name extension

(defun my-set-theme-on-mode ()
  "set background color or theme depending on file suffix"
  (interactive)
  (let* (($bfn (buffer-file-name))
         ($fileNameExt (if $bfn
                           (file-name-extension $bfn)
                         nil
                         )))
    (cond
     ((not $fileNameExt)
      nil)
     ((string-equal $fileNameExt "el")
      (progn
        (set-background-color "honeydew")))
     ((string-equal $fileNameExt "txt")
      (progn
        (set-background-color "cornsilk")))
     ((string-equal $fileNameExt "js")
      (progn
        (load-theme 'tango t)))
     ((string-equal $fileNameExt "ts")
      (progn
        (load-theme 'tango t)))
     ((string-equal $fileNameExt "html")
      (progn
        (load-theme 'light-blue t)))
     ((string-equal $fileNameExt "css")
      (progn
        (load-theme 'tango-dark t)))
     (t nil))))

(add-hook 'find-file-hook 'my-set-theme-on-mode)
(add-hook 'kill-buffer-hook 'my-set-theme-on-mode)

;; need to add hook to
;; switch buffer
;; switch frame
;; switch window

You can modify the code to set themes instead of just background. See: Emacs Init: Set Color Theme.

In the same way, hook is used to customize keys for major mode. [see Emacs Keys: Change Major Mode Keys]

If you want change based on major mode instead of file name extension, you'll need to find the major mode's name.