🖋️

[Emacs] rust-analyzerのcompletion snippetsをカスタマイズしたい

2024/04/10に公開

今回もEmacsネタですが。

EmacsでRust書くときは
brotzeit/rustic: Rust development environment for Emacs
こちらにお世話になっています。

ちょっと前まで

hoge.ok

と書くと

Ok(hoge)

に変換されるスニペットがあったのですが
どうも最近デフォルトのスニペットから無くなったようで困ってました。

.ok() postfix snippet is annoying · Issue #9636 · rust-lang/rust-analyzer
internal: Remove a few snippet completions, replace them with user snippets definitions by Veykril · Pull Request #10527 · rust-lang/rust-analyzer

これなんですかね?結構前なんですね。
知りませんでした。

hoge.dbg

などは残っているので、ほしい人はカスタマイズしなさいね。ということなんですね 🤔

https://github.com/rust-lang/rust-analyzer/blob/a5feb4f05f09adca661c869b1bf2324898cbaa43/crates/ide-completion/src/snippet.rs#L56-L101

まぁ、カスタマイズできそうなのでやってみましょう。

環境

Emacs : 29.1
rust-analyzer: 9cced6da93 2024-04-05

rust-analyzer のマニュアルを見てみる

User Manual

rust-analyzer.completion.snippets.custom

{
    "Ok": {
        "postfix": "ok",
        "body": "Ok(${receiver})",
        "description": "Wrap the expression in a `Result::Ok`",
        "scope": "expr"
    }
}

こんなjsonを渡せばいけそうですね。

rust-analyzerの設定をカスタマイズする方法

https://rust-analyzer.github.io/manual.html#eglot

ありたがいことにEglot向けのカスタマイズ方法が書いてありました。

Language Server Protocol Specification - 3.17

LSPの仕様にも initializationOptions があるんですね。勉強になりました。

やってみる

  (add-to-list 'eglot-server-programs
               `(rustic-mode . ("rust-analyzer" :initializationOptions
                                ( :procMacro (:enable t)
                                  :cargo ( :buildScripts (:enable t)
                                           :features "all")
                                  :completion ( :snippets ( :custom
                                                            ( :Ok ( :postfix "ok"
                                                                    :body "Ok(${receiver})"
                                                                    :description "Ok($expr)"
                                                                    :scope "expr"
                                                                    )
                                                              :Some ( :postfix "some"
                                                                      :body "Some(${receiver})"
                                                                      :description "Some($expr)"
                                                                      :scope "expr"
                                                                      )
                                                              )))))))

こんな感じで入れてみました。

  • procMacrocargo はおまけです
  • completion 以降が今回のメイン
    • .okOk でラップする
    • .someSome でラップする
    • という2つのスニペットを追加

結果

無事達成できました

Discussion