【问题标题】:Emacs Auto Load Color Theme by TimeEmacs 按时间自动加载颜色主题
【发布时间】:2013-02-07 20:40:11
【问题描述】:

我可以让 Emacs 自动加载主题吗?还是在自定义时间执行某些命令?说我想要的是M-x load-theme RET solarized-light,当我早上 9:00 在办公室时,M-x laod-theme RET solarized-dark,当我回到家并在晚上 8:00 继续使用 emacs 时。

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:

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

    如果你想编写一个完整的实现,你可以这样做(Warning, not debugged):

    ;; <Color theme initialization code>
    (setq current-theme '(color-theme-solarized-light))
    
    (defun synchronize-theme ()
        (setq hour 
            (string-to-number 
                (substring (current-time-string) 11 13)))
        (if (member hour (number-sequence 6 17))
            (setq now '(color-theme-solarized-light))
            (setq now '(color-theme-solarized-dark))) 
        (if (equal now current-theme)
            nil
            (setq current-theme now)
            (eval now) ) ) ;; end of (defun ...
    
    (run-with-timer 0 3600 synchronize-theme)
    

    有关使用的函数的更多信息,请参阅 emacs 手册的以下部分:

    【讨论】:

    • 很好的例子。我每天都使用 emacs,但从未尝试学习 elisp。刚刚开始学习并遵循您的示例。有用。谢谢。小提醒:应该是substring (current-time-string) 11 13) 吗?没有括号?事实证明,在run-with-timer 中的synchronize-theme 之前添加' 有效。
    • @liuminzhao:你能澄清什么需要修复(或直接自己修复)。
    • 它在一些错误修复后工作:(if (eq now current-theme) to (if (equal now current-theme)
    • @tangxinfa:随时编辑答案以修复错误。
    【解决方案2】:

    另一个(非常优雅的)解决方案是theme-changer

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

    设置位置:

    (setq calendar-location-name "Dallas, TX") 
    (setq calendar-latitude 32.85)
    (setq calendar-longitude -96.85)
    

    指定昼夜主题:

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

    项目托管on Github,可以通过melpa安装。

    【讨论】:

      【解决方案3】:

      你可以使用这个sn-p代码来做你想做的事。

      (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)))))
      

      只需根据需要自定义变量install-theme-loading-times

      (setq install-theme-loading-times '(("9:00am" . solarized-light)
                      ("8:00pm" . solarized-dark)))
      

      【讨论】:

      • 遵循@Dan 的代码,它可以工作。我也会通过你的代码学习 elisp。谢谢。
      【解决方案4】:

      你可以从run-with-timer函数开始:

      (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'.
      

      安排一个函数每分钟左右运行一次,这将检查 当前时间并在适当的时候拨打load-theme(不要切换 每分钟的主题,即使它正在重新加载当前主题)。

      【讨论】:

      • 感谢您的指导。遵循@Dan 代码,我想我明白了。谢谢。
      【解决方案5】:

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

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

      ;; 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))
      

      【讨论】:

        猜你喜欢
        • 2013-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多