Настройка темы Emacs на основе внешнего освещения
Ссылка на оригинал - https://matthewbilyeu.com/blog/2018-04-09/setting-emacs-theme-based-on-ambient-l…, автор публикации - Matt Bilyeu
Я сижу рядом с окном на работе. В солнечные дни легче увидеть светлую тему редактора, а когда небо темное, темная тема становится легче для моих глаз. Поэтому я решил сделать так, чтобы мой MacBook автоматически переключал тему Emacs на основе показаний датчика внешней освещенности.
Это решение состоит из двух частей: исполняемый файл командной строки для чтения данных с датчика, а затем небольшая функция elisp для переключения тем.
Программа ниже взята со StackOverflow и немного изменена. Она получает службу AppleLMUController IO, затем, когда служба готова, печатает данные датчика освещенности в stdout и выходит.
// lmutracker.mm // // clang -o lmutracker lmutracker.mm -framework IOKit -framework CoreFoundation #include <mach/mach.h> #import <IOKit/IOKitLib.h> #import <CoreFoundation/CoreFoundation.h> static double updateInterval = 0.1; static io_connect_t dataPort = 0; void updateTimerCallBack(CFRunLoopTimerRef timer, void *info) { kern_return_t kr; uint32_t outputs = 2; uint64_t values[outputs]; kr = IOConnectCallMethod(dataPort, 0, nil, 0, nil, 0, values, &outputs, nil, 0); if (kr == KERN_SUCCESS) { printf("%8lld", values[0]); exit(0); } if (kr == kIOReturnBusy) { return; } mach_error("I/O Kit error:", kr); exit(kr); } int main(void) { kern_return_t kr; io_service_t serviceObject; CFRunLoopTimerRef updateTimer; serviceObject = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleLMUController")); if (!serviceObject) { fprintf(stderr, "failed to find ambient light sensors\n"); exit(1); } kr = IOServiceOpen(serviceObject, mach_task_self(), 0, &dataPort); IOObjectRelease(serviceObject); if (kr != KERN_SUCCESS) { mach_error("IOServiceOpen:", kr); exit(kr); } setbuf(stdout, NULL); updateTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + updateInterval, updateInterval, 0, 0, updateTimerCallBack, NULL); CFRunLoopAddTimer(CFRunLoopGetCurrent(), updateTimer, kCFRunLoopDefaultMode); CFRunLoopRun(); exit(0); }
Сопровождающий elisp-код будет вызывать этот исполняемый файл по таймеру и менять тему в зависимости от показаний света.
(setq current-theme "dark")
(defconst light-theme 'majapahit-light)
(defconst dark-theme 'majapahit-dark)
;; будет применять темную тему, если комната темная, и светлую тему, если комната светлая
(defun change-theme-for-lighting ()
(let* ((current-light-sensor-reading
(string-to-number
(shell-command-to-string "./lmutracker"))))
(if (< current-light-sensor-reading 100000)
(when (not (string-equal current-theme "dark"))
(load-theme dark-theme 1)
(setq current-theme "dark"))
(when (not (string-equal current-theme "light"))
(load-theme light-theme 1)
(setq current-theme "light")))))
;; вероятно, нужно запускать реже, чем каждую секунду
(run-with-timer 0 1 #'change-theme-for-lighting)
Хотите больше полезных советов? Смотрите и подписывайтесь на наш канал! Здесь я публикую лучшие советы для пользователей Андроид, Windows, iOS и Mac OS. Также вы можете задать мне любой вопрос, подписавшись на канал.