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

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

このコミットは、Go言語のVimプラグインに関連する変更です。具体的には、go fmtgoimports(または類似のインポート管理ツール)、godocといったGoツールをVimから実行するためのコマンドに、ユーザーが選択的に機能を無効化できるフラグガードを追加しています。また、import.vimにおけるデフォルトのキーマッピングが削除され、ユーザーが明示的に設定する必要があるように変更されました。

コミット

commit b76ddefee593c50c658f4d7b876c354296b1d31b
Author: Josh Hoak <jhoak@google.com>
Date:   Thu Jun 13 15:07:09 2013 +1000

    misc/vim: Adding flag-guarding for Vim commands
    
    Default behavior is the same as before, but now a user may selectively disable some commands.
    
    Also: deleted the mappings for import.vim.
    
    Tested: by trying the commands for fmt, import and godoc in succession to make sure they still work. Also, ran test.sh in ftplugin/go.
    
    R=golang-dev, dsymonds
    CC=golang-dev
    https://golang.org/cl/10124043

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

https://github.com/golang/go/commit/b76ddefee593c50c658f4d7b876c354296b1d31b

元コミット内容

misc/vim: Adding flag-guarding for Vim commands

Default behavior is the same as before, but now a user may selectively disable some commands.

Also: deleted the mappings for import.vim.

Tested: by trying the commands for fmt, import and godoc in succession to make sure they still work. Also, ran test.sh in ftplugin/go.

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/10124043

変更の背景

この変更の主な背景は、Vimユーザーに対してGo関連のコマンドの柔軟性を提供することにあります。以前は、これらのコマンド(Fmt, Import, Drop, Godocなど)は常に有効であり、ユーザーが特定のコマンドを無効にしたい場合や、他のVimプラグインや自身のVim設定と競合する場合に、それを制御する手段がありませんでした。

このコミットは、以下の2つの主要な目的を達成するために行われました。

  1. コマンドの選択的無効化: ユーザーが特定のGo関連Vimコマンドを必要としない場合や、他のツールやワークフローを好む場合に、それらを簡単に無効にできるようにするため。これにより、Vim環境のカスタマイズ性が向上します。
  2. キーマッピングの明示化: import.vimにおけるデフォルトのキーマッピング(例: \f\F)を削除し、ユーザーが自身の.vimrcファイルなどで明示的にマッピングを設定するように促すため。これは、ユーザーの既存のキーマッピングとの衝突を避け、より予測可能で制御しやすいVim環境を提供することを目的としています。

これにより、Go開発者は自身のVim環境をより細かく制御できるようになり、不要な機能や競合するキーマッピングによる問題を回避できるようになります。

前提知識の解説

このコミットを理解するためには、以下の前提知識が必要です。

  1. Vim (Vi IMproved): テキストエディタの一種で、特にプログラマーに人気があります。強力なカスタマイズ性、キーボード中心の操作、豊富なプラグインエコシステムが特徴です。

    • ftplugin (filetype plugin): Vimの機能の一つで、特定のファイルタイプ(例: Go言語のファイル)を開いたときに自動的にロードされるスクリプトを指します。これにより、ファイルタイプに応じた特別なコマンドや設定を適用できます。
    • command!: Vimスクリプトで新しいユーザー定義コマンドを定義するための命令です。-bufferは、そのコマンドが現在のバッファ(開いているファイル)でのみ有効であることを示します。
    • function!: Vimスクリプトでユーザー定義関数を定義するための命令です。
    • let g:variable_name: グローバルスコープのVim変数を定義または設定します。g:プレフィックスはグローバル変数を意味します。ユーザーは.vimrcファイルでこれらの変数を設定することで、プラグインの動作をカスタマイズできます。
    • exists("g:variable_name"): 指定されたグローバル変数が存在するかどうかをチェックするVimスクリプト関数です。
    • nnoremap <buffer> <LocalLeader>f: ノーマルモードでのキーマッピングを定義します。<buffer>は現在のバッファでのみ有効なマッピングであることを示します。<LocalLeader>は、ユーザーが設定できる特別なプレフィックスキー(デフォルトは\)です。
    • au Filetype go ...: autocmd(自動コマンド)の一種で、ファイルタイプがgoになったときに指定されたコマンドを実行します。
  2. Go言語のツール群:

    • go fmt: Go言語の公式フォーマッタです。Goのソースコードを標準的なスタイルに自動的に整形します。
    • goimports: go fmtの機能に加え、Goのソースコードに必要なインポートパスを自動的に追加・削除するツールです。このコミットのimport.vimは、このgoimportsまたは類似のインポート管理ツールと連携していると考えられます。
    • godoc: Go言語のドキュメント表示ツールです。Goのソースコードから生成されたドキュメントをコマンドラインやWebブラウザで表示できます。

これらの知識があることで、コミットがVimのカスタマイズ性とGo開発ワークフローの改善にどのように貢献しているかを深く理解できます。

技術的詳細

このコミットの技術的な核心は、Vimスクリプトにおける条件付きコマンド定義と、ユーザー設定可能なグローバル変数の導入にあります。

