根据时间切换 emacs theme

赞!多谢,我再学习一下手册。

整理了一下,加上了随机选择主题

;; 亮色主题和暗色主题
(setq day-theme-list '( modus-operandi ef-day ef-spring ef-summer))
(setq dark-theme-list '( modus-vivendi ef-night ef-autumn ef-winter))

;; 随机选取主题
(defun my-random-element (my-list)
  "Return a random element from MY-LIST."
  (let ((my-length (length my-list))
        (my-random-index (random (length my-list))))
    (nth my-random-index my-list)))

;; 根据时间选择亮/暗主题
(defun synchronize-theme ()
  (setq hour
	(string-to-number
	 (substring (current-time-string) 11 13)))
  (if (member hour (number-sequence 6 18))
      (progn
	(setq now (my-random-element day-theme-list))
	(setq lst (my-random-element dark-theme-list))
	)
    (setq now (my-random-element dark-theme-list))
    (setq lst (my-random-element day-theme-list))
    )
  (mapc 'disable-theme custom-enabled-themes)
  (load-theme now t))
(synchronize-theme) ;; 启动时立即执行一次
;; 每小时执行一次
(let* ((current-minutes
	(string-to-number (substring (current-time-string) 14 16)))
       (current-seconds
	(string-to-number (substring (current-time-string) 17 20)))
       (remain-seconds
	;; remaining seconds = 3600 - 60 * min - sec
	(- 3600 (* 60 current-minutes) current-seconds))
       )
  (run-with-timer remain-seconds 3600 'synchronize-theme))

2 个赞

这相当于用手电筒可以控制emacs的颜色主题。

我是想在白天启用浅色主题,晚上启用深色主题。在网上看到有简单的设置方法,与君共享。

按照上述链接,我的代码如下:

(load-theme 'tango t t)     ;;加载浅色主题,但不启用。
(load-theme 'zerodark t t)	;;加载深色主题,但不启用。
;;早上5点启用浅色主题, 每24小时重复一次。
(run-at-time "05:00" (* 60 60 24) (lambda () (enable-theme 'tango)))
;;晚上7点启用深色主题, 每24小时重复一次。
(run-at-time "19:00" (* 60 60 24) (lambda () (enable-theme 'zerodark)))

若需进一步了解函数参数含义,可以使用C-h f查看。

2 个赞

为了避免 enable-theme 出现混乱,考虑在enable-theme之前,先做一下disable-theme为好。

;;; Theme
(use-package modus-themes)
(use-package standard-themes)
(use-package ef-themes)

;; Switch Themes automatically according to sunrise
(use-package circadian
  :ensure nil
  :demand t
  :load-path "~/.emacs.d/site-lisp/circadian"
  :config
  (setq calendar-latitude 40.0)
  (setq calendar-longitude 116.4)
  (setq circadian-themes `((:sunrise . ,(nth (random 7) '(modus-operandi
                                                          modus-operandi-tinted
                                                          standard-light
                                                          ef-elea-light
                                                          ef-maris-light
                                                          ef-deuteranopia-light
                                                          ef-cyprus)))
                           (:sunset  . ,(nth (random 7) '(modus-vivendi
                                                          modus-vivendi-tinted
                                                          standard-dark
                                                          ef-elea-dark
                                                          ef-maris-dark
                                                          ef-deuteranopia-dark
                                                          ef-bio)))))
  (circadian-setup))

也可以用 darkman

最近又折腾了一下,都是用 Prot 的主题:ef-themes,modus-themes,doric-themes,它们都提供了随机加载亮色/暗色主题的函数,可以自己定义随机条件调用。

我目前的随机逻辑是:

ef-themes 颜色最鲜艳, modus-themes 次之, doric-themes 最单调,周三前觉得周末很远,比较煎熬,所以周一到周三使用 ef-themes ,让色彩丰富明亮一些;周四周五快到周末了,心情渐佳,改用 modus-themes ;周末应该好好休息,就用单调一些的 doric-themes ,避免过分沉浸在 Emacs 中。

白天(8:00 - 18:00)用亮色主题,晚上用暗色主题。

当第一次启动 Emacs 的时候,会基于设定的白天黑夜时间,随机加载一个主题。 之后切换明暗主题,就通过调用 light/dark 两个函数随机加载,不会自动变化。

提供 light/dark 两个方法也方便在看腻了或者不喜欢的时候随机一下。

相关代码
;; theme
(use-package modus-themes
  :config
  (setq modus-themes-italic-constructs t
        modus-themes-bold-constructs t
        modus-themes-disable-other-themes t)
  ;; remove fill-column-indicator background
  (modus-themes-with-colors
    (custom-set-faces
     `(fill-column-indicator ((,c :background unspecified :foreground ,bg-dim :height 1.0))))))

(use-package ef-themes)
(use-package doric-themes)

(defun spike-leung/load-theme-by-time (light-fn dark-fn)
  "Call LIGHT-FN  to load light themes from 8:00a.m to 6:00p.m.
otherwise, call DARK-FN to load dark themes."
  (let ((hour (string-to-number (format-time-string "%H"))))
    (funcall (if (and (>= hour 8) (< hour 18)) light-fn dark-fn))))

(defun spike-leung/themes-load-random (&optional background-mode)
  "Random load themes.

Use `ef-themes' for Monday,Tuesday,Wednesday.
Use `modus-themes' on Thursday, Friday.
Use `doric-themes' on Saturday, Sunday.
Use light themes at day, use dark themes at night.

With optional BACKGROUND-MODE as a prefix argument, prompt to limit the
set of themes to either dark or light variants."
  (require 'modus-themes)
  (require 'ef-themes)
  (require 'doric-themes)
  (let ((week (string-to-number (format-time-string "%u"))))
    (cond
     ((<= week 3)
      (cond
       ((eq background-mode 'light) (ef-themes-load-random-light))
       ((eq background-mode 'dark) (ef-themes-load-random-dark))
       (t (spike-leung/load-theme-by-time #'ef-themes-load-random-light #'ef-themes-load-random-dark))))
     ((<= week 5)
      (if background-mode
          (modus-themes-load-random background-mode)
        (spike-leung/load-theme-by-time
         (lambda () (modus-themes-load-random 'light))
         (lambda () (modus-themes-load-random 'dark)))))
     (t
      (if background-mode
          (doric-themes-load-random background-mode)
        (spike-leung/load-theme-by-time
         (lambda () (doric-themes-load-random 'light))
         (lambda () (doric-themes-load-random 'dark))))))))

(defun light()
  "Load random light themes."
  (interactive)
  (spike-leung/themes-load-random 'light))

(defun dark()
  "Load random dark themes."
  (interactive)
  (spike-leung/themes-load-random 'dark))

;; 要在 desktop 加载后再执行,避免被 desktop 记录的主题覆盖,导致混乱
(add-hook 'desktop-after-read-hook #'spike-leung/themes-load-random)

相关的折腾记录博客文章里:https://taxodium.ink/emacs-random-theme.html

2 个赞