[Mac] 根据环境光自动调整主题

环境变暗时用暗色主题,变亮时用亮色主题:

(除了关灯,用手挡住 Macbook 上的摄像头的位置也行。)

2018-04-11 21_46_11

文中用的是 run-with-timer 定期监测,感觉会拖慢 Emacs,我没试过。我自己写了个用 Emacs Subprocess + Filter 的方法,应该会好些。下面的代码仅供参考,如果你打算运行,得先把

  • sanityinc-tomorrow-eighties
  • sanityinc-tomorrow-day

改成你想要的暗色和亮色主题。

(defun auto-theme-mode-filter (_proc output)
  (let ((current-light-sensor-reading (string-to-number output))
        (current-theme (car custom-enabled-themes))
        (dark-theme 'sanityinc-tomorrow-eighties)
        (light-theme 'sanityinc-tomorrow-day))
    (cond ((/= (length output) 8))      ; printf("%8lld", values[0]);
          ((and (< current-light-sensor-reading 100000)
                (not (eq current-theme dark-theme)))
           (disable-theme current-theme)
           (enable-theme dark-theme))
          ((and (>= current-light-sensor-reading 100000)
                (not (eq current-theme light-theme)))
           (disable-theme current-theme)
           (enable-theme light-theme)))))

(define-minor-mode auto-theme-mode
  "Automatically set Emacs theme based on ambient light."
  :global t
  (let* ((buf " *auto-theme-mode*")
         (proc (get-buffer-process buf)))
    (if auto-theme-mode
        (or (and proc (eq 'run (process-status proc)))
            (let ((process-connection-type nil))
              (set-process-filter
               (start-process
                "lmutracker"
                buf
                "/bin/sh"
                "-c"
                "while true; do lmutracker && sleep 1; done")
               #'auto-theme-mode-filter)))
      (and proc (kill-process proc)))))
5 个赞

棒极了,比我那个预习设置时间段切换主题的强多了

坐火车的时候会怎样,光线不停变化,屏幕闪烁?

把手放到摄像头位置晃一晃,就会不停地来回换主题

如果只换 Emacs 的 theme,不换终端的 theme,会很难看。

请问这个需要打开摄像头吗

找到动态切换 iTerm2 Color Preset 的方法(快捷键):

看看有没有可能在 Emacs 中调用。

搞这种东西,最好了解一下"施密特触发器" 的工作原理.

2 个赞

不需要,只是 MacBook 的环境光传感器在摄像头边上。

可以连同 iTerm2 主题一起切换了:

(前 → 后)

如果只换 Emacs 主题,效果是这样的:

@xuchunyang 大佬,好像最新的macos不能发访 ambient light sensor了,方便时可以更新一下代码吗?谢谢!ps:macos big sur 11.5.1 emacs 27.2