Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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スクリプトファイルで、makeprgerrorformatなどのオプションをその言語やビルドシステムに合わせて設定します。これにより、ユーザーは:compiler <plugin_name>コマンドを実行するだけで、その言語のビルド環境をVimに設定できます。

技術的詳細

このコミットで追加されたmisc/vim/compiler/go.vimファイルは、Go言語用のVimコンパイラプラグインとして機能します。

  1. makeprgの設定: CompilerSet makeprg=go\\ build この行は、Vimのmakeprgオプションをgo buildに設定します。これにより、Vim内で:makeコマンドを実行すると、内部的にgo buildコマンドが実行されるようになります。go\\ buildのようにバックスラッシュでスペースをエスケープしているのは、Vimのコマンドライン解析の都合上、gobuildを一つのコマンドとして認識させるためです。

  2. 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%.%#: これは、上記以外のすべての行を無視するための汎用パターンです。
  3. current_compiler変数の設定: if exists("current_compiler") finish endif let current_compiler = "go" これは、Vimのコンパイラプラグインの標準的な慣習です。もし既にcurrent_compiler変数が設定されている(つまり、別のコンパイラプラグインが読み込まれている)場合は、このスクリプトの実行を終了します。これにより、複数のコンパイラプラグインが競合するのを防ぎます。その後、現在のコンパイラがgoであることを示します。

  4. CompilerSetコマンドの定義: if exists(":CompilerSet") != 2 command -nargs=* CompilerSet setlocal <args> endif CompilerSetはVimの組み込みコマンドではありません。このコードは、CompilerSetというカスタムコマンドを定義しています。このコマンドは、引数をそのままsetlocalコマンドに渡します。setlocalは、現在のバッファにのみ適用されるオプションを設定するために使用されます。これにより、makeprgerrorformatの設定がグローバルではなく、Goファイルを開いているバッファにのみ適用されるようになります。

  5. 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つのファイルが変更されています。

  1. misc/vim/compiler/go.vim (新規追加) Go言語用のVimコンパイラプラグインの本体です。makeprgerrorformatの設定が含まれています。

  2. 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プラグイン開発の知識