🛠️

terminal から gopls を使う

に公開

gopls といえば、VSCode や Neovim などのエディタでコード補完や定義ジャンプを実現する LSP サーバーの Go の実装として知られています。
しかし、gopls の機能の多くはコマンドラインからも直接呼び出して利用できます。

この記事では、普段エディタ経由で使っている gopls の機能を CLI から活用する方法を紹介します。

gopls -h コマンドを実行すると、利用できるコマンドやオプションの一覧が読めます。

よく使う gopls CLI コマンド

基本の話

LSP でやり取りするメッセージの多くは「このファイルの N 行目の M 文字目」という指定をリクエストに含めています。
これを gopls コマンドを使うときには filename.go:line:column という形式で表現します。
ログなどでも出てくる形式なので、馴染みやすいかなと思います。

他にもバイトのオフセットで指定する filename.go:#123 という書き方ができますが、これは一般的ではないので使いづらそうです。

gopls definition

関数や、型、変数の定義を調べる機能がコマンドでも利用できます。

使えるオプションとして -json-markdown があり、それぞれの形式でも出力できます。

gopls definition main.go:10:15
/path/to/file.go:5:2-9: defined here as field foo *FOO

gopls definition -json main.go:10:15
{
    "span": {
        "uri":"file:///path/to/file.go",
        "start":{
            "line": 5,
            "column": 2,
            "offset": 123,
        },
        "end":{
            "line": 5,
            "column": 9,
            "offset": 130,
        },
    },
    "description": "defined here as field foo *FOO"
}

gopls definition -markdown main.go:10:15

/path/to/file.go:5:2-9: defined here as ```go
field foo *FOO

gopls references

変数や関数がどこで使われているかの一覧を取得します。

# 特定位置の識別子の参照を全て表示
gopls references main.go:12:20

gopls references -d main.go:12:20

gopls prepare_renamegopls rename

変数名や関数名、型名などを利用箇所も含めて変えるコマンドが使えます。
実行する前に gopls prepare_rename コマンドを使って、結果を確認してから rename するようにしましょう。

# できるかチェック
gopls prepare_rename main.go:12:34

# 位置を指定して新しい名前に変更
gopls rename main.go:12:34 NewFunctionName

# 差分を確認
gopls rename -d main.go:12:34 NewFunctionName

# 変更して書き込み
gopls rename -w main.go:12:34 NewFunctionName

gopls symbols

エディタのアウトラインに出すためのファイル内の関数、型、フィールドの一覧を取得します。
変数名などは取れません。

# ファイル内のシンボル一覧
gopls symbols main.go

gopls check

コンパイルエラーなど、diagnostic の情報を教えてくれます。
デフォルトでは warning 以上の情報を出力しますが、-severity オプションをつけると表示する情報のレベルを変えることができます。

# ファイルの問題をチェック
gopls check main.go

# info 以上の情報を出力する
gopls check -severity=info main.go

gopls workspace_symbol

プロジェクト全体から型や関数を検索:
-matcher オプションで検索方法を変えることができます。デフォルトは caseinsensitive ですが、fuzzyfastfuzzycasesensitive が使えます。

# "User" を含むシンボルを検索
gopls workspace_symbol User

# fuzzy 検索
gopls workspace_symbol -matcher fuzzy "Handler"

既存のツールがあるけど gopls でも使えるコマンド

コードのフォーマット

Go で使う format tool といえば gofmt が標準ですが、gopls コマンドでも同様の機能があります。

# ファイルをフォーマットして標準出力に表示
gopls format main.go

# 直接ファイルを上書き更新
gopls format -w main.go

gopls imports

こちらも goimports が基本ですが、gopls からも利用できます。

# import を整理して表示
gopls imports main.go

# 実際にファイルを更新する例
gopls imports -w main.go

その他のコマンド

これまで紹介したコマンド以外にも gopls には多くのコマンドがあります。
詳しくは gopls -h を実行し、ヘルプを読むとそれぞれの詳細が読めます。

主に2つのセクションがあります。

main

gopls を Language Server として使うための機能やサポートコマンドです。
gopls serve でサーバーを起動したり、gopls api-json で使えるメソッド一覧を JSON 形式で取得できたりします。

feature

gopls が LSP 向けに提供しているコマンドを直接呼ぶ機能です。
すでに紹介した gopls definition などの他に、 gopls signaturegopls links などがあります。

gopls コマンドの悩み

gopls の feature コマンドは terminal などから直接叩けて非常に便利です。
しかし、毎回ワークスペース全部を読み込んでいるような振る舞いをするため、大きなリポジトリでは実行にかなり時間がかかります。

生成 AI ツールに使わせる

agent ツールに使わせる

私は gopls コマンドの使い方を CLAUDE.md に記述して、利用させています。
使ってよいコマンドのリストに gopls を入れておき、 gopls コマンドを使って検索してくれと書くと頑張ってやってくれます。
私は業務では基本的に Go しか書かないので、gopls コマンドだけあれば十分に役目が果たせます。

ですが、ワークスペースを読み込むのに時間がかかるので、けっこう大変かもしれません。

MCP から使う

gopls には -mcp-listen オプションが生えています。
golang.org/x/tools/gopls/internal/mcp に実装されているサーバーを起動するようです。
パッケージにあるファイルを見ると、diagnostic や reference を返す機能が実装されています。

まとめ

gopls コマンドの機能の一部を紹介しました。
gopls は単なる LSP サーバーではなく、便利な CLI としても活用できます。
エディタを使わなくても gopls が提供する機能の恩恵を受けることができます。

普段エディタで使っている便利な機能を、CLI からも活用してみてはいかがでしょうか。

参考

Discussion