分享一段快速切换主题代码

灵感来源于spacemacs,但是又像我一样不使用spacemacs的emacser

(setq maple-cycle-themes (mapcar 'symbol-name (custom-available-themes)))

(defun maple/cycle-theme (num)
  (interactive)
  (setq maple-current-theme-index
        (+ num
           (cl-position
            (car (mapcar 'symbol-name custom-enabled-themes)) maple-cycle-themes :test 'equal)))
  (when (>= maple-current-theme-index (length maple-cycle-themes))
    (setq maple-current-theme-index 0))
  (setq maple-current-theme (nth maple-current-theme-index maple-cycle-themes))
  (mapc 'disable-theme custom-enabled-themes)
  (let ((progress-reporter
         (make-progress-reporter
          (format "Loading theme %s..." maple-current-theme))))
    (load-theme (intern maple-current-theme) t)
    (progress-reporter-done progress-reporter)))

(defun maple/next-theme()
  (interactive)
  (maple/cycle-theme 1))

(defun maple/previous-theme()
  (interactive)
  (maple/cycle-theme -1))

(defhydra maple/cycle-themes ()
  ("n" maple/next-theme "next theme")
  ("p" maple/previous-theme "prev theme"))

另外,有时会遇到 Unknown theme,不知道这个有什么解决办法?

1 个赞

我也有感于 Spacemacs 的切换主题,配合 stackoverflow 上的答案 (出处不记得了),写了一段小代码

;; Cycle through this set of themes
(defvar samray-theme-list '(zenburn sanityinc-tomorrow-eighties gruvbox molokai))

(defvar samray-current-theme nil)
(defun samray/cycle-theme ()
  "Cycle through a list of themes, samray-theme-list."
  (interactive)
  (when samray-current-theme
    (setq samray-theme-list (append samray-theme-list (list samray-current-theme))))
  (setq samray-current-theme (pop samray-theme-list))
  (load-theme  samray-current-theme t)
  )

还有就是在 load-theme 之前先 disable 现在的主题

;;; Disable theme before load a new theme
(defadvice load-theme
    (before theme-dont-propagate activate)
  "Disable theme before load theme."
  (mapc #'disable-theme custom-enabled-themes))

因为循环切换的是自己喜欢的且已经存在的主题,所以就不会出现 Unknown theme

1 个赞

一直用的是 M-x customize-themes 来设置主题,自己的配置中只要把喜欢的几个主题装上。

固定在两个主题之间切换,所以我这个方法比较简单。(...) 是自定义的部分。

(defvar current-theme-name "gruvbox")
(defun switch-theme ()
  (interactive)
  (if (string-equal current-theme-name "gruvbox")
      (progn
        (disable-theme 'gruvbox)
        (...)
        (setq current-theme-name "default"))
    (progn
      (load-theme 'gruvbox t)
      (...)
      (setq current-theme-name "gruvbox"))))
1 个赞

不过也有人说了

This advice is a bad idea. Themes are supposed to be applicable on top of each other. Packages may rely on that. It’s better to define a new command that does the same thing.

有些包会依赖“主题能相互叠加”的属性,最好单独定义一个命令。

我觉得这个挺方便的啊, 或者 spc T n, 反正自己定义的就那几个。。