Gopls: Webベースの機能
LSPのwindow.showDocumentリクエストを使用すると、サーバーはクライアントにエディターでファイルを開くか、ブラウザーでウェブページを開くように指示できます。これは、ウェブインターフェースを通じてプログラムに関する情報を報告するgoplsのいくつかの機能の基盤となっています。
Webインターフェースがすべての人にとって理想的ではないことは認識しています。一部のユーザーはフルスクリーンエディターレイアウトを好み、ウィンドウ切り替えを嫌います。また、ウィンドウシステムのないテキストのみの端末で作業するユーザーもいます。たとえば、リモートssh経由やLinuxコンソール上での作業です。残念ながら、LSPにはいくつかの自然な種類の拡張性、たとえばサーバーが定義する機能が欠けています。
- 参照クエリを一般化するクエリで、同様のUI要素を使用して結果を表示するもの。
- テキストストリームを生成するコマンド。典型的なシェルコマンドやコンパイラのように、クライアントがエディタの通常の端末のようなUI要素にリダイレクトできるもの。または
- リネームのように、ユーザーに追加情報の入力を促すリファクタリング操作。
WebベースのUIは、LSPがこれらの機能を実装するための標準的な方法を提供するまでの間、これらのギャップを埋めるのに役立ちます。
Goplsのウェブサーバーはlocalhostポートでリッスンします。セキュリティのため、そのすべてのエンドポイントには、認証トークンとして機能するランダムな文字列が含まれています。サーバーから認証されたURLが提供されたクライアントはソースコードにアクセスできますが、マシン上で実行されている任意のプロセスはアクセスできません。goplsプロセスを再起動すると、このシークレットが変更され、既存の以前のURLはすべて無効になります。既存のページには、接続が切断されたことを示すバナーが表示されます。
TODO: Webサーバーとデバッグサーバーを結合する。詳細については、https://go.dokyumento.jp/issue/68229を参照してください。
Goplsは、ウェブブラウザとクライアントエディタ間の双方向通信をサポートしています。すべてのウェブベースのレポートには、ソースコード内の宣言へのリンクが含まれています。これらのリンクのいずれかをクリックすると、goplsはエディタにshowDocumentリクエストを送信し、関連するソースファイルを適切な行で開きます。これは、ソースコードが変更されたが保存されていない場合でも機能します。(VS Codeユーザーへ: このイベントを処理する際にエディタのウィンドウを前面に表示させたい場合は、microsoft/vscode#208093に賛成票をお願いします。)
source.doc: パッケージドキュメントを参照する
任意のGoソースファイルで、コードアクションリクエストは「パッケージドキュメントを参照」するコマンドを返します。このコマンドは、現在のGoパッケージのドキュメントを表示するブラウザウィンドウを開きます。https://pkg.go.devと同様のデザインで表示されます。
これにより、公開されていない内部パッケージであっても、パッケージのドキュメントをプレビューできます。ページをリロードすると、変更を反映してドキュメントが更新されます。Goソースファイルを保存する必要はありません。
パッケージレベルのシンボルまたはメソッドへのリンクをクリックすると、通常pkg.go.devではGitHubやGoogle Code Searchなどのソースコードビューアに移動しますが、この機能ではエディターが関連するソースファイルと行に移動します。
クライアントサポート
- VS Code: 「Source Action... > Browse documentation for package P」メニューを使用します。
- Emacs + eglot: go-modeで
M-x go-browse-docを使用します。 - Vim + coc.nvim: ??
source.freesymbols: フリーシンボルを参照する
コードを研究する際、それを理解するためであろうと、異なる組織やファクタリングを評価するためであろうと、特定のコードのチャンクに対する「入力」が何であるかを知る必要があることはよくあります。これは、それを独自の関数に抽出し、どのようなパラメータを受け取るかを知りたい場合でも、長い関数の一部が先行する部分とどのように関連しているかを理解したい場合でも同様です。
コードのチャンクを選択し、「フリーシンボルを閲覧」コードアクションを呼び出すと、エディタは選択範囲のフリーシンボルに関するレポートを表示するブラウザを開きます。シンボルは、選択範囲内から参照されているが、その外で定義されている場合に「フリー」です。本質的に、これらは選択されたチャンクへの入力です。
レポートは、シンボルをインポートされたシンボル、ローカルシンボル、パッケージレベルシンボルに分類します。インポートされたシンボルはパッケージごとにグループ化され、上述のようにパッケージのドキュメントにリンクします。残りの各シンボルは、エディターがその宣言に移動するリンクとして表示されます。
TODO: ドットパスを説明する。
クライアントサポート
- VS Code: 「Source Action... > Browse free symbols」メニューを使用します。
- Emacs + eglot: go-modeで
M-x go-browse-freesymbolsを使用します。 - Vim + coc.nvim: ??
source.assembly: アセンブリを参照する
コードのパフォーマンスを最適化したり、予期せぬクラッシュを調査したりする際に、Go関数用にコンパイラが生成したアセンブリコードを検査すると役立つ場合があります。
関数 f 内にカーソルまたは選択範囲を置くと、gopls は「f のアセンブリを参照」コードアクションを提供します。これにより、その関数とその中にネストされた関数のアセンブリのウェブベースのリストが開きます。
ソースを編集し、ページをリロードするたびに、現在のパッケージが再コンパイルされ、リストが更新されます。変更されたファイルを保存する必要はありません。
コンパイラのターゲットアーキテクチャは、gopls がファイルを解析するときに使用するものと同じです。通常はマシンの GOARCH ですが、`foo_amd64.go` のようなビルドタグを持つファイルや `//go:build amd64` のコメントを含むファイルを表示する場合、タグがアーキテクチャを決定します。
各命令は、デバッグ情報に従って、その命令に対応するソース行にエディタを移動させるリンク付きで表示されます。
上記の例は、time.NewTimerのarm64アセンブリリストを示しています。示された命令が異なる関数syncTimer内のソースロケーションにリンクしていることに注目してください。これは、コンパイラがNewTimerからsyncTimerへの呼び出しをインライン化したためです。
ジェネリック関数、パッケージ初期化子(func init)、テストパッケージ内の関数に対するアセンブリの閲覧はまだサポートされていません。(貢献歓迎!)
クライアントサポート
- VS Code: 「Source Action... > Browse GOARCH assembly for f」メニューを使用します。
- Emacs + eglot: go-modeで
M-x go-browse-assemblyを使用します。 - Vim + coc.nvim: ??
source.splitPackage: パッケージをコンポーネントに分割する
ウェブベースの「パッケージ分割」ツールは、複雑なパッケージを2つ以上のコンポーネントに分割するのに役立ち、それらのコンポーネント間の依存関係が非循環であることを保証します。
ページ上の指示に従って、名前付きコンポーネントのセットを選択し、各宣言を最も適切なコンポーネントに割り当てて、あるシンボルから別のシンボルへの参照によって作成されたコンポーネント間の依存関係を視覚化します。
以下の図は、`fmt`パッケージを操作するツールを示しています。このパッケージは、(原則として)書式設定用(`Printf`とその仲間)、スキャン用(`Scanf`)、およびそれらの共通の依存関係用の3つのサブパッケージに分割できます。
(このパッケージでツールを試してみてください。これは教育的な演習になります。下の図は解決策を示しています。)
このツールは現在、コード変換(宣言を新しいパッケージに移動したり、必要に応じてシンボルの名前を変更してエクスポートしたりすること)は実行しませんが、将来のリリースで追加したいと考えています。
クライアントサポート
- VS Code: 「Source Action... > Split package P」メニューを使用します。
このドキュメントのソースファイルは、golang.org/x/tools/gopls/doc の下にあります。