Контекст
Я використовую after-make-frame-functions
гачок для належного завантаження тем у конфігурації клієнта / сервера emacs . Зокрема, це фрагмент коду, який я використовую, щоб зробити це (виходячи з цієї відповіді ТАК ):
(if (daemonp)
(add-hook 'after-make-frame-functions
(lambda (frame)
(select-frame frame)
(load-theme 'monokai t)
;; setup the smart-mode-line and its theme
(sml/setup)))
(progn (load-theme 'monokai t)
(sml/setup)))
Проблема
Коли emacsclient -c/t
запускається новий сеанс, гак виконується не тільки в новому кадрі, але і у всіх попередніх існуючих кадрах (інші сеанси emacsclient ), і це робить дуже дратівливий візуальний ефект (теми завантажуються знову у всі ці кадри) . Ще гірше, що в терміналі клієнти вже відкрили колір теми, повністю заплутавшись. Очевидно, що це відбувається лише на клієнтах emacs, підключених до одного сервера emacs. Причина такої поведінки зрозуміла, гачок виконується на сервері, і всі його клієнти постраждали.
Питання
Чи є спосіб виконати цю функцію лише один раз або отримати той самий результат, не використовуючи гачок?
Часткове рішення
Зараз у мене цей код, завдяки відповіді @ Drew. Але все-таки є проблема, коли ви запускаєте сеанс клієнта в терміналі, графічний інтерфейс не завантажує теми належним чином і навпаки. Після багатьох тестів я зрозумів, що поведінка залежить від того, який emacsclient починається спочатку, і після відмови від різних речей я думаю, що це, можливо, пов'язане з завантаженою палітрою кольорів. Якщо ви перезавантажуєте тему вручну, все працює добре, і саме тому ця поведінка не з’являється, коли функція викликається гаком кожен раз, як у моїй початковій конфігурації.
(defun emacsclient-setup-theme-function (frame)
(progn
(select-frame frame)
(load-theme 'monokai t)
;; setup the smart-mode-line and its theme
(sml/setup)
(remove-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)))
(if (daemonp)
(add-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)
(progn (load-theme 'monokai t)
(sml/setup)))
Остаточне рішення
Нарешті, у мене є повністю працюючий код, який вирішує поведінку, бачену в частковому рішенні, для досягнення цього я запускаю функцію один раз за режимом (термінал або gui), коли потім вперше запускається відповідний emacsclient, а потім знімаю функцію з гачка, оскільки є більше не потрібно. Тепер я щасливий! :) Дякую ще раз @Drew!
Кодекс:
(setq myGraphicModeHash (make-hash-table :test 'equal :size 2))
(puthash "gui" t myGraphicModeHash)
(puthash "term" t myGraphicModeHash)
(defun emacsclient-setup-theme-function (frame)
(let ((gui (gethash "gui" myGraphicModeHash))
(ter (gethash "term" myGraphicModeHash)))
(progn
(select-frame frame)
(when (or gui ter)
(progn
(load-theme 'monokai t)
;; setup the smart-mode-line and its theme
(sml/setup)
(sml/apply-theme 'dark)
(if (display-graphic-p)
(puthash "gui" nil myGraphicModeHash)
(puthash "term" nil myGraphicModeHash))))
(when (not (and gui ter))
(remove-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)))))
(if (daemonp)
(add-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)
(progn (load-theme 'monokai t)
(sml/setup)))