各Vimスクリプトファイル(fmt.vim, import.vim, godoc.vim)には、以下の共通パターンが適用されています。

  1. グローバル変数の導入とデフォルト値の設定: 各ファイルは、対応するコマンドを制御するための新しいグローバル変数(例: g:go_fmt_commands, g:go_import_commands, g:go_godoc_commands)を導入しています。 これらの変数は、if !exists("g:variable_name")というVimスクリプトのイディオムを使って、まだ定義されていない場合にデフォルト値1(有効)が設定されます。これにより、既存のユーザーは.vimrcファイルを変更することなく、以前と同じ動作を維持できます。

    if !exists("g:go_fmt_commands")
        let g:go_fmt_commands = 1
    endif
    
  2. コマンド定義のフラグガード: Vimコマンド(command!)の定義が、新しく導入されたグローバル変数の値に基づいて条件付けされるようになりました。 例えば、fmt.vimでは、Fmtコマンドの定義がif g:go_fmt_commandsブロック内に移動されました。

    if g:go_fmt_commands
        command! -buffer Fmt call s:GoFormat()
    endif
    

    これにより、ユーザーが.vimrcファイルでlet g:go_fmt_commands = 0と設定した場合、Fmtコマンドは定義されなくなり、Vim内で利用できなくなります。

  3. import.vimにおけるキーマッピングの削除と推奨: import.vimでは、以前はデフォルトで提供されていたキーマッピング(例: map <buffer> <LocalLeader>f :Import fmt<CR>)が削除されました。 その代わりに、コメントとして、ユーザーが自身のVim設定ファイルでこれらのマッピングをどのように再定義できるかの例が提供されています。これは、ユーザーの既存のキーマッピングとの衝突を避けるための重要な変更です。ユーザーは、自身の好みに合わせて<LocalLeader>以外のキーや異なるマッピングスタイルを選択できるようになります。

    " If you would like to add shortcuts, you can do so by doing the following:
    "
    "   Import fmt
    "   au Filetype go nnoremap <buffer> <LocalLeader>f :Import fmt<CR>
    "
    "   Drop fmt
    "   au Filetype go nnoremap <buffer> <LocalLeader>F :Drop fmt<CR>
    "
    "   Import the word under your cursor
    "   au Filetype go nnoremap <buffer> <LocalLeader>k
    "       \ :exe 'Import ' . expand('<cword>')<CR>
    

このアプローチにより、プラグインのデフォルト動作を維持しつつ、ユーザーが自身の開発環境をより細かく制御できる柔軟性が提供されます。これは、Vimプラグイン開発における一般的なベストプラクティスであり、ユーザーエクスペリエンスを向上させるための重要な改善です。

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

このコミットで変更された主要なファイルと、その中のコアとなる変更箇所は以下の通りです。

misc/vim/ftplugin/go/fmt.vim

--- a/misc/vim/ftplugin/go/fmt.vim
+++ b/misc/vim/ftplugin/go/fmt.vim
@@ -12,11 +12,25 @@
 "       It tries to preserve cursor position and avoids
 "       replacing the buffer with stderr output.
 "
+" Options:
+"
+"   g:go_fmt_commands [default=1]
+"
+"       Flag to indicate whether to enable the commands listed above.
+"
 if exists("b:did_ftplugin_go_fmt")
     finish
 endif
 
-command! -buffer Fmt call s:GoFormat()
+
+if !exists("g:go_fmt_commands")
+    let g:go_fmt_commands = 1
+endif
+
+
+if g:go_fmt_commands
+    command! -buffer Fmt call s:GoFormat()
+endif
 
 function! s:GoFormat()
     let view = winsaveview()

misc/vim/ftplugin/go/import.vim

--- a/misc/vim/ftplugin/go/import.vim
+++ b/misc/vim/ftplugin/go/import.vim
@@ -24,23 +24,40 @@
 "       imported, an error will be displayed and the buffer will be
 "       untouched.\n"
-" In addition to these commands, there are also two shortcuts mapped:\n"
+" If you would like to add shortcuts, you can do so by doing the following:\n"
 "
-"   \f  -  Runs :Import fmt\n"
-"   \F  -  Runs :Drop fmt\n"
+"   Import fmt\n"
+"   au Filetype go nnoremap <buffer> <LocalLeader>f :Import fmt<CR>\n"
 "
-" The backslash is the default maplocalleader, so it is possible that\n"
+"   Drop fmt\n"
+"   au Filetype go nnoremap <buffer> <LocalLeader>F :Drop fmt<CR>\n"
+"
+"   Import the word under your cursor\n"
+"   au Filetype go nnoremap <buffer> <LocalLeader>k\n"
+"       \ :exe 'Import ' . expand('<cword>')<CR>\n"
+"
+" The backslash '\' is the default maplocalleader, so it is possible that\n"
 " your vim is set to use a different character (:help maplocalleader).\n"
 "
+" Options:\n"
+"
+"   g:go_import_commands [default=1]\n"
+"
+"       Flag to indicate whether to enable the commands listed above.\n"
+"
 if exists("b:did_ftplugin_go_import")
     finish
 endif
 
