Hare 言語に簡単な LSP を設定する

TL;DR

  • Universal Ctags をインストールし、下記の Hare 言語設定を保存する
  • ctags-lsp をインストールする (そのために Go 処理系のインストールが必要になる場合あり)
  • エディタ/IDE に、Hare 言語には ctags-lsp を使うよう設定する

はじめに

Hare 言語 用の簡単な LSP を設定できたので、作業記録を残しておきます。

Hare の FAQ によれば、今のところ Hare にはメンテナンスされている LSP サーヴァがありません。 言語開発陣の提供する Vim プラグインを使う分には LSP がなくても特に困らないのですが、 筆者が Helix エディタ を試用する際に Hare 用の LSP が欲しかったので、既存ツールの組み合わせで簡単なものを設定しました。

設定の方針

LSP サーヴァとして ctags-lsp を使います。 これは、ソースコードの解析を Universal Ctags に任せ、 その結果を利用して LSP の「補完」と「定義へのジャンプ」のみを提供するものです。 LSP サーヴァとしては機能が限られていますが、その代わりに設定が不要で、 Universal Ctags が対応する多くの言語で利用できるという利点があります。

Hare 用の Universal Ctags 設定は、Hare のサイトやコミュニティを検索しても見つからなかったため、 自作しました。

Universal Ctags の設定

まずは自分の作業環境に合わせて Universal Ctags をインストールします。 この際、JSON 出力のサポートが必要です。 インストール後、 ctags --version の出力に +json が含まれることを確認してください。 筆者は Fedora のパッケージでインストールしました。

次に、Hare 言語を解析できるよう設定します。 以下の内容を $XDG_CONFIG_HOME/ctags/hare.ctags (大抵の場合は ~/.config/ctags/hare.ctags) にセーブします。

--langdef=Hare
--langmap=Hare:.ha
--kinddef-Hare=f,function,functions
--kinddef-Hare=s,structure,structs
--kinddef-Hare=e,enum,enums
--kinddef-Hare=E,event,errors
--kinddef-Hare=c,const,consts
--kinddef-Hare=v,variable,variables
--kinddef-Hare=C,class,types
--regex-Hare=/^(export\s+)?fn\s+([a-zA-Z_][a-zA-Z0-9_]*)/\2/f/x
--regex-Hare=/^@test\s+fn\s+([a-zA-Z_][a-zA-Z0-9_]+)/\1/f/x
--regex-Hare=/^(export\s+)?type\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*struct\s*\{/\2/s/x
--regex-Hare=/^(export\s+)?type\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*union\s*\{/\2/s/x
--regex-Hare=/^(export\s+)?type\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*enum\s+/\2/e/x
--regex-Hare=/^(export\s+)?type\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*!/\2/E/x
--regex-Hare=/^(export\s+)?type\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=/\2/C/x
--regex-Hare=/^(export\s+)?def\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*[:=]/\2/c/x
--regex-Hare=/^(export\s+)?const\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*[:=]/\2/c/x
--regex-Hare=/^(export\s+)?let\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*[:=]/\2/v/x

セーブ後に念のため ctags --version をもう一度実行し、エラーが起きないことを確認してください。

この設定は ctags-lsp と組み合わせる前提のもので、そのため2点ほど妥協点があります。 LSP の Symbol Kind (シンボルの種類に付ける番号) には、Hare のユーザ定義型とユーザ定義エラー型に対応するものがありません。 このため、前者はクラス、後者はイヴェント扱いとしています。

ctags-lsp のインストール

あまり広く使われているツールではないため、パッケージとしてインストールできるのは Homebrew のみのようです。 Homebrew では brew install netmute/tap/ctags-lsp でインストールします。

それ以外の場合は、Go 言語 のソースからビルドする必要があります。 まずは、自分の作業環境に合わせて Go 処理系をインストールします。 その後、go install github.com/netmute/ctags-lsp@latest とすると、 ctags-lsp をインストールできます。

インストール手順について、詳しくは ページ を参照してください。

インストール後は、特に設定は必要ありません。 ctags-lsp の実行ファイルがある場所のみ確認しておいてください。 Go 言語の作業を ~/go/ 以下でやる運用なら、 ~/go/bin/ctags-lsp になる場合が多いと思います。

また、ctags-lsp から ctags を起動できる必要があります。 ctags へ PATH が通っていることを確認してください。 ctags-lsp に専用のコンテナを割り当てて使う場合は、 そのコンテナ内で ctags を起動できる必要があります。

エディタ/IDE の設定

使用するエディタや IDE に合わせて、Hare 言語用の LSP サーヴァには ctags-lsp を使用するよう設定します。 詳しくはお使いのエディタ/IDE のマニュアルを参照してください。

Helix エディタの場合

設定ファイル $XDG_CONFIG_HOME/helix/languages.toml の該当部分は以下のようになります。 commandctags-lsp 実行ファイルを指定するよう書き換えてください。

[language-server.ctags-lsp]
command = "/YOUR/HOME/DIRECTORY/go/bin/ctags-lsp"

[[language]]
name = "hare"
language-servers = [ "ctags-lsp" ]

LSP が上手く利用できない時は Helix のエラーログ ~/.cache/helix/helix.log に何かメッセージが出ているかもしれません。 筆者の場合、ハマり所は上記の通り、 Universal Ctags の設定に問題があったことと、 および ctags-lspctags を見つけられなかった事の 2 点でした。

まとめ

Helix のシンボルピッカーを使っている様子 (Bluesky 投稿)

既存ツールの組み合わせで、簡易的ですが Hare 言語用の LSP を設定することができました。