あれ?もう三月?という程度には時間の流れが早くて色々ビビってます。
最近仕事の方に時間が割かれがちなので、ちょっと埋め草的にEmacsの設定を紹介してみます。
company→corfu
長いこと利用していた company-modeから、corfuに完全移行しました。理由は特になくって、company-modeの機能をそこまで利用していないし、もっとライトウェイトなものでもいいなー、と思っていたところで見付けました。
Corfu enhances completion at point with a small completion popup. The current candidates are shown in a popup below or above the point. Corfu is the minimalistic completion-in-region counterpart of the Vertico minibuffer UI.
corfuの冒頭を引用すると↑のようになります。completion-at-point-functions、通帳capfsのインターフェースを利用した補完インターフェース、だけしか提供していません。 company-modeでは、company-backendとかで追加する必要がありました。corfuは、独自ではなく、あくまでEmacsの補完インターフェースに沿ったものである、ということが特徴ですね。
この作者が作成したパッケージとして、同じようにミニマルな verticoなどがあり、こちらも利用しています。
今の設定はこんな感じです。
(leaf corfu
:straight (corfu :type git :host github :repo "minad/corfu")
:require t
:custom
(corfu-cycle . t) ;; Enable cycling for `corfu-next/previous'
(corfu-auto . t) ;; Enable auto completion
(corfu-auto-delay . 0.01) ;; Enable auto completion
(corfu-count . 15) ;; show more candidates
(corfu-auto-prefix . 3)
(corfu-max-width . 150) ;; max width of corfu completion UI
(corfu-commit-predicate . #'my:corfu-commit-predicate) ;; Do not commit selected candidates on next input
(corfu-quit-no-match . 'separator)
(corfu-separator . ?\s)
(corfu-preview-current . t) ;; Disable current candidate preview
;; (corfu-preselect-first nil) ;; Disable candidate preselection
(corfu-echo-documentation . nil) ;; Disable documentation in the echo area
;; (corfu-scroll-margin 5) ;; Use scroll margin
:bind
(:corfu-map
("SPC" . corfu-insert-separator))
:preface
;; from https://github.com/minad/corfu/wiki
(defun my:corfu-commit-predicate ()
"Auto-commit candidates if
1. A \".\" is typed, except after a SPACE.
2. A key is typed after corfu-complete
3. A selection was made, aside from entering SPACE.
"
(cond
((seq-contains-p (this-command-keys-vector) ?.)
(or (string-empty-p (car corfu--input))
(not (string= (substring (car corfu--input) -1) " "))))
((equal last-command #'corfu-complete)
(or (string-empty-p (car corfu--input))
(not (string= (substring (car corfu--input) -1) " "))))
((/= corfu--index corfu--preselect) ; a selection was made
(not (seq-contains-p (this-command-keys-vector) ? )))))
:config
(corfu-global-mode))
corfu-auto
ってのを設定して、自動で表示されるようにしていますが、その代わりにprefixを3としています。これはなんでかというと、↑の設定だと、company-modeみたいにドット .
で区切る、みたいな真似ができないからです。その代わりに、orderlessを利用した検索ができるので、そこはトレードオフになっています。実際、lspを使っていたりすると、1文字とかで表示されても非常にうざったいことになったし、1文字だけで検索すること自体がほぼありえなかったので、これでもわりと困りません。困る場合はゼロとは言いませんが・・・。
auto-buffer-save-enhanced → super-save
auto-buffer-save-enhancedが、メンテナンスされていない状態が非常に長くなっており、さすがに気になってきたので、切り替えました。いくつかありましたが、一番利用されていそうな super-saveを利用しています。
ただ、super-saveだと、auto-buffer-save-enhancedで便利だった、 現在表示していないバッファも自動で保存する というがデフォルトでできない・・・というのがありました。
PRはでています。
そこで、PRを参考にして、以下のような設定にして使っています。
(leaf super-save
:straight (super-save :type git :host github :repo "bbatsov/super-save")
:custom
;; auto save when idle
(super-save-auto-save-when-idle . nil)
:config
(defun my:super-save-command ()
"all-buffer version 'super-save-command'"
(let ((buffer-to-save (buffer-list)))
(save-excursion
(dolist (buffer buffer-to-save)
(set-buffer buffer)
(when (and buffer-file-name
(buffer-modified-p (current-buffer))
(file-writable-p buffer-file-name)
(if (file-remote-p buffer-file-name) super-save-remote-files t)
(super-save-include-p buffer-file-name))
(save-buffer))))))
;; adivceで再定義する
(advice-add 'super-save-command ':override #'my:super-save-command)
(super-save-mode +1)
(add-to-list 'super-save-triggers #'ace-select-window)
(add-to-list 'super-save-triggers #'ace-window))
idleで保存されると、snippetsとか使うときにひじょーに邪魔になることがわかっていたので、あえて定義していません。その代わり、PRを参考にして、super-save-commandをadviceで上書きしています。本当はもうちょっといいやりかたしたらいいんですが、動くのでまぁこれでいいや、ってやってます。
実は、再起動したりすると上手くtriggersの設定が反映されないこととかあるんですが、とりあえずはこれで動いていますし、不便も感じていないです。
kind-icon
corfuを利用するようになって、ちょっとだけ困ったというか、見栄えが気になったのがアイコン部分ですが、これについてはkind-iconを利用することで解消できました。
こちらも特に不満なく利用できています。all-the-iconsよりも軽量なのでこれまたいいかんじです。
modus-theme
長いことgruvboxを利用していましたが、心機一転で、emacs28から標準添付されるようになるmodus-themeを利用しています。
見た目は↑みたいな感じです。コントラストが結構はっきりしていて、アクセントもきつすぎず薄すぎず、ちょうどいいです。また、かなり広範囲のfaceに渡って設定が入っていて、 え、ここもあるの みたいなfaceになったりしてちょっとびっくりしたりもします。
ときたまパッケージを更新するのも大事
最近は、上記に加えてconsultとか、ミニマルなものを組み合わせて利用する形が多いです。anything/helm/ivyのような、 すべての箇所で統一した補完インターフェース というわけではないですが、Emacsの標準インターフェースをできるだけ利用するようにしたり、faceに独自性をあえてつけないことで、逆に一貫した見た目を提供したりできています。また、検索もorderlessが通底して広く利用されていることで、ほとんどの箇所で同じような補完を利用できますので、これまた意外と操作感もおおきく変わりません。
embarkのような、操作感というか概念が大きく変わるようなものがあると、それはそれで慣れないのですが
もちろん、company/ivyを利用するという選択も全く問題ないですし、逆に小さいパッケージだとできないことができたりもします。それらを考えて構成していく、というのも一興だと思うので、組み合わせを探ってみるのもいいんじゃないでしょうか。
VSCode使ってるとかだとそういうこともできませんが。