フックを「グループ化」するにはどうすればよいですか?


14

末尾の空白の表示、バッファ境界の表示、虹色の区切り文字など、特定の機能があります。ほとんどのモードで有効にしたいのですが、プログラミングやテキスト関連のすべてのモードを有効にします(末尾のスペースを表示するため、たとえばediff-mode、例外ルールでグローバル化されたマイナーモードを使用する代わりに、メジャーモードと競合します。ほとんどのモードは、いずれかに由来しているためprog-modetext-mode、両方に該当の機能を追加prog-mode-hookしてtext-mode-hook作業を行い、しかし、そのような、本明細書以下ではない十分なモードがあるcss-modeかはLaTeX-mode

とりあえずこれらのすべてのモードを含むフックを定義して、1つのフックに機能を追加するだけにします。呼び出しましょうnon-special-mode-hook(区別するためspecial-mode-hook)。そのために作られたすべての主要なモードで実行されるフックをどのように作成できますか?


回答:


19

これらの設定を1つの関数にグループ化し、その関数を関連するすべてのフック関数に追加するだけです。

(defun my-non-special-mode-setup ()
  (setq show-trailing-whitespace t)
  ...)
(dolist (hook '(prog-mode-hook text-mode-hook css-mode-hook ...))
  (add-hook hook 'my-non-special-mode-setup))

これを行う他の方法はこれ以上簡潔ではありません。モードのホワイトリストまたはブラックリストのいずれかを持っている場所で、何が起こっても何も起こりません。実際には、リストに追加する必要のあるモードがいくつかあるだけなので、単純にすることをお勧めします。

私自身の設定では、このトリック正確使用して、いくつかのLisp指向モードの設定を統一します。


ありがとう、私はこのソリューションを他の有用なグループ(lispyグループなど)に適応させると思います。
wasamasa 14

1
それはまさに私自身がやっていることです:github.com/purcell/emacs.d/blob/…– sanityinc 14
13:07に

1
すばらしい、答えにURLを追加できますか?ハイライトされたスニペットは実際の使用法を非常によく説明するだけでなく、Emacs Lisp関連の「フック」をより大きな「フック」のサブセットとして使用するなど、既存のメジャーモードからフック名を自動的に作成する方法などのさらなる使用法も示していると思いますでderived-mode-hook-name
wasamasa 14

私は(dolist ...)vs (add-hook ...)<repeat>のためだけにこれが私のものよりも好きです。モード固有を維持することは別の(ファイルあたりのモードを変更したとき、私は唯一の鉱山に固執したいですuse-packageel-get)。両方ともオールインワンのソリューションですが、異なる視点からのものです。
ジョナサンリーチペピン14

ここに非nil APPEND引数を指定しadd-hookない場合、フックは指定したリストの順序と逆の順序で呼び出されることに注意してください。それに関して何も問題はありません。順序が重要な場合に備えて、注意してください。
ドリュー

5

に関数を追加してafter-change-major-mode-hook、新しいモードが(おそらくを介して(not (derived-mode-p 'special-mode)))興味深いモードであるかどうかをチェックし、そうであれば実行されnon-special-mode-hookます。


これはかなり気の利いたように見えます(一度使用するfundamental-modeだけで、テキストを表示するだけではないため、すべての「特殊」モードがわかったのですが)。したがって、賛成票。
wasamasa

4

自分の設定とマイナーモードのアクティブ化をdefunにラップし、フックをループして呼び出す@sanityincのパターンを頻繁に実行していることに気づきましたが、よりクリーンなアプローチが必要だったため、このマクロを作成しました。

(defmacro hook-modes (modes &rest body)
  (declare (indent 1))
  `(--each ,modes
     (add-hook (intern (format "%s-hook" it))
               (lambda () ,@body))))

注:私はdash.el清潔を求めていますが、を使用するように簡単に調整できます(dolist)

次に、グループ化されたモードをリスト変数として定義し、次のように使用できます。

(defvar progish-modes
  '(prog-mode css-mode sgml-mode))

(hook-modes progish-modes
  (highlight-symbol-mode)
  (highlight-symbol-nav-mode))

1
ここderived-mode-hook-nameで、モードのフック変数の名前を取得するために使用できるため、internトリックを回避できることに注意してください。
sanityinc

@sanityinc TIL derived-mode-hook-name。素敵なヒント!
waymondo

1

これらのすべての非派生モードで機能する新しいフックを定義するのではなく、次のことができます。

(defun run-my-hooks ()
  "Run all the following functions in the hook"
  (smartparens-mode 1)
  (whitespace-mode 1)
  (my-needed-mode 1)
  ...)

(add-hook 'specific-mode-hook 'run-my-hooks)
(add-hook 'another-mode-hook 'run-my-hooks)

それでもすべてのモードに追加する必要がありますが、すべてのモードを含むように関数を定義することにより、追加機能を追加/削除するときに1つの定義を変更するだけで済みます。


-2

たぶんあなたはこれを試すことができます:

(setq lisp-dialects-mode-hook '(lisp-mode-hook
                            lisp-interaction-mode-hook
                            emacs-lisp-mode-hook
                            ;; common-lisp-mode-hook
                            scheme-mode-hook
                            clojure-mode-hook
                            cider-repl-mode-hook
                            ))

(add-hook 'lisp-dialects-mode-hook 'func)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.