久しぶりに .emacs.d (Emacsの設定)を新たに書き直しています。
(かなり)重い腰を上げた理由は、新しいMacBookに切り替えたこととか、ふとEmacs 27から29に上げたらEmacs環境が壊れたこととかいろいろあるのですが、設定をモダンにやり切るところまでやろうと思ったのは、やはり @takeokunn からの突き上げ?がvim-jpラジオでピークに達したことが理由です*1。
audee.jp
audee.jp
最初は「今の設定が動くところまで」だけで終わっていたんですけどね。
最後の最後にvim-jpラジオを聴いて「やるかああああああああ」となりました。上記のエピソードはEmacserにとてもオススメです。やる気にさせてくれます*2。
やはり道具としてのEmacs、使い込まないといけないですね*3。
20252021年最新のEmacsの設定
さて、何がモダンなEmacsの設定なのかというと、2021年の記事ですが以下がとてもわかりやすいです。信頼できる筋のエントリなので信頼できます。
blog.tomoya.dev
今時のEmacserには普通なんだと思いますが、私は2024年までHelm / Companyで止まっていましたからね。隔世の感があります。
ようは
- Emacsの標準の機能を駆使する
- 小さなパッケージを組み合わせる
というのがトレンドのようです。
Vertico、Consult、Corfu、Orderless、Marginalia、Embark らへんが、主力っぽいです。
よーし、だんだんわかってきた。
fido-vertical-modeを使う
さらに、確かな信頼できる筋のエントリを見てみます。これも2021年。
qiita.com
Emacs 28から fido-vertical-mode
というVerticoっぽいマイナーモードが、Emacs標準で提供されたそうです。
で、
「”Emacsの標準の機能を駆使する”のがトレンドなら、Verticoよりもfido-vertical-modeを使ったほうが良いのではないか」
という安直な動機で、fido-vertical-mode を使うことにしました。
(fido-vertical-mode +1)
が、
どうやらまだ時代はVerticoのようで、fido-vertical-modeの設定例があまりなく、少し困ったので、いくつか設定を共有します。
補完のためのミニバッファの領域を大きくしたい
Anything/Helm時代、私は補完候補を大きく画面の半分に出して使うスタイルだったのですが、初期設定だとConsult(+ fido-vertical-mode)で補完候補を出しても、画面の1/4程度しか出してくれません。
Verticoであれば vertico-count
で設定できるっぽいのですが、fido-vertical-mode に fido-vertical-count
はありません。
じゃあどうすればいいのか。ということで icomplete.el*4のソースコードを見に行ったらそれらしい記述がありました。
As many completion candidates as possible are displayed, depending on
the value of max-mini-window-height', and the way the mini-window is
resized depends on
resize-mini-windows'.
emacs/lisp/icomplete.el at 6a299b3caceb2c73b932ba73849738faa8c5d975 · emacs-mirror/emacs · GitHub
*5
さらに設定例までありました。なるほど。
(add-hook 'icomplete-minibuffer-setup-hook
(lambda () (setq-local max-mini-window-height 3)))
will constrain Emacs to a maximum minibuffer height of 3 lines when
icompletion is occurring.
emacs/lisp/icomplete.el at 6a299b3caceb2c73b932ba73849738faa8c5d975 · emacs-mirror/emacs · GitHub
というわけで、私は画面の半分(50%)まで表示させたいので小数点以下の値を使って以下のように設定しました。
(add-hook 'icomplete-minibuffer-setup-hook
(lambda ()
(setq-local max-mini-window-height 0.5)))
なお、max-mini-window-height
に自然数を設定すると表示画面割合ではなく表示行数になります。便利。
補完スタイル( completion-styles
)にOrderlessを使いたい
www.gnu.org
補完スタイル(主に補完候補の絞り込みのスタイル)をOrderlessをはじめとする便利なスタイルに切り替えるのが良いとのことなので以下のように設定してみましたがうまく補完スタイルがデフォルトから変更されません。
(fido-vertical-mode +1)
(use-package consult
:ensure t
:hook (completion-list-mode . consult-preview-at-point-mode))
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion)))))
また icomplete.el のソースを見にいくと、fido-vertical-mode( fido-mode )の起動タイミングで completion-styles
が flex
に上書き設定されていることがわかりました( icomplete--fido-mode-setup
関数)。
emacs/lisp/icomplete.el at 6a299b3caceb2c73b932ba73849738faa8c5d975 · emacs-mirror/emacs · GitHub
icomplete--fido-mode-setup
関数は minibuffer-setup-hook にフックされているっぽいので、発火タイミングを調整しながら、さらに completion-styles
を上書き設定するようにしました。
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion))))
:config
(remove-hook 'minibuffer-setup-hook #'icomplete--fido-mode-setup)
(add-hook 'minibuffer-setup-hook
(lambda ()
(setq-local completion-styles '(orderless basic))))
(add-hook 'minibuffer-setup-hook #'icomplete--fido-mode-setup))
なお、 orderless doesn't work with fido · Issue #110 · oantolin/orderless · GitHub でも同じようなワークアラウンドが紹介されていました。
もう少しスッキリ書きたかったのですが、今のElisp力ではここまで。
2025/1/14 10:28追記
早速有識者からアドバイスをいただきました。ブログ書いて良かった。
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion))))
:config
(add-hook 'minibuffer-setup-hook
(lambda ()
(setq-local completion-styles '(orderless basic)) t))
スッキリ!
Orderlessのスペース区切りと相性が悪いのをなんとかしたい(2025/1/14 15:17追記)
vim-jp Slackの #tech-emacs チャンネルで、fido-vertical-modeを使っているとスペース入力でワード補完が走ることがあり、それがOrderlessの「スペース区切りでの補完キーワード列挙」の機能と相性が悪いというのを教えていただきました。
設定時は気づいていなかったのですが、確かにスペースでワード補完が走ってしまうことある*6ことがわかりました。
ソースを追ってみると minibuffer.el のkeymapとバッティングしていることがわかりました。
emacs/lisp/minibuffer.el at e6ad99e36c6c2e5322381f8af48cc283d2d899dc · emacs-mirror/emacs · GitHub
ということで無効化します。
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion))))
:config
(keymap-unset minibuffer-local-completion-map "SPC")
(add-hook 'minibuffer-setup-hook
(lambda ()
(setq-local completion-styles '(orderless partial-completion))) t))
なお、最近は define-key
global-set-key
ではなく keymap-set
keymap-global-set
を使うらしいです(これも #tech-emacs チャンネルで教えてもらいました)。
naokton.hatenablog.com
今のところ fido-vertical-mode で十分満足
Verticoを使ったことがないのでアレなんですが、今のところ fido-vertical-mode で十分満足しています。Marginaliaもちゃんと連携できますし。
「Emacsの標準の機能を駆使する」という意味ならまあ良い選択なのではないかなと。
有識者のアドバイスお待ちしております。