环境变暗时用暗色主题,变亮时用亮色主题:
(除了关灯,用手挡住 Macbook 上的摄像头的位置也行。)
文中用的是 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 中调用。
guo
8
搞这种东西,最好了解一下"施密特触发器" 的工作原理.
2 个赞
不需要,只是 MacBook 的环境光传感器在摄像头边上。
@xuchunyang 大佬,好像最新的macos不能发访 ambient light sensor
了,方便时可以更新一下代码吗?谢谢!ps:macos big sur 11.5.1 emacs 27.2
原文引用的原帖有新的代码:macos - How do you programmatically access the ambient light sensor on Mac OS X 10.5+? - Stack Overflow
改了一下输出搬过来:
// lmutracker.mm
//
// clang -o lmutracker lmutracker.mm -F /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/PrivateFrameworks -framework Foundation -framework IOKit -framework CoreFoundation -framework BezelServices
#include <mach/mach.h>
#import <Foundation/Foundation.h>
#import <IOKit/IOKitLib.h>
#import <IOKit/hidsystem/IOHIDServiceClient.h>
typedef struct __IOHIDEvent *IOHIDEventRef;
#define kAmbientLightSensorEvent 12
#define IOHIDEventFieldBase(type) (type << 16)
extern "C" {
IOHIDEventRef IOHIDServiceClientCopyEvent(IOHIDServiceClientRef, int64_t, int32_t, int64_t);
double IOHIDEventGetFloatValue(IOHIDEventRef, int32_t);
IOHIDServiceClientRef ALCALSCopyALSServiceClient(void);
}
static double updateInterval = 0.1;
static IOHIDServiceClientRef client;
static IOHIDEventRef event;
void updateTimerCallBack(CFRunLoopTimerRef timer, void *info) {
double value;
event = IOHIDServiceClientCopyEvent(client, kAmbientLightSensorEvent, 0, 0);
value = IOHIDEventGetFloatValue(event, IOHIDEventFieldBase(kAmbientLightSensorEvent));
printf("%8f", value);
CFRelease(event);
}
int main(void) {
kern_return_t kr;
CFRunLoopTimerRef updateTimer;
client = ALCALSCopyALSServiceClient();
if (client) {
event = IOHIDServiceClientCopyEvent(client, kAmbientLightSensorEvent, 0, 0);
}
if (!event) {
fprintf(stderr, "failed to find ambient light sensors\n");
exit(1);
}
CFRelease(event);
setbuf(stdout, NULL);
printf("%8f", 0.0);
updateTimer = CFRunLoopTimerCreate(kCFAllocatorDefault,
CFAbsoluteTimeGetCurrent() + updateInterval, updateInterval,
0, 0, updateTimerCallBack, NULL);
CFRunLoopAddTimer(CFRunLoopGetCurrent(), updateTimer, kCFRunLoopDefaultMode);
CFRunLoopRun();
exit(0);
}
1 个赞