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

[インデックス 18110] ファイルの概要

このコミットは、Go言語のVimプラグインにおけるgo/complete.vimファイル内の引用符の破損を修正するものです。具体的には、go env GOROOTコマンドの実行に失敗した際に表示されるエラーメッセージの文字列リテラルにおけるシングルクォートのエスケープ方法が修正されています。

コミット

commit 7413e48d5beeae3fa0b22fecf39cf1db5a1339f7
Author: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Date:   Tue Dec 24 08:40:13 2013 +1100

    misc/vim: Fix broken quote
    
    R=golang-codereviews, gobot, dsymonds
    CC=golang-codereviews
    https://golang.org/cl/44960043

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/7413e48d5beeae3fa0b22fecf39cf1db5a1339f7

元コミット内容

misc/vim: Fix broken quote

R=golang-codereviews, gobot, dsymonds
CC=golang-codereviews
https://golang.org/cl/44960043

変更の背景

この変更は、Go言語のVimプラグイン(misc/vimディレクトリ配下)の一部であるautoload/go/complete.vimファイルにおいて、エラーメッセージの表示に関するバグを修正するために行われました。具体的には、Vimスクリプト内でgo env GOROOTコマンドを実行する際に、何らかの理由でそのコマンドが失敗した場合に表示されるエラーメッセージの文字列リテラルに問題がありました。

