Emacs按时间自动加载颜色主题

Emacs按时间自动加载颜色主题,emacs,elisp,Emacs,Elisp,我可以让Emacs自动加载主题吗?或者在自定义时间执行特定命令?我想说的是,当我早上9:00在办公室时,M-x加载主题RET日光浴当我回到家并在晚上8:00在emacs上继续时,M-x laod主题RET日光浴 您可以从运行计时器开始功能: (run-with-timer SECS REPEAT FUNCTION &rest ARGS) Perform an action after a delay of SECS seconds. Repeat the action every RE

我可以让Emacs自动加载主题吗?或者在自定义时间执行特定命令?我想说的是,当我早上9:00在办公室时,
M-x加载主题RET日光浴
当我回到家并在晚上8:00在emacs上继续时,
M-x laod主题RET日光浴

您可以从
运行计时器开始
功能:

(run-with-timer SECS REPEAT FUNCTION &rest ARGS)

Perform an action after a delay of SECS seconds.
Repeat the action every REPEAT seconds, if REPEAT is non-nil.
SECS and REPEAT may be integers or floating point numbers.
The action is to call FUNCTION with arguments ARGS.

This function returns a timer object which you can use in `cancel-timer'.
安排一个函数每分钟左右运行一次,这将检查 当前时间,并在适当时调用
加载主题
(不要切换
每分钟创建一个主题,即使它正在重新加载当前主题)。

要扩展@Anton Kovalenko的答案,您可以使用elisp函数获取当前时间,并以小时为单位提取当前时间

如果要编写完整的实现,可以执行以下操作(警告,未调试):

;;
(setq当前主题(颜色主题日光)
(取消同步主题()
(setq小时)
(字符串到数字)
(子字符串(当前时间字符串)11 13)
(如果(成员小时(编号顺序6 17))
(setq now(颜色主题日光灯))
(setq now'(颜色主题日光浴深色)))
(如果(现在等于当前主题)
无
(setq当前主题现在)
(现在评估);;结束(解除。。。
(使用计时器0 3600同步主题运行)
有关所用功能的更多信息,请参阅emacs手册的以下章节:


您可以使用这段代码来做您想做的事情

(defvar install-theme-loading-times nil
  "An association list of time strings and theme names.
The themes will be loaded at the specified time every day.")
(defvar install-theme-timers nil)
(defun install-theme-loading-at-times ()
  "Set up theme loading according to `install-theme-loading-at-times`"
  (interactive)
  (dolist (timer install-theme-timers)
(cancel-timer timer))
  (setq install-theme-timers nil)
  (dolist (time-theme install-theme-loading-times)
(add-to-list 'install-theme-timers
         (run-at-time (car time-theme) (* 60 60 24) 'load-theme (cdr time-theme)))))
只需根据需要自定义变量
安装主题加载时间

(setq install-theme-loading-times '(("9:00am" . solarized-light)
                ("8:00pm" . solarized-dark)))
另一个(非常优雅的)解决方案是主题变换器

给定位置和日/夜颜色主题,此文件提供更改主题功能,可根据是白天还是夜晚选择适当的主题。它将在日出和日落时继续更改主题。要安装:

设置位置:

(setq calendar-location-name "Dallas, TX") 
(setq calendar-latitude 32.85)
(setq calendar-longitude -96.85)
指定日间和夜间主题:

(require 'theme-changer)
(change-theme 'tango 'tango-dark)

该项目是托管的,可以通过melpa安装。

此实现根据您提供的纬度和经度的日出和日落时间更改主题。唯一的依赖项是随Emacs(IIRC)发布的
solar.el

(我认为这里的代码可能更短。)

;日出日落时根据纬度和经度改变主题
(需要“太阳能”)
(defun今日日期整数(偏移量)
返回整数列表中今天的日期,即系统时间中的月份、日期和年份
日期(mapcar)
(lambda(图案)
(字符串到数字(格式化时间字符串模式)))
(“%m”%d“%Y”))
(赛特卡尔)
(nthcdr)
1.
(日期)
(+偏移量(第n个1日)))
(日期)
(定义当前时间小数点()
(let*((当前最小分数(/(字符串到数字(格式时间字符串“%M”))60.0))
(当前小时(字符串到数字(格式时间字符串“%H”))
(+当前小时当前最小分数)))
(解除下一次报警时间(日出时间日落时间)
(let*((当前时间(当前时间小数)))
(秒(<当前时间日出时间)
(-日出时间当前时间))
((和(>=当前时间日出时间)
(<当前时间日落时间))
(-日落时间当前时间))
((>=当前时间日落时间)
(让((明天日出时间)car
(((+24明日日出时间)当前时间
(减至秒(小时)(*小时60))
(defun变更主题(浅色主题深色主题coor)
(让*(q(setq)日历纬度(car coor)))
(uq(setq历法经度(第n个1坐标)))
(今日日期(今日日期整数0))
(日出日落列表(今天太阳日出日落日期))
(日出时间(汽车(汽车日出日落列表)))
(日落时间(汽车(第n个1日出日落列表)))
(当前时间(当前时间十进制))
(当前主题(如果(或(<当前时间日出时间)(>当前时间日落时间))
黑暗主题
轻主题)
(next-alarm-t(next报警时间日出时间日落时间)))
(取消功能计时器的更改主题)
(加载主题当前主题t)
(按时间运行)
(至秒next-alarm-t)无“更改主题灯光主题黑暗主题coor”))
(更改主题为“日光gruvbox light”和“日光gruvbox dark”(47.6062-122.3321))

谢谢你的指导。遵循@Dan code,我想我已经明白了。谢谢。很好的例子。我每天使用emacs,但从未尝试学习elisp。刚刚开始学习并遵循你的例子。很好。谢谢。小提醒:那应该是
子字符串(当前时间字符串)11 13)
?没有括号?另外,在
运行计时器
中的
同步主题
之前添加
也会起作用。@liuminzhao:你能澄清一下需要修复的内容吗(或者自己直接修复)。在一些错误修复后,它会起作用:(if(eq现在当前主题)到(if(eq现在当前主题)@唐新发:请随意编辑答案来修复这个bug。按照@Dan的代码就可以了。我也会通过你的代码来学习elisp。谢谢。
(require 'theme-changer)
(change-theme 'tango 'tango-dark)
;; theme changing at sunrises and sunsets according to lat and long
(require 'solar)

(defun today-date-integer (offset)
  "Returns today's date in a list of integers, i.e. month, date, and year, in system time."
  (let* ((date (mapcar
   (lambda (pattern)
     (string-to-number (format-time-string pattern)))
   '("%m" "%d" "%Y"))))
    (setcar
   (nthcdr
    1
    date)
   (+ offset (nth 1 date)))
    date))

(defun current-time-decimal ()
  (let* ((current-min-fraction (/ (string-to-number (format-time-string "%M")) 60.0))
    (current-hour (string-to-number (format-time-string "%H"))))
    (+ current-hour current-min-fraction)))

(defun next-alarm-time (sunrise-time sunset-time)
  (let* ((current-time (current-time-decimal)))
   (cond ((< current-time sunrise-time)
       (- sunrise-time current-time))
    ((and (>= current-time sunrise-time)
          (< current-time sunset-time))
      (- sunset-time current-time))
    ((>= current-time sunset-time)
     (let ((tomorrow-sunrise-time (car (car (solar-sunrise-sunset (today-date-integer 1))))))
       (- (+ 24 tomorrow-sunrise-time) current-time))))))

(defun to-seconds (hour) (* hour 60 60))

(defun change-theme (light-theme dark-theme coor)
  (let* ((_ (setq calendar-latitude (car coor)))
    ( _ (setq calendar-longitude (nth 1 coor)))
    (today-date (today-date-integer 0))
    (sunrise-sunset-list (solar-sunrise-sunset today-date))
    (sunrise-time (car (car sunrise-sunset-list)))
    (sunset-time (car (nth 1 sunrise-sunset-list)))
    (current-time (current-time-decimal))
    (current-theme (if (or (< current-time sunrise-time) (> current-time sunset-time))
             dark-theme
             light-theme))
    (next-alarm-t (next-alarm-time sunrise-time sunset-time)))
    (cancel-function-timers 'change-theme)
    (load-theme current-theme t)
    (run-at-time
     (to-seconds next-alarm-t) nil 'change-theme light-theme dark-theme coor)))

(change-theme 'solarized-gruvbox-light 'solarized-gruvbox-dark '(47.6062 -122.3321))