[インデックス 17897] ファイルの概要
このコミットは、Go言語のVimプラグインにおけるgofmt
のエラー表示方法の改善に関するものです。具体的には、gofmt
の出力するエラーをVimのロケーションリスト(location list)ではなく、クイックフィックスリスト(quickfix list)に表示するように変更しています。これにより、gofmt
が返すエラーがVimの標準的なエラー表示メカニズムにより適切に統合され、ユーザーエクスペリエンスが向上します。
コミット
commit ee261b75e1a31ab7056a897e1b65fba3568cf9ba
Author: David Symonds <dsymonds@golang.org>
Date: Wed Nov 27 19:32:15 2013 +1100
misc/vim: send Fmt errors to the quickfix list instead of the location list.
Output from gofmt is a list of errors, so they should appear in the error list.
R=adg
CC=golang-dev
https://golang.org/cl/33760043
---
misc/vim/ftplugin/go/fmt.vim | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n
diff --git a/misc/vim/ftplugin/go/fmt.vim b/misc/vim/ftplugin/go/fmt.vim
index 5f7976f5f6..359545bd40 100644
--- a/misc/vim/ftplugin/go/fmt.vim
+++ b/misc/vim/ftplugin/go/fmt.vim
@@ -57,7 +57,7 @@ function! s:GoFormat()\
endif
undo
if !empty(errors)\
- call setloclist(0, errors, \'r\')
+ call setqflist(errors, \'r\')
endif
echohl Error | echomsg \"Gofmt returned error\" | echohl None
endif
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ee261b75e1a31ab7056a897e1b65fba3568cf9ba
元コミット内容
misc/vim: send Fmt errors to the quickfix list instead of the location list.
Output from gofmt is a list of errors, so they should appear in the error list.
R=adg
CC=golang-dev
https://golang.org/cl/33760043
変更の背景
この変更の背景には、Vimにおけるエラー表示の慣習とgofmt
の出力形式の整合性があります。
gofmt
はGo言語のコードフォーマッタであり、コードの書式がGoの標準スタイルに準拠しているかをチェックし、必要に応じて自動修正を行います。しかし、書式に問題がある場合や、構文エラーなどによりフォーマットできない場合には、エラーメッセージを生成します。これらのエラーメッセージは、通常、ファイル名、行番号、エラー内容といった形式でリストとして出力されます。
Vimには、このようなエラーや警告のリストを扱うための二つの主要な機能があります。
- ロケーションリスト (Location List): これはVimの各ウィンドウに固有のリストであり、特定のファイルやバッファに関連する情報を表示するのに適しています。例えば、現在のファイル内での検索結果や、特定のLSP (Language Server Protocol) クライアントからの診断情報などがこれに該当します。
- クイックフィックスリスト (Quickfix List): これはVimセッション全体で共有されるグローバルなリストであり、コンパイルエラーやプロジェクト全体にわたる検索結果など、より広範なエラーや警告を扱うのに適しています。
元の実装では、gofmt
のエラーがロケーションリストに送られていました。しかし、gofmt
の出力は「エラーのリスト」であり、これはVimのクイックフィックスリストが本来扱うべき種類の情報です。クイックフィックスリストは、コンパイラのエラー出力のように、複数のファイルにまたがる可能性のあるエラー群を効率的にナビゲートするために設計されています。
この不整合を解消し、gofmt
のエラーをVimのより適切なメカニズムで表示することで、ユーザーがエラーをより直感的に、かつ効率的に処理できるようになることが、この変更の主な動機です。
前提知識の解説
このコミットを理解するためには、以下のVimの機能とGo言語のツールに関する知識が必要です。
Vimのリスト機能: クイックフィックスリストとロケーションリスト
Vimには、ファイル内の特定の場所(エラー、警告、検索結果など)のリストを管理するための強力な機能が二つあります。
-
クイックフィックスリスト (Quickfix List):
- スコープ: Vimセッション全体でグローバルに一つだけ存在します。
- 用途: コンパイルエラー、リンターの警告、
grep
コマンドによるプロジェクト全体の検索結果など、複数のファイルにまたがる可能性のある、またはプロジェクト全体に影響するエラーや警告のリストを管理するのに適しています。 - 操作:
:copen
でクイックフィックスウィンドウを開き、:cnext
、:cprev
でリスト内を移動します。setqflist()
関数を使ってプログラム的にリストの内容を設定できます。 - 利点: プロジェクト全体のエラーを一元的に管理し、迅速に修正作業を進めることができます。
-
ロケーションリスト (Location List):
- スコープ: 各Vimウィンドウに固有のリストです。つまり、複数のウィンドウを開いている場合、それぞれのウィンドウが独立したロケーションリストを持つことができます。
- 用途: 現在のバッファ(ファイル)内での検索結果、特定のLSPクライアントからの診断情報、特定のファイルに限定されたリンターの警告など、ウィンドウやバッファに特化した情報のリストを管理するのに適しています。
- 操作:
:lopen
でロケーションリストウィンドウを開き、:lnext
、:lprev
でリスト内を移動します。setloclist()
関数を使ってプログラム的にリストの内容を設定できます。 - 利点: 異なるウィンドウで異なる作業を行っている際に、それぞれの作業に関連するリストを独立して管理できるため、コンテキストの混同を防ぎます。
gofmt
gofmt
は、Go言語のソースコードをGoの公式スタイルガイドに沿って自動的にフォーマットするツールです。Goのツールチェインに標準で含まれており、Goコミュニティではコードの整形に広く利用されています。
- 機能:
- Goのコードを標準的なスタイルに整形します。
- 構文エラーがある場合など、フォーマットできない場合にはエラーメッセージを出力します。
- 重要性:
gofmt
によって、Goのコードベース全体で一貫したコードスタイルが保たれ、可読性が向上し、コードレビューの負担が軽減されます。
Vimscript
VimscriptはVimエディタの内部スクリプト言語です。Vimの動作をカスタマイズしたり、新しい機能を追加したりするために使用されます。このコミットで変更されているfmt.vim
ファイルはVimscriptで書かれており、VimのGo言語用ファイルタイププラグインの一部です。
function! s:GoFormat()
: Vimscriptで定義された関数で、s:
はスクリプトローカルな関数であることを示します。この関数はGoファイルのフォーマット処理を担当しています。call setloclist(0, errors, 'r')
:setloclist()
関数を呼び出し、errors
変数の内容をロケーションリストに設定します。0
は現在のウィンドウを指し、'r'
はリストを置き換える(replace)ことを意味します。call setqflist(errors, 'r')
:setqflist()
関数を呼び出し、errors
変数の内容をクイックフィックスリストに設定します。'r'
はリストを置き換えることを意味します。
技術的詳細
このコミットの技術的な核心は、VimのVimscript関数であるsetloclist()
からsetqflist()
への変更です。
misc/vim/ftplugin/go/fmt.vim
ファイルは、VimでGo言語のファイルを開いた際に、gofmt
を実行してコードを整形するためのロジックを含んでいます。このスクリプトは、gofmt
の実行結果を処理し、エラーが発生した場合にはそのエラー情報をVimのリスト機能に渡す役割を担っています。
変更前のコードでは、gofmt
がエラーを返した場合、そのエラーリストはsetloclist(0, errors, 'r')
というVimscriptの呼び出しによって、現在のウィンドウのロケーションリストに設定されていました。
しかし、gofmt
のエラーは、単一のファイル内の特定の箇所に限定されるというよりは、コード全体のフォーマットに関する問題や、構文エラーなど、プロジェクト全体に影響を及ぼす可能性のある「エラーのリスト」として扱われるべきです。Vimの設計思想において、このような「エラーのリスト」はクイックフィックスリストに表示されるのが適切です。クイックフィックスリストは、コンパイラのエラー出力のように、複数のファイルにまたがるエラーを効率的にナビゲートし、修正するための標準的なインターフェースを提供します。
このコミットでは、この認識に基づき、setloclist()
の呼び出しをsetqflist()
に置き換えています。
- call setloclist(0, errors, 'r')
+ call setqflist(errors, 'r')
この変更により、gofmt
がエラーを検出した場合、そのエラーメッセージはVimのグローバルなクイックフィックスリストに表示されるようになります。これにより、ユーザーは:copen
コマンドでクイックフィックスウィンドウを開き、:cnext
や:cprev
といったコマンドを使って、gofmt
によって報告されたすべてのエラーを効率的に巡回し、修正することができます。これは、特に大規模なGoプロジェクトで作業している場合や、複数のファイルにわたるフォーマットの問題を一度に解決する必要がある場合に、開発者のワークフローを大幅に改善します。
また、この変更は、Vimのリスト機能の適切な利用を促進するという点でも重要です。ロケーションリストはウィンドウ固有の情報を扱うのに適しているのに対し、クイックフィックスリストはセッション全体のエラー情報を扱うのに適しています。gofmt
のエラーをクイックフィックスリストに送ることで、Vimの機能がその意図された目的に沿ってより効果的に活用されるようになります。
コアとなるコードの変更箇所
変更はmisc/vim/ftplugin/go/fmt.vim
ファイル内のs:GoFormat()
関数にあります。
具体的には、以下の行が変更されました。
--- a/misc/vim/ftplugin/go/fmt.vim
+++ b/misc/vim/ftplugin/go/fmt.vim
@@ -57,7 +57,7 @@ function! s:GoFormat()\
endif
undo
if !empty(errors)\
- call setloclist(0, errors, \'r\')
+ call setqflist(errors, \'r\')
endif
echohl Error | echomsg \"Gofmt returned error\" | echohl None
endif
コアとなるコードの解説
変更された行は、s:GoFormat()
関数内でgofmt
の実行後にエラー(errors
変数に格納されている)が存在する場合の処理を定義しています。
-
変更前:
call setloclist(0, errors, 'r')
この行は、
gofmt
が返したエラーのリストを、現在のVimウィンドウのロケーションリストに設定していました。0
は現在のウィンドウを指し、'r'
は既存のリストを新しいリストで「置き換える(replace)」ことを意味します。 -
変更後:
call setqflist(errors, 'r')
この行は、
gofmt
が返したエラーのリストを、Vimセッション全体のクイックフィックスリストに設定するように変更されました。setqflist()
はロケーションリストとは異なり、ウィンドウ指定の引数を必要としません。これは、クイックフィックスリストが常にグローバルなリストであるためです。'r'
の引数は同様に、既存のリストを置き換えることを意味します。
この変更により、gofmt
のエラーはVimのクイックフィックスウィンドウ(:copen
で開く)に表示されるようになり、ユーザーは:cnext
や:cprev
などのクイックフィックスコマンドを使ってエラー間を移動できるようになります。これは、gofmt
が生成するエラーが、コンパイルエラーやリンターの警告と同様に、プロジェクト全体にわたる問題として扱われるべきであるという設計思想に合致しています。
関連リンク
- Vim documentation: quickfix: https://vimhelp.org/quickfix.txt.html
- Vim documentation: location-list: https://vimhelp.org/quickfix.txt.html#location-list
- Go:
gofmt
command: https://pkg.go.dev/cmd/gofmt - Go code review comments: https://go.dev/doc/effective_go#gofmt
参考にした情報源リンク
- Vim quickfix list vs location list: https://www.freshman.tech/vim-quickfix-location-list/
- Vim
setqflist()
andsetloclist()
: https://stackoverflow.com/questions/1009099/vim-setqflist-and-setloclist - Vim
setqflist()
documentation: https://vimhelp.org/eval.txt.html#setqflist() - Vim
setloclist()
documentation: https://vimhelp.org/eval.txt.html#setloclist()