Vimスクリプトでは、文字列リテラル内でシングルクォート(')を表現する際、特定のエスケープルールに従う必要があります。元のコードでは、このエスケープが正しく行われていなかったため、エラーメッセージが意図した通りに表示されず、ユーザーにとって分かりにくい、あるいは構文エラーを引き起こす可能性がありました。このコミットは、この「壊れた引用符」を修正し、エラーメッセージが正しく表示されるようにすることを目的としています。

前提知識の解説

Vimスクリプト

Vimスクリプトは、テキストエディタVimの内部スクリプト言語です。Vimの動作をカスタマイズしたり、新しい機能を追加したりするために使用されます。Vimスクリプトでは、変数、関数、条件分岐、ループなどの基本的なプログラミング構造がサポートされています。

文字列リテラルとエスケープ

Vimスクリプトにおいて、文字列リテラルは通常、シングルクォート(')またはダブルクォート(")で囲まれます。

  • シングルクォート文字列: シングルクォートで囲まれた文字列では、ほとんどの特殊文字がそのまま解釈されます。ただし、文字列リテラル自体を閉じるシングルクォートを文字列内に含めたい場合は、そのシングルクォートを二重に記述('')することでエスケープします。例えば、'It''s a test' は "It's a test" と解釈されます。
  • ダブルクォート文字列: ダブルクォートで囲まれた文字列では、バックスラッシュ(\)を用いたエスケープシーケンスが解釈されます(例: \nは改行、\"はダブルクォート)。

このコミットの文脈では、シングルクォート文字列内でシングルクォートをエスケープする方法が問題となっていました。

echomsgコマンド

echomsgはVimスクリプトのコマンドで、メッセージをVimのコマンドラインに表示し、同時にメッセージ履歴にも保存します。デバッグ情報やエラーメッセージを表示する際によく使用されます。

go env GOROOTコマンド

go envはGo言語の環境変数を表示するコマンドです。go env GOROOTは、Goのインストールディレクトリ(GOROOT)のパスを出力します。Goのツールチェインが正しく動作するためには、このGOROOTが正しく設定されている必要があります。Vimプラグインは、この情報を使用してGoのツールやライブラリのパスを特定します。

system()関数

Vimスクリプトのsystem()関数は、引数として与えられたシェルコマンドを実行し、その標準出力を文字列として返します。このコミットでは、system('go env GOROOT')としてGoコマンドを実行し、GOROOTのパスを取得しようとしています。

v:shell_error変数

v:shell_errorはVimの組み込み変数で、直前に実行されたシェルコマンドがエラーを返したかどうかを示すフラグです。シェルコマンドが成功した場合は0、失敗した場合は非0の値が設定されます。この変数をチェックすることで、go env GOROOTの実行が成功したかどうかを判断できます。

技術的詳細

このコミットの技術的な核心は、Vimスクリプトにおける文字列リテラルのエスケープの修正です。

元のコードでは、echomsg ' \'go env GOROOT\' failed'という記述がありました。 ここで、'go env GOROOT'という文字列をシングルクォートで囲まれたメッセージの中に含めようとしています。しかし、Vimスクリプトのシングルクォート文字列では、内部のシングルクォートをエスケープするためにバックスラッシュ(\)を使用するのではなく、シングルクォートを二重に記述('')する必要があります。

元のコードの\'は、Vimスクリプトのシングルクォート文字列内では、単なるバックスラッシュとそれに続くシングルクォートとして解釈されてしまい、意図した「シングルクォートのエスケープ」としては機能しませんでした。結果として、Vimスクリプトのパーサーは、'go env GOROOT'の最初のシングルクォートで文字列リテラルが閉じられたと誤解し、その後のgo env GOROOTの部分をVimスクリプトの構文エラーとして扱っていた可能性があります。

修正後のコードでは、echomsg '''go env GOROOT'' failed'となっています。 この変更により、'go env GOROOT'という部分が正しく文字列リテラルとして解釈されるようになります。具体的には、'''は「シングルクォートで囲まれた文字列リテラル内で、シングルクォートを表現する」というVimスクリプトのルールに従っています。これにより、go env GOROOTという文字列が正しくエラーメッセージの一部として表示されるようになります。

この修正は、Vimスクリプトの構文規則に厳密に従うことで、エラーメッセージの正確な表示を保証し、ユーザーエクスペリエンスを向上させるものです。

コアとなるコードの変更箇所

--- a/misc/vim/autoload/go/complete.vim
+++ b/misc/vim/autoload/go/complete.vim
@@ -58,7 +58,7 @@ function! go#complete#Package(ArgLead, CmdLine, CursorPos)\
   if executable(\'go\')
     let goroot = substitute(system(\'go env GOROOT\'), \'\\n\', \'\', \'g\')
     if v:shell_error
-      echomsg \'\\\'go env GOROOT\\\' failed\'
+      echomsg \'\'\'go env GOROOT\'\' failed\'
     endif
   else
     let goroot = $GOROOT

コアとなるコードの解説

変更された行は、misc/vim/autoload/go/complete.vimファイルの58行目です。

元のコード:

echomsg '\'go env GOROOT\' failed'

この行は、go env GOROOTコマンドの実行が失敗した場合に、Vimのメッセージ領域にエラーメッセージを表示しようとしていました。しかし、Vimスクリプトのシングルクォート文字列のエスケープルールに違反していました。\'という記述は、Vimスクリプトのシングルクォート文字列内では、バックスラッシュとそれに続くシングルクォートとして解釈され、文字列リテラルを閉じるシングルクォートとしては機能しませんでした。

修正後のコード:

echomsg '''go env GOROOT'' failed'

この行は、Vimスクリプトの正しいエスケープルールに従っています。シングルクォート文字列内でシングルクォートを表現するには、そのシングルクォートを二重に記述します('')。

  • 最初の'echomsgの引数である文字列リテラルの開始。
  • '''は、文字列内に表示したい'をエスケープしたもの。
  • go env GOROOTは表示したい文字列の一部。
  • ''は、文字列内に表示したい'をエスケープしたもの。
  • failed'は文字列の残りの部分。
  • 最後の'は文字列リテラルの終了。

この修正により、'go env GOROOT' failedというメッセージが正しくVimのメッセージ領域に表示されるようになり、ユーザーはgo env GOROOTコマンドの実行に問題があったことを明確に理解できるようになります。

関連リンク

参考にした情報源リンク

特になし。この解説は、提供されたコミット情報とVimスクリプトの一般的な知識に基づいて作成されました。