Bối cảnh
Tôi đang sử dụng after-make-frame-functions
hook để tải đúng các chủ đề trong cấu hình máy khách / máy chủ emacs . Cụ thể đây là đoạn mã mà tôi sử dụng để thực hiện điều đó (dựa trên câu trả lời SO này ):
(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)))
Vấn đề
Khi một emacsclient -c/t
phiên mới được bắt đầu, hook không chỉ được thực hiện trong khung mới, mà trong tất cả các khung tồn tại trước đó (các phiên emacsclient khác ) và nó tạo ra hiệu ứng hình ảnh rất khó chịu (các chủ đề được tải lại trong tất cả các khung đó) . Tệ hơn nữa, trong các thiết bị đầu cuối, các máy khách đã mở màu chủ đề bị rối hoàn toàn. Rõ ràng điều đó chỉ xảy ra trên các máy khách emacs được kết nối với cùng một máy chủ emacs. Lý do cho hành vi này là rõ ràng, hook được chạy trên máy chủ và tất cả các máy khách của nó bị ảnh hưởng.
Câu hỏi
Có cách nào để thực hiện chức năng này chỉ một lần hoặc nhận được kết quả tương tự mà không cần sử dụng hook không?
Một giải pháp một phần
Bây giờ tôi có mã này, nhờ câu trả lời của @ Drew. Nhưng vẫn có một vấn đề, một khi bạn bắt đầu một phiên máy khách trong thiết bị đầu cuối, GUI không tải các chủ đề đúng cách và ngược lại. Sau rất nhiều thử nghiệm, tôi nhận ra rằng hành vi phụ thuộc vào việc emacsclient bắt đầu trước và sau khi loại bỏ những thứ khác nhau, tôi nghĩ rằng nó có thể liên quan đến bảng màu được tải. Nếu bạn tải lại thủ công thì chủ đề đều hoạt động tốt và đó là lý do tại sao hành vi này không xuất hiện khi hàm được gọi bởi hook mỗi lần như trong cấu hình ban đầu của tôi.
(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)))
Giải pháp cuối cùng
Cuối cùng tôi có mã làm việc hoàn toàn để giải quyết hành vi được thấy trong giải pháp một phần, để đạt được điều này, tôi chạy chức năng một lần theo chế độ (terminal hoặc gui) khi lần đầu tiên emacsclient thích hợp được khởi động, sau đó loại bỏ hàm khỏi hook vì không cần thiết nữa. Bây giơ tôi hạnh phuc! :) Cảm ơn một lần nữa @Drew!
Mật mã:
(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)))