-command! -buffer -nargs=? -complete=customlist,go#complete#Package Drop call s:SwitchImport(0, '', <f-args>)\n-command! -buffer -nargs=1 -complete=customlist,go#complete#Package Import call s:SwitchImport(1, '', <f-args>)\n-command! -buffer -nargs=* -complete=customlist,go#complete#Package ImportAs call s:SwitchImport(1, <f-args>)\n-map <buffer> <LocalLeader>f :Import fmt<CR>\n-map <buffer> <LocalLeader>F :Drop fmt<CR>\n+if !exists("g:go_import_commands")
+    let g:go_import_commands = 1
+endif
+
+if g:go_import_commands
+    command! -buffer -nargs=? -complete=customlist,go#complete#Package Drop call s:SwitchImport(0, '', <f-args>)
+    command! -buffer -nargs=1 -complete=customlist,go#complete#Package Import call s:SwitchImport(1, '', <f-args>)
+    command! -buffer -nargs=* -complete=customlist,go#complete#Package ImportAs call s:SwitchImport(1, <f-args>)
+endif
 
 function! s:SwitchImport(enabled, localname, path)
     let view = winsaveview()

misc/vim/plugin/godoc.vim

--- a/misc/vim/plugin/godoc.vim
+++ b/misc/vim/plugin/godoc.vim
@@ -3,6 +3,20 @@
 " license that can be found in the LICENSE file.\n"
 "
 " godoc.vim: Vim command to see godoc.\n"
+"
+"
+" Commands:\n"
+"
+"   :Godoc\n"
+"
+"       Open the relevant Godoc for either the word[s] passed to the command or\n"
+"       the, by default, the word under the cursor.\n"
+"
+" Options:\n"
+"
+"   g:go_godoc_commands [default=1]\n"
+"
+"       Flag to indicate whether to enable the commands listed above.\n"
 if exists("g:loaded_godoc")
   finish
 endif
@@ -12,6 +26,16 @@ let g:loaded_godoc = 1
 let s:buf_nr = -1
 let s:last_word = ''
 
+if !exists('g:go_godoc_commands')
+  let g:go_godoc_commands = 1
+endif
+
+if g:go_godoc_commands
+  command! -nargs=* -range -complete=customlist,go#complete#Package Godoc :call s:Godoc(<q-args>)
+endif
+
+nnoremap <silent> <Plug>(godoc-keyword) :<C-u>call <SID>Godoc('')<CR>
+
 function! s:GodocView()
   if !bufexists(s:buf_nr)
     leftabove new
@@ -92,7 +116,4 @@ function! s:Godoc(...)\n"
   endif
 endfunction
 
-command! -nargs=* -range -complete=customlist,go#complete#Package Godoc :call s:Godoc(<q-args>)\n-nnoremap <silent> <Plug>(godoc-keyword) :<C-u>call <SID>Godoc('')<CR>\n"
-
 " vim:ts=4:sw=4:et\n"

コアとなるコードの解説

各ファイルにおけるコアとなるコードの変更は、Vimコマンドの定義をifブロックで囲むことで、ユーザーがグローバル変数を通じてその有効/無効を切り替えられるようにした点です。

  1. fmt.vim の変更:

    • g:go_fmt_commandsという新しいグローバル変数が導入され、デフォルト値が1(有効)に設定されます。
    • command! -buffer Fmt call s:GoFormat()というFmtコマンドの定義が、if g:go_fmt_commandsブロック内に移動されました。
    • これにより、ユーザーは.vimrclet g:go_fmt_commands = 0と記述することで、Fmtコマンドを無効にできます。
  2. import.vim の変更:

    • g:go_import_commandsという新しいグローバル変数が導入され、デフォルト値が1(有効)に設定されます。
    • Drop, Import, ImportAsといったインポート関連コマンドの定義が、if g:go_import_commandsブロック内に移動されました。
    • 最も注目すべきは、以前存在したデフォルトのキーマッピング(map <buffer> <LocalLeader>fなど)が完全に削除された点です。代わりに、ユーザーが自身のVim設定でこれらのマッピングをどのように追加できるかの例がコメントとして提供されています。これは、プラグインがユーザーのキーマッピングを上書きするのを避け、より明示的な設定を促すための変更です。
  3. godoc.vim の変更:

    • g:go_godoc_commandsという新しいグローバル変数が導入され、デフォルト値が1(有効)に設定されます。
    • command! -nargs=* -range -complete=customlist,go#complete#Package Godoc :call s:Godoc(<q-args>)というGodocコマンドの定義が、if g:go_godoc_commandsブロック内に移動されました。
    • nnoremap <silent> <Plug>(godoc-keyword) :<C-u>call <SID>Godoc('')<CR>というノーマルモードマッピングはifブロックの外に移動されました。これは、このマッピング自体は常に存在しますが、それが呼び出すs:Godoc関数がg:go_godoc_commandsによってガードされているため、コマンドが無効化されている場合は実質的に機能しないことを意味します。

これらの変更は、Vimプラグインの設計において、ユーザーのカスタマイズ性と制御を向上させるための標準的なアプローチを反映しています。

関連リンク

参考にした情報源リンク