Helixでのスニペットの設定の仕方を探していたのだけれど、スニペットはスニペット用のLSPとして設定するようだ。
探すと2つほど見つかったのだが、hx-lspというのをとりあえず入れてみた。
自分の使い方としてはAtCoderやるときに自作ライブラリを単に挿入するだけなので、LSP導入するほどか?とも思うのだけど、VSCodeではスニペットで実装していたので、VSCodeのスニペットがそのまま移行できそうだったこと、rustで実装されていて1バイナリになることからこれにした。ちなみにもう一つのはnpmパッケージだった。
導入に当たり、行ったことを記録しておく。基本的にはREADME通りで大丈夫
hx-lspのインストール
rustup update
cargo install hx-lsp
rust関係はAHC用にインストールしてある。念の為、rustupで最新にしておく
language.toml への設定追記
LSPの設定とそれをrubyで使用するように設定。
ruby用にsolargraphも設定しているので、マルチLSP環境の設定にする。
use-grammars = { only = ["ruby", "toml", "bash", "hcl", "yaml", "lua"]}
[language-server.hx-lsp]
command = "hx-lsp"
[[language]]
name = "ruby"
language-servers = [ "solargraph", "hx-lsp" ]
VSCode用のスニペットをhx-lsp用のディレクトリにコピー
$HOME/.config/helix/snippets/ruby.json
が、hx-lsp用のスニペットを置いておくところなので、VSCode用に作ったスニペット用のjsonファイルと同じものを置くと使える。
自分はライブラリのコードをまるごとスニペットに変換するスクリプトを使用しているため、そのファイルでhelix用のスニペットファイルも一緒に作っている。
#!/bin/bash
function snippet_entry() {
local key=$1
local prefix=$2
local file=$3
local body=$(jq '.' "$file" -R | jq -s '.')
local args=()
args+=(--arg name "$key")
args+=(--arg prefix "$prefix")
local filter='{ key: $name, value: {prefix: $prefix, body: . }}'
jq "${args[@]}" "$filter" <<<"$body"
}
function add_snippet(){
local key=$1
local prefix=$2
local file=$3
local entry=$(snippet_entry "$key" "$prefix" "$file")
snippets+=("$entry")
}
function merge_snippets(){
jq 'from_entries' -s <<<"${snippets[*]}"
}
snippets=()
SNIPPETS_DIR="$(cd $(dirname $0); pwd)/../lib"
VSCODE_SNIPPETS_PATH=$HOME/.config/Code/User/snippets/ruby.json
HELIX_SNIPPETS_PATH=$HOME/.config/helix/snippets/ruby.json
for f in $SNIPPETS_DIR/*.rb; do
add_snippet "$(basename $f)" "$(basename $f)" "$f"
done
merge_snippets | tee "$VSCODE_SNIPPETS_PATH" "$HELIX_SNIPPETS_PATH"
使い方
挿入モードでprefixに一致するスニペットが表示されるので、選択するとコードがまるっと挿入される。VSCodeのときと近い使い心地で悪くない。