[インデックス 16683] ファイルの概要
このコミットは、Go言語のVimエディタ用コンパイラプラグインを追加するものです。これにより、Vimの:make
コマンドとクイックフィックスリストがgo build
コマンドと連携し、GoプロジェクトのビルドエラーをVim内で効率的に処理できるようになります。
コミット
commit aec6b49aaebd7adc9ec8d11f3ffacdf041b0da2d
Author: David Bürgin <676c7473@gmail.com>
Date: Mon Jul 1 16:20:50 2013 +1000
misc/vim: Add compiler plugin for Go
This change adds a basic compiler plugin for Go. The plugin
integrates "go build" with Vim's ":make" command and the
quickfix list.
Fixes #5751.
R=golang-dev, dsymonds, niklas.schnelle, 0xjnml
CC=golang-dev
https://golang.org/cl/10466043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/aec6b49aaebd7adc9ec8d11f3ffacdf041b0da2d
元コミット内容
この変更は、Go言語用の基本的なVimコンパイラプラグインを追加します。このプラグインは、go build
コマンドをVimの:make
コマンドおよびクイックフィックスリストと統合します。
Fixes #5751. (このIssue番号はGoの内部トラッカーのものであり、GitHubの公開Issueとは異なります。)
変更の背景
Vimは多くの開発者に愛用されている強力なテキストエディタです。プログラミングにおいて、コードのコンパイルやビルドは日常的な作業であり、その結果(特にエラーや警告)をエディタ内で直接確認し、修正箇所へ素早くジャンプできる機能は開発効率を大幅に向上させます。
Go言語の開発においても、go build
コマンドはプロジェクトをビルドするための主要なツールです。しかし、Vimの標準機能だけではgo build
の出力形式をVimのクイックフィックスリストに適切にマッピングすることができませんでした。これにより、開発者はビルドエラーが発生した場合、ターミナルでgo build
を実行し、エラーメッセージを手動で解析し、Vimで該当箇所を探すという手間が発生していました。
このコミットは、この問題を解決するために、Vimのコンパイラプラグイン機構を利用してgo build
の出力をVimが理解できる形式に変換し、クイックフィックスリストに統合することを目的としています。これにより、Vimユーザーは:make
コマンドを実行するだけでgo build
を実行し、エラーがあればクイックフィックスリストに表示され、簡単にエラー箇所へ移動できるようになります。
前提知識の解説
Vimの:make
コマンドとクイックフィックスリスト
Vimには、外部コマンドを実行し、その出力を解析してエラーや警告を一覧表示する強力な機能があります。
:make
コマンド: Vim内で外部のビルドコマンド(通常はmake
)を実行するためのコマンドです。Vimはmakeprg
オプションで指定されたコマンドを実行し、その標準出力をキャプチャします。- クイックフィックスリスト (Quickfix List):
:make
コマンドや:grep
コマンドなどで検出されたエラーや警告のリストを表示するVimのウィンドウです。このリストから項目を選択すると、対応するファイルと行にジャンプできます。 errorformat
オプション: Vimが外部コマンドの出力を解析し、ファイル名、行番号、列番号、エラーメッセージなどを抽出するための正規表現のリストです。このオプションを適切に設定することで、様々なコンパイラやリンカの出力形式に対応できます。
Go言語のビルドプロセスとgo build
コマンド
Go言語のプロジェクトは、go build
コマンドを使用してコンパイルおよびリンクされます。このコマンドは、指定されたパッケージとその依存関係をビルドし、実行可能ファイルを生成します。ビルド中にエラーが発生した場合、go build
は標準エラー出力にエラーメッセージを出力します。Goのエラーメッセージは通常、ファイル名:行番号:列番号: エラーメッセージ
のような形式で出力されます。
Vimのコンパイラプラグイン
Vimには、特定のプログラミング言語やビルドシステムに対応するための「コンパイラプラグイン」という仕組みがあります。これは、~/.vim/compiler/
ディレクトリ(またはVimのruntimepath内の対応するディレクトリ)に配置されるVimスクリプトファイルで、makeprg
やerrorformat
などのオプションをその言語やビルドシステムに合わせて設定します。これにより、ユーザーは:compiler <plugin_name>
コマンドを実行するだけで、その言語のビルド環境をVimに設定できます。
技術的詳細
このコミットで追加されたmisc/vim/compiler/go.vim
ファイルは、Go言語用のVimコンパイラプラグインとして機能します。
-
makeprg
の設定:CompilerSet makeprg=go\\ build
この行は、Vimのmakeprg
オプションをgo build
に設定します。これにより、Vim内で:make
コマンドを実行すると、内部的にgo build
コマンドが実行されるようになります。go\\ build
のようにバックスラッシュでスペースをエスケープしているのは、Vimのコマンドライン解析の都合上、go
とbuild
を一つのコマンドとして認識させるためです。 -
errorformat
の設定:CompilerSet errorformat=
\\%-G#\\ %.%#,\
\\%A%f:%l:%c:\\ %m,\
\\%A%f:%l:\\ %m,\
\\%C%*\\\\s%m,\
\\%-G%.%#
この部分が、go build
の出力するエラーメッセージをVimが解析できるようにするための最も重要な設定です。errorformat
はカンマ区切りの正規表現のリストで、Vimは上から順に各行をパターンマッチングします。%-G#\\ %.%#
: これは、Goのエラー出力によく見られる、ビルドの進行状況を示す行(例:# command-line-arguments
)を無視するためのパターンです。%-G
は、マッチした行をクイックフィックスリストに追加しないことを意味します。%A%f:%l:%c:\\ %m
: これは、ファイル名:行番号:列番号: エラーメッセージ
という形式のエラーメッセージにマッチします。%A
: エラーメッセージの開始を示すマーカー。%f
: ファイル名。%l
: 行番号。%c
: 列番号。%m
: エラーメッセージ本文。:
や
%A%f:%l:\\ %m
: これは、ファイル名:行番号: エラーメッセージ
という形式のエラーメッセージにマッチします。列番号がない場合に対応します。%C%*\\\\s%m
: これは、複数行にわたるエラーメッセージの追加行(継続行)にマッチします。%C
は継続行の開始を示し、%*\\\\s
は任意の空白文字をスキップします。%-G%.%#
: これは、上記以外のすべての行を無視するための汎用パターンです。
-
current_compiler
変数の設定:if exists("current_compiler")
finish
endif
let current_compiler = "go"
これは、Vimのコンパイラプラグインの標準的な慣習です。もし既にcurrent_compiler
変数が設定されている(つまり、別のコンパイラプラグインが読み込まれている)場合は、このスクリプトの実行を終了します。これにより、複数のコンパイラプラグインが競合するのを防ぎます。その後、現在のコンパイラがgo
であることを示します。 -
CompilerSet
コマンドの定義:if exists(":CompilerSet") != 2
command -nargs=* CompilerSet setlocal <args>
endif
CompilerSet
はVimの組み込みコマンドではありません。このコードは、CompilerSet
というカスタムコマンドを定義しています。このコマンドは、引数をそのままsetlocal
コマンドに渡します。setlocal
は、現在のバッファにのみ適用されるオプションを設定するために使用されます。これにより、makeprg
やerrorformat
の設定がグローバルではなく、Goファイルを開いているバッファにのみ適用されるようになります。 -
cpo
オプションの一時的な変更:let s:save_cpo = &cpo
set cpo-=C
...
let &cpo = s:save_cpo
unlet s:save_cpo
cpo
(compatible) オプションは、Vimの動作をVi互換にするかどうかを制御します。set cpo-=C
は、errorformat
の%C
(継続行)などの特殊なパターンが正しく機能するために必要な設定です。処理の前後でcpo
の値を保存・復元することで、他のVimスクリプトやユーザー設定に影響を与えないようにしています。
コアとなるコードの変更箇所
このコミットでは、以下の2つのファイルが変更されています。
-
misc/vim/compiler/go.vim
(新規追加) Go言語用のVimコンパイラプラグインの本体です。makeprg
とerrorformat
の設定が含まれています。 -
misc/vim/readme.txt
(更新) VimプラグインのREADMEファイルです。新しく追加されたGoコンパイラプラグインのインストール方法と使用方法に関する説明が追記されています。
diff --git a/misc/vim/compiler/go.vim b/misc/vim/compiler/go.vim
new file mode 100644
index 0000000000..2c8cce4973
--- /dev/null
+++ b/misc/vim/compiler/go.vim
@@ -0,0 +1,30 @@
+" Copyright 2013 The Go Authors. All rights reserved.
+" Use of this source code is governed by a BSD-style
+" license that can be found in the LICENSE file.
+"
+" compiler/go.vim: Vim compiler file for Go.
+
+if exists("current_compiler")
+ finish
+endif
+let current_compiler = "go"
+
+if exists(":CompilerSet") != 2
+ command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:save_cpo = &cpo
+set cpo-=C
+
+CompilerSet makeprg=go\ build
+CompilerSet errorformat=
+ \%-G#\ %.%#,\
+ \%A%f:%l:%c:\ %m,\
+ \%A%f:%l:\ %m,\
+ \%C%*\s%m,\
+ \%-G%.%#
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim:ts=4:sw=4:et
diff --git a/misc/vim/readme.txt b/misc/vim/readme.txt
index dca24ea1d0..a394cec5a9 100644
--- a/misc/vim/readme.txt
+++ b/misc/vim/readme.txt
@@ -14,6 +14,7 @@ To use all the Vim plugins, add these lines to your $HOME/.vimrc.\n If you want to select fewer plugins, use the instructions in the rest of\n this file.\n \n+\n Vim syntax highlighting\n -----------------------\n \n@@ -69,6 +70,21 @@ To install automatic indentation:\n filetype indent on\n \n \n+Vim compiler plugin\n+-------------------\n+\n+To install the compiler plugin:\n+\n+ 1. Same as 1 above.\n+ 2. Copy or link compiler/go.vim to the compiler directory underneath your vim\n+ runtime directory (normally $HOME/.vim/compiler).\n+ 3. Activate the compiler plugin with ":compiler go". To always enable the\n+ compiler plugin in Go source files add an autocommand to your .vimrc file\n+ (normally $HOME/.vimrc):\n+\n+ autocmd FileType go compiler go\n+\n+\n Godoc plugin\n ------------\n \n```
## コアとなるコードの解説
### `misc/vim/compiler/go.vim`
このファイルは、Go言語のビルドエラーをVimのクイックフィックスリストに統合するためのVimスクリプトです。
* **ヘッダー**: コピーライト情報とファイルの説明が含まれています。
* **`if exists("current_compiler") ... endif`**: 既に別のコンパイラが設定されている場合に、このスクリプトの読み込みをスキップするためのガード句です。これにより、Vimのコンパイラ設定の競合を防ぎます。
* **`let current_compiler = "go"`**: 現在のコンパイラを`go`として設定します。
* **`if exists(":CompilerSet") ... endif`**: `CompilerSet`コマンドが定義されていない場合に、それを定義します。このコマンドは、`setlocal`コマンドのラッパーとして機能し、現在のバッファにのみオプションを適用します。
* **`let s:save_cpo = &cpo` / `set cpo-=C` / `let &cpo = s:save_cpo`**: `cpo`オプションを一時的に変更し、`errorformat`の特殊なパターン(特に`%C`)が正しく機能するようにします。処理後に元の値に戻すことで、他の設定への影響を最小限に抑えます。
* **`CompilerSet makeprg=go\\ build`**: `:make`コマンドが`go build`を実行するように設定します。
* **`CompilerSet errorformat=...`**: `go build`の出力形式を解析するための正規表現パターンを設定します。これにより、Vimはエラーメッセージからファイル名、行番号、列番号、エラーメッセージを抽出し、クイックフィックスリストに表示できるようになります。
### `misc/vim/readme.txt`
このファイルは、Go言語のVimプラグイン群のREADMEです。今回のコミットでは、新しく追加されたGoコンパイラプラグインのインストールと使用方法に関するセクションが追加されました。
* **`Vim compiler plugin`セクションの追加**:
* コンパイラプラグインのインストール手順が説明されています。`compiler/go.vim`ファイルをVimのruntime directory(通常は`$HOME/.vim/compiler`)にコピーまたはリンクする必要があることが示されています。
* `:compiler go`コマンドを使用してプラグインをアクティブにする方法が説明されています。
* Goソースファイルを開いたときに常にコンパイラプラグインを有効にするために、`.vimrc`ファイルに`autocmd FileType go compiler go`という自動コマンドを追加する方法が提供されています。これにより、Goファイルを編集する際に手動で`:compiler go`を実行する必要がなくなります。
## 関連リンク
* Vim documentation: `quickfix`: [https://vimhelp.org/quickfix.txt.html](https://vimhelp.org/quickfix.txt.html)
* Vim documentation: `errorformat`: [https://vimhelp.org/options.txt.html#%27errorformat%27](https://vimhelp.org/options.txt.html#%27errorformat%27)
* Go Command Documentation (`go build`): [https://pkg.go.dev/cmd/go#hdr-Build_packages_and_dependencies](https://pkg.go.dev/cmd/go#hdr-Build_packages_and_dependencies)
* Go CL 10466043 (このコミットの元の変更リスト): [https://golang.org/cl/10466043](https://golang.org/cl/10466043)
## 参考にした情報源リンク
* Vimの公式ドキュメント (`:help quickfix`, `:help errorformat`, `:help compiler-plugins`)
* Go言語の公式ドキュメント (`go build`コマンド)
* コミットメッセージと変更されたファイルの内容
* GoのIssueトラッカー (ただし、`Fixes #5751`は内部Issueであり、公開されているGitHub Issueとは異なるため、直接的な情報源としては利用できませんでした。)
* 一般的なVimプラグイン開発の知識