コンテキスト
emacsクライアント/サーバー構成でafter-make-frame-functions
テーマを適切にロードするためにフックを使用しています。具体的には、これを作成するために使用するコードスニペットです(このSO回答に基づいています)。
(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の回答のおかげで、このコードが完成しました。しかし、まだ問題があります。ターミナルでクライアントセッションを開始すると、GUIはテーマを適切にロードせず、その逆も同様です。多くのテストを行った結果、動作はどの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)))
最終的な解決策
最後に、部分的なソリューションで見られる動作を解決する完全に動作するコードがあり、これを達成するために、適切なemacsclientが初めて起動されたときにモード(端末またはgui)で関数を1回実行し、関数をフックから削除しますもう必要ありません。今、私は幸せです!:) @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)))