[インデックス 17875] ファイルの概要
このコミットは、Go言語のVimプラグイン(misc/vim/ftplugin/go/fmt.vim
)に新しい設定フラグ g:gofmt_command
を追加するものです。これにより、Vimの :Fmt
コマンドが使用する gofmt
実行可能ファイルのパスをユーザーがカスタマイズできるようになります。
コミット
commit c4f5421bc773f55be51097b9e29d70b68edb7f99
Author: David Crawshaw <david.crawshaw@zentus.com>
Date: Tue Nov 12 09:28:07 2013 +1100
misc/vim: add a gofmt_command flag for :Fmt
R=dsymonds, dominik.honnef, n13m3y3r, rsc, kamil.kisiel
CC=golang-dev
https://golang.org/cl/22940044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/c4f5421bc773f55be51097b9e29d70b68edb7f99
元コミット内容
misc/vim: add a gofmt_command flag for :Fmt
変更の背景
Go言語の開発において、コードのフォーマットは gofmt
ツールによって標準化されています。Vimエディタを使用するGo開発者は、通常、Go言語のVimプラグインが提供する :Fmt
コマンドを使用して、現在開いているGoファイルのコードを gofmt
で自動的にフォーマットします。
このコミットが導入される以前は、Vimプラグインは gofmt
コマンドを直接呼び出していました。これは、gofmt
がシステムのPATH環境変数に存在することを前提としていました。しかし、開発環境によっては、gofmt
の実行可能ファイルが標準のPATHにない場合や、特定のバージョンの gofmt
を使用したい場合、あるいは gofmt
と互換性のある別のフォーマッタ(例: goimports
など)を使用したい場合があります。
このような状況に対応するため、ユーザーが :Fmt
コマンドによって呼び出されるフォーマッタを柔軟に指定できるようにする必要がありました。この変更は、Vimプラグインの使いやすさとカスタマイズ性を向上させることを目的としています。
前提知識の解説
Vimのftplugin (Filetype Plugin)
Vimには、特定のファイルタイプ(例: Go、Python、JavaScriptなど)に特化した設定やコマンドを自動的にロードする「ファイルタイププラグイン(ftplugin)」の仕組みがあります。misc/vim/ftplugin/go/fmt.vim
は、Go言語のファイルを開いたときにロードされるVimスクリプトであり、Goコードのフォーマットに関連する機能を提供します。
Vimのグローバル変数 (g:
) とバッファローカル変数 (b:
)
Vimスクリプトでは、変数を定義して設定を管理します。
g:
プレフィックスを持つ変数はグローバル変数であり、Vimセッション全体でアクセス可能です。ユーザーは~/.vimrc
などの設定ファイルでこれらの変数を設定することで、プラグインの挙動をカスタマイズできます。b:
プレフィックスを持つ変数はバッファローカル変数であり、特定のバッファ(開いているファイル)にのみ有効です。b:did_ftplugin_go_fmt
のような変数は、ftpluginが既にロードされたかどうかを追跡するためによく使用されます。
Vimのコマンド定義 (command!
)
Vimスクリプトでは、command!
キーワードを使用して新しいユーザー定義コマンドを作成できます。
-buffer
: このフラグは、定義されたコマンドが現在のバッファでのみ利用可能であることを示します。Fmt
: 定義されるコマンドの名前です。call s:GoFormat()
: コマンドが実行されたときに呼び出されるVimスクリプト関数です。s:
プレフィックスは、その関数がスクリプトローカルであることを示します。
Vimの外部コマンド実行 (%!
)
Vimでは、%!
コマンドを使用して、現在のバッファ全体を外部コマンドの標準入力に渡し、そのコマンドの標準出力をバッファの内容で置き換えることができます。これは、外部ツール(この場合は gofmt
)を使ってバッファの内容を処理し、その結果をVimに反映させるためによく使われる強力な機能です。
VimScriptの文字列連結と実行 (.
, execute
)
VimScriptでは、.
演算子を使って文字列を連結できます。また、execute
コマンドは、文字列として与えられたVimScriptコマンドを実行します。これにより、動的にコマンドを構築して実行することが可能になります。
技術的詳細
このコミットの主要な変更点は、gofmt
コマンドの呼び出しをハードコードされた文字列から、ユーザーが設定可能な変数 g:gofmt_command
を介したものに変更したことです。
-
新しいグローバル変数の導入:
g:gofmt_command
という新しいグローバル変数が導入されました。この変数は、gofmt
実行可能ファイルのパスまたはコマンド名を保持します。 デフォルト値は"gofmt"
に設定されており、これは以前の挙動(PATHからgofmt
を探す)と互換性があります。" g:gofmt_command [default="gofmt"] " " Flag naming the gofmt executable to use. " if !exists("g:gofmt_command") let g:gofmt_command = "gofmt" endif
このコードブロックは、
g:gofmt_command
がまだ定義されていない場合にのみ、そのデフォルト値を設定します。これにより、ユーザーが~/.vimrc
などでこの変数を事前に設定している場合は、その値が尊重されます。 -
s:GoFormat()
関数の変更:s:GoFormat()
関数内でgofmt
を呼び出す部分が変更されました。変更前:
silent %!gofmt
これは、現在のバッファの内容を
gofmt
コマンドの標準入力に渡し、その出力をバッファに書き戻すことを意味します。変更後:
silent execute "%!" . g:gofmt_command
この変更により、
gofmt
という固定のコマンド名ではなく、g:gofmt_command
変数の値が使用されるようになりました。execute
コマンドと文字列連結 (.
) を組み合わせることで、Vimはg:gofmt_command
の値(例:"gofmt"
や"/usr/local/bin/goimports"
など)を%!
コマンドの一部として動的に実行します。例えば、ユーザーが
let g:gofmt_command = "goimports"
と設定した場合、Vimはsilent %!goimports
を実行するのと同じ効果を得ます。
この変更により、VimのGoプラグインはより柔軟になり、ユーザーは自分の開発環境や好みに合わせてフォーマッタを簡単に切り替えることができるようになりました。
コアとなるコードの変更箇所
misc/vim/ftplugin/go/fmt.vim
ファイルの以下の部分が変更されました。
--- a/misc/vim/ftplugin/go/fmt.vim
+++ b/misc/vim/ftplugin/go/fmt.vim
@@ -18,15 +18,21 @@
"
" Flag to indicate whether to enable the commands listed above.
"
+" g:gofmt_command [default="gofmt"]
+"
+" Flag naming the gofmt executable to use.
+"
if exists(\"b:did_ftplugin_go_fmt\")
finish
endif
-
if !exists(\"g:go_fmt_commands\")
let g:go_fmt_commands = 1
endif
+if !exists(\"g:gofmt_command\")
+ let g:gofmt_command = \"gofmt\"
+endif
if g:go_fmt_commands
command! -buffer Fmt call s:GoFormat()
@@ -34,7 +40,7 @@ endif
function! s:GoFormat()
let view = winsaveview()
- silent %!gofmt
+ silent execute \"%!\" . g:gofmt_command
if v:shell_error
let errors = []
for line in getline(1, line('$'))
コアとなるコードの解説
-
コメントの追加:
g:gofmt_command
変数に関する新しいコメントが追加され、その目的とデフォルト値が説明されています。これは、プラグインのユーザーが新しい設定オプションを理解するのに役立ちます。 -
g:gofmt_command
のデフォルト値設定:if !exists("g:gofmt_command")
ブロックが追加され、g:gofmt_command
がまだ定義されていない場合に"gofmt"
をデフォルト値として設定します。これにより、既存のユーザーは設定を変更することなく、以前と同じ挙動を維持できます。 -
s:GoFormat()
関数内のgofmt
呼び出しの動的化:silent %!gofmt
の行がsilent execute "%!" . g:gofmt_command
に変更されました。"%!"
: これはVimの外部コマンド実行プレフィックスです。.
(ドット): VimScriptにおける文字列連結演算子です。g:gofmt_command
: ユーザーが設定したgofmt
実行可能ファイルのパスまたはコマンド名を含む変数です。execute
: 文字列として構築されたコマンドを実行します。
この変更により、
gofmt
の呼び出しが静的なものから動的なものに変わり、ユーザーがg:gofmt_command
を設定することで、任意のフォーマッタコマンドを実行できるようになりました。
関連リンク
- Go言語の公式ウェブサイト: https://golang.org/
gofmt
ツールに関するドキュメント:gofmt
はGo言語の標準ツールであり、Goのインストールに含まれています。詳細なドキュメントは通常、Goの公式ドキュメントやgo help fmt
コマンドで確認できます。- Vimのドキュメント:
ftplugin
::help ftplugin
g:
,b:
::help g:
/:help b:
command!
::help :command
%!
::help :!
execute
::help :execute
参考にした情報源リンク
- コミットハッシュ: c4f5421bc773f55be51097b9e29d70b68edb7f99
- GitHub上のコミットページ: https://github.com/golang/go/commit/c4f5421bc773f55be51097b9e29d70b68edb7f99
- Go CL (Code Review) ページ: https://golang.org/cl/22940044 (これはコミットメッセージに記載されているリンクです)
- Vimのヘルプドキュメント (Vimエディタ内で
:help <topic>
でアクセス可能)