启动时根据日出日落时间切换主题

一直想要一个这样的功能:白天用light主题,晚上用dark的,同时还能根据看文档看网页等场景不同,手动一键切换。

今天终于能自己实现了,头一回用Elisp实现比较完整的功能 :smiley:

代码附后,只要设置好两种候选主题和经纬度的数值,启动Emacs时就可以根据自己所在位置的日出、日落时间切换主题了。

当然后续要自己加上一个判断当前主题是深是浅并进行切换的函数。

日出前和日落后光照可能仍然很足,可能需要前后延长一点时间,另外跟天气、地形等也有一定的关系。有待继续hack……

主要思路是用自带的sunrise-sunset功能,取得当前位置的日出日落时间,并与当前时刻比大小。但没查到这个函数怎么用24h表示,所以多加了一层判断。

现在我还不知道当时间从白天跨到日落,或从黎明跨到日出,能不能实时切换。知道如何实现的道友请告知。代码有可改进之处,也请留言,谢谢!

(defvar dark-theme "Hesperus")
(defvar light-theme "Phosphorus")

(defun get-time-of-solar ()
  "Switch themes based on the local times of sunrise and sunset."
  (let* ((sslist (split-string (sunrise-sunset) "[:apm\s]")))
    (setq sunrise-time (string-to-number
			(concat (nth 1 sslist) (nth 2 sslist))))
    (setq sunset-time (string-to-number
		       (concat (nth 7 sslist) (nth 8 sslist))))))

(if (> (string-to-number (format-time-string "%H")) 12)
    (if (> (string-to-number (format-time-string "%I%M"))
	   sunset-time)
	(setq my-current-theme light-theme)
      (setq my-current-theme dark-theme))
  (if (> (string-to-number (format-time-string "%H%M"))
	 sunrise-time)
      (setq my-current-theme dark-theme)
    (setq my-current-theme light-theme)))
6 个赞

后续判断并切换的函数,我是这样实现的:

(cond
   ((string-equal my-current-theme "Hesperus")
    (progn
      (disable-theme 'Hesperus)
      (load-theme 'Phosphorus t)
      (setq my-current-theme "Phosphorus")))
   ((string-equal my-current-theme "Phosphorus")
    (progn
      (disable-theme 'Phosphorus)
      (load-theme 'Hesperus t)
      (setq my-current-theme "Hesperus"))))

即,如果当前为白天,则先将my-current-theme设置为dark-theme,随后disable之、并启用light-theme,且重新设置my-current-theme,这样的话,需要根据场景进一步手动切换主题,也能用同一个函数了。

有更好的改进思路,也请回复!

有现成的轮子

1 个赞

这个轮子好像不能手动切换……

手动切换直接用load-theme不可以么

可以,但还要自己写一堆东西,还要照顾现有的轮子……

(setq calendar-latitude lat)
(setq calendar-longitude long)
(solar-sunrise-sunset (calendar-current-date))

使用24h 表示日出和日落时间,

1 个赞

这个轮子更好

2 个赞

好东西,已用! :grinning: