map.txt For Vim バージョン 9.1. Last change: 2024 Oct 08
VIMリファレンスマニュアル by Bram Moolenaar
キーマップ、短縮入力、ユーザー定義コマンドについて。
ユーザーマニュアルの05.4、24.7、40.1でこの機能について紹介しています。
1. マップ key-mapping
1.1 マップコマンド :map-commands
1.2 特別な引数 :map-arguments
1.3 マップとモード :map-modes
1.4 マップの一覧表示 map-listing
1.5 特殊キーのマップ :map-special-keys
1.6 特殊文字 :map-special-chars
1.7 マップに使うキー map-which-keys
1.8 例 map-examples
1.9 マップを使う map-typing
1.10 Altキーを使ったマップ :map-alt-keys
1.11 Metaキーを使ったマップ :map-meta-keys
1.12 superキーまたはcommandキーのマップ :map-super-keys
1.13 modifyOtherKeys モードのマップ modifyOtherKeys
1.14 Kitty キーボードプロトコルを使ったマップ kitty-keyboard-protocol
1.15 オペレータの作成 :map-operator
2. 短縮入力 abbreviations
3. ローカルマップとローカル関数 script-local
4. ユーザー定義コマンド user-commands
==============================================================================
1. マップ (Key mapping) key-mapping mapping macro
マップは入力キーの動作を変更するために使われます。一般的にはファンクションキー
にコマンドを割り当てるのに使われます。例:
このマップはカーソルの位置に現在の日時を挿入します。(<F2>などは<>表記法を参照)
1.1 マップコマンド :map-commands
マップを新しく作成、削除、一覧表示するコマンドがあります。マップコマンドの種類
とモードの関係については map-overviewを参照してください。
{lhs} left-hand-side (左辺値) の略 {lhs}
{rhs} right-hand-side (右辺値) の略 {rhs}
:map {lhs} {rhs} mapmode-nvo :map
:nm[ap] {lhs} {rhs} mapmode-n :nm :nmap
:vm[ap] {lhs} {rhs} mapmode-v :vm :vmap
:xm[ap] {lhs} {rhs} mapmode-x :xm :xmap
:smap {lhs} {rhs} mapmode-s :smap
:om[ap] {lhs} {rhs} mapmode-o :om :omap
:map! {lhs} {rhs} mapmode-ic :map!
:im[ap] {lhs} {rhs} mapmode-i :im :imap
:lm[ap] {lhs} {rhs} mapmode-l :lm :lma :lmap
:cm[ap] {lhs} {rhs} mapmode-c :cm :cmap
:tma[p] {lhs} {rhs} mapmode-t :tma :tmap
キー入力 {lhs} を {rhs} に割り当てます。作成したマップ
は、マップコマンドに対応したモードで使用できます。マッ
プが使用されたときに {rhs} が調べられ、再マップされま
す。マップを入れ子にしたり再帰的にすることができます。
Note: 空白は有効なノーマルモードのコマンドであるため、
末尾の空白は {rhs} に含まれます。
map-trailing-white を参照。
:nore :norem
:no[remap] {lhs} {rhs} mapmode-nvo :no :noremap :nor
:nn[oremap] {lhs} {rhs} mapmode-n :nn :nnoremap
:vn[oremap] {lhs} {rhs} mapmode-v :vn :vnoremap
:xn[oremap] {lhs} {rhs} mapmode-x :xn :xnoremap
:snor[emap] {lhs} {rhs} mapmode-s :snor :snore :snoremap
:ono[remap] {lhs} {rhs} mapmode-o :ono :onoremap
:no[remap]! {lhs} {rhs} mapmode-ic :no! :noremap!
:ino[remap] {lhs} {rhs} mapmode-i :ino :inor :inoremap
:ln[oremap] {lhs} {rhs} mapmode-l :ln :lnoremap
:cno[remap] {lhs} {rhs} mapmode-c :cno :cnor :cnoremap
:tno[remap] {lhs} {rhs} mapmode-t :tno :tnoremap
キー入力 {lhs} を {rhs} に割り当てます。作成したマップ
は、マップコマンドに対応したモードで使用できます。
{rhs} は再マップされないので、マップが入れ子になったり
再帰的になることはありません。コマンドを再定義するとき
によく使われます。
Note: {rhs} 内のキーも、i_CTRL-] と c_CTRL-] を除
き、短縮入力をトリガーしません。
Note: {rhs} に <Plug> が表れる場合は再マップが許可され
ていなくてもその部分には常に適用{訳注:再マップ}されま
す。
:unm[ap] {lhs} mapmode-nvo :unm :unmap
:nun[map] {lhs} mapmode-n :nun :nunmap
:vu[nmap] {lhs} mapmode-v :vu :vunmap
:xu[nmap] {lhs} mapmode-x :xu :xunmap
:sunm[ap] {lhs} mapmode-s :sunm :sunmap
:ou[nmap] {lhs} mapmode-o :ou :ounmap
:unm[ap]! {lhs} mapmode-ic :unm! :unmap!
:iu[nmap] {lhs} mapmode-i :iu :iunmap
:lu[nmap] {lhs} mapmode-l :lu :lunmap
:cu[nmap] {lhs} mapmode-c :cu :cun :cunmap
:tunma[p] {lhs} mapmode-t :tunma :tunmap
マップコマンドに対応したモードの {lhs} というマップを
削除します。他のモードのマップは残ります。
{lhs} がマッピングの {rhs} にマッチするときも機能しま
す。これは略語が適用された場合に使用します。
Note: 末尾の空白は {lhs} に含まれます。
map-trailing-white を参照。
:mapc[lear] mapmode-nvo :mapc :mapclear
:nmapc[lear] mapmode-n :nmapc :nmapclear
:vmapc[lear] mapmode-v :vmapc :vmapclear
:xmapc[lear] mapmode-x :xmapc :xmapclear
:smapc[lear] mapmode-s :smapc :smapclear
:omapc[lear] mapmode-o :omapc :omapclear
:mapc[lear]! mapmode-ic :mapc! :mapclear!
:imapc[lear] mapmode-i :imapc :imapclear
:lmapc[lear] mapmode-l :lmapc :lmapclear
:cmapc[lear] mapmode-c :cmapc :cmapclear
:tmapc[lear] mapmode-t :tmapc :tmapclear
マップコマンドに対応したモードのすべてのマップを削除し
ます。
バッファローカルなマップを削除するには <buffer> 引数を
付けてください :map-<buffer>。
警告: Mac の標準マップ mac-standard-mappings と
MS-DOS の標準マップ dos-standard-mappings も削除され
ます。
:map mapmode-nvo
:nm[ap] mapmode-n
:vm[ap] mapmode-v
:xm[ap] mapmode-x
:sm[ap] mapmode-s
:om[ap] mapmode-o
:map! mapmode-ic
:im[ap] mapmode-i
:lm[ap] mapmode-l
:cm[ap] mapmode-c
:tma[p] mapmode-t
マップコマンドに対応したモードのすべてのマップを一覧表
示します。Note: ":map" と ":map!" は複数のモードを表示
できるのでよく使われます。
:map {lhs} mapmode-nvo :map_l
:nm[ap] {lhs} mapmode-n :nmap_l
:vm[ap] {lhs} mapmode-v :vmap_l
:xm[ap] {lhs} mapmode-x :xmap_l
:sm[ap] {lhs} mapmode-s :smap_l
:om[ap] {lhs} mapmode-o :omap_l
:map! {lhs} mapmode-ic :map_l!
:im[ap] {lhs} mapmode-i :imap_l
:lm[ap] {lhs} mapmode-l :lmap_l
:cm[ap] {lhs} mapmode-c :cmap_l
:tma[p] {lhs} mapmode-t :tmap_l
マップコマンドに対応したモードの {lhs} で始まるマップ
を一覧表示します。
マップコマンドを使うと、単キーまたは複数キーの入力を別の文字列にマップできま
す。ファンクションキーにコマンド列を割り当てたり、あるキーを別のキーに変換した
りできます。マップを保存、復元する方法については :mkexrc を参照してくださ
い。
map-ambiguous
二つのマップがあって、両方とも同じ文字で始まっている場合、どちらを使用するかが
あいまいになってしまいます。例:
の文字が必要になります。そのため、"aa" が入力された時点ではまだマップは適用さ
れず、次の入力まで待機状態になります。例えば空白文字を入力すれば "foo" と空白
文字が挿入されます。"a" を入力すれば "bar" が挿入されます。
末尾空白
map-trailing-white
このunmapコマンドは動作しません:
なぜなら unmap "@@ " を試行するとき、コマンド区切りの "|" の前の空白を含んでい
るためです。他の末尾空白の例として:
unmap @@ の末尾が空白文字のためエラーになりますが、これは見えないので特定す
るのが非常に困難です。
一般的な解決策はマップしたキーの後の右にコマンド区切りの "|" を置くことです。
その後に空白とコメントを続けます:
1.2 特別な引数 :map-arguments
引数に "<buffer>"、"<nowait>"、"<silent>"、"<special>"、"<script>"、"<expr>"、
"<unique>" を指定できます。マップコマンドの直後 (他の引数の前) に置いてくださ
い。
:map-local :map-<buffer> :map-buffer
E224 E225
カレントバッファだけで使用できるマップを作成するには、マップコマンドの引数に
"<buffer>" を指定します。例:
ルなマップが存在する場合に短いローカルなマップが影響を受けないようにするには下
記の <nowait> を参照して下さい。
"<buffer>" はマップを削除するときにも指定できます:
す。アンロード(:bunload)では消去されません。ローカルオプションと同じです。
また、map-precedence を参照して下さい。
:map-<nowait> :map-nowait
"," にバッファローカルなマップを定義する場合に "," から始まるグローバルなマッ
プがあるかもしれません。その場合はVimが "," のマップか、あるいはより長いマップ
を使用するかどうか知るために別の文字を入力する必要があります。これを避けるには
引数に <nowait> を追加します。そしてそのマップは一致する場合に使用され、Vimは
それ以上入力される文字を待ちません。しかし、既に文字が入力されていた場合はそれ
が使われます。
Note: これが動作するのは <nowait> なマッピングが完全にマッチし、なんらかの部分
マッチの前に見付かるときです。これが動作するのは:
- バッファローカルなマッピングで唯一のマッチがあるとき。なぜなら常にグローバル
なマッピングより先に見付かるからです。
- これとは別のバッファローカルなマッピングが部分マッチするが、より早く定義され
ているとき (最後に定義したマッピングが最初に見付かる)。
:map-<silent> :map-silent
実行するコマンドがコマンドラインに表示されないようにするには、マップコマンドの
引数に "<silent>" を指定します。例:
実行されたコマンドが出力するメッセージは表示されてしまいます。それを静かにさせ
るには ":silent" を使います:
プがコマンドライン補完の別のエントリを選択するとき、それは表示されません。
それでもまだ、例えば inputdialog() のプロンプトなどは表示されます。
"<silent>" は短縮入力にも使えますが、コマンドラインで使うと正しく表示されなく
なります。
:map-<special> :map-special
'cpoptions' に "<" フラグが入っている場合でも、<> 表記を使って特殊キーを記述で
きます。'cpoptions' を設定することで副作用を発生させたくない場合に使ってくださ
い。例:
:map-<script> :map-script
マップや短縮入力を定義するときに "<script>" 引数を指定すると、{rhs} の中の
"<SID>" で始まるスクリプトローカルなマップだけが再マップされます。別の場所で
マップが定義されていても (例えば mswin.vim で CTRL-V にマップが定義されていて
も)、その影響を避けることができます。その場合でも同じスクリプトで定義された
マップは使うことができます。
Note: ":map <script>" と ":noremap <script>" の動作は同じです。コマンド名より
"<script>" の効果が優先されます。再マップが制限されることが明確になるため
":noremap <script>" を使う方がいいでしょう。
:map-<unique> :map-unique E226 E227
マップや短縮入力を定義するときに "<unique>" 引数を指定すると、同じ名前のものが
すでに定義されていた場合に、コマンドは失敗します。例:
失敗する例:
maparg() を参照してください。
:map-<expr> :map-expression
マップや短縮入力を定義するときに "<expr>" 引数を指定すると、引数が式 (スクリプ
ト) として扱われます。マップが実行されたときに、式が評価され、その値が {rhs}
として使われます。例:
て、ある条件に一致するなら omni 補完を開始する、というようなことができます。
グローバルな名前空間の汚染を回避するには、スクリプトローカル関数を利用すること
が望しいです。RHS内に <SID> を使ってマッピングが定義されたスクリプトを見付けら
れるようにします。
短縮入力では、入力されて短縮入力展開のトリガーとなった文字が v:char にセット
されます。これを使って {lhs} の展開方法を決めることもできます。自分で v:char
を挿入したり変更したりすべきではありません。
マッピングで何も実行させない場合は、評価結果が空文字列になるようにします。も
し、なんからの{訳注:状態などの}変更で Vim がメインループを通過する必要があるも
のなら (例えば、画面の更新など)、"\<Ignore>" を返すようにします。
これは、"何もしない" と同義ですが Vim はループから入力待ちに戻ります。例:
前のコマンドが実行される前に、先行入力を探す時に式が評価されることがあることを
覚えておいてください。例:
あることに気付くでしょう。
これは評価のマッピングの文字の前に <Ignore> を挿入することで解決できます:
Vim9 script 内でのマッピング定義時は、式がそのスクリプトのコンテキストで評価
されます。これは式内でスクリプトローカルの要素についてアクセスできることを意味
します。
副作用に注意してください。式は文字の取得中に評価されるため、簡単に異常動作を起
こせてしまいます。そのため、次のものは制限されます:
- バッファのテキストの変更 textlock。
- 他のバッファの編集。
- :normal コマンド。
- カーソルの移動は可能ですが、後で元に戻されます。
以上のことを実現したい場合は、そのためのコマンド文字列を返してください。もしく
は代わりに <Cmd> マッピングを使用してください。
getchar() が使用できます。先行入力があればそれが消費されます。例えば次のような
マップを定義します:
するためには文字がもう一つ必要です。次に 'x' を押すと後者のマップが使われ、
"foo" が挿入されます。他のキーを押すと前者のマップが使われ、その文字が
getchar() によって取得され、返されます。
例を示します。リスト番号を自動的に増加させつつ挿入します:
CTRL-L で次の番号を挿入し、CTRL-R で番号をリセットします。CTRL-R は空文字列を
返すので、何も挿入されません。
Note: テキストの末尾以外で 0x80 をシングルバイトとして使った場合、それは機能し
ません。特殊キーとして認識されます。
<Cmd> :map-cmd
特別な文字列 <Cmd> は "コマンドマッピング" を開始し、モードを変化させずにコマ
ンドを直に実行します。マッピングの {rhs} で ":...<CR>" を使うなら、代わりに
"<Cmd>...<CR>" が使えます。例:
これはビジュアルおよびオペレータ待機モードでの :<C-U>、挿入モードでの
<C-O>: より柔軟で、なぜなら常にノーマルモードへ移行する代わりにコマンド実行
が現在のモードのままでだからです。ビジュアルモードでは gv での{訳注:選択の}
維持のトリックが不要です。コマンドをコマンドラインモードで直に動かせます (これ
でないならタイマーでのハックが必要です)。
挿入モードを跨いで <Cmd> を使う例:
<expr> マッピングとは異なり、<Cmd> コマンドに特別な制約はありません: あたかも
(制約のない) autocommand が呼び出されたかのように実行されます。
<ScriptCmd>
<ScriptCmd> は <Cmd> に似ていますが、コマンド実行時のコンテキストはマッピング
が定義された箇所のスクリプトのものが設定されます。これは Vim9 script で特に
便利です。また、インポートでの参照でも動作するので、autoload されるかもしれな
いスクリプトを使用するプラグインで便利です:
<F4> がどこで入力されたとしても、"impl" のインポートはマッピングが定義された
場所のスクリプトのコンテキストで検出されます。この例のように autoload のイン
ポートをする場合、マッピングが定義された時点ではなく、一度 <F4> が入力された時
にのみ "implementation.vim" スクリプトがロードされます。
<ScriptCmd> がない時は "s:impl" は "E121: Undefined variable" という結果になり
ます。
Note:
- <Cmd> と <ScriptCmd> はモード変更を回避するので、ユーザーの介入を必要としな
いため、CmdlineEnter と CmdlineLeave イベントをトリガーしません。
- 同じ理由により、<C-R><C-W> のようなキーコード keycodes は通常の、マッピン
グされていないキーとして解釈されます。
- コマンドは echo されません、<silent> は不要です。
- {rhs} は、マッピングが再帰的であっても、短縮入力や他のマッピングの対象にはな
りません。
- ビジュアルモードでは、line('v') と col('v') を使って、ビジュアルエリアの
一端を取得でき、カーソルは反対の端にいます。
E1255 E1136
<Cmd> と <ScriptCmd> コマンドではマッピング定義の {rhs} が <CR> で終わる必要が
あります。Command-line に入ることはありません。{rhs} でリテラル <CR> を使用
するには、<lt> を使用します。
1.3 マップとモード :map-modes
mapmode-nvo mapmode-n mapmode-v mapmode-o
マップには 7 つの種類があります。
- ノーマルモード: ノーマルモードのコマンドを入力するとき。
- ビジュアルモード: ビジュアルモードのコマンドを入力するとき。
- 選択モード: ビジュアルモードに似ていますが入力したテキストによって選択範囲が
置換されます。
- オペレータ待機モード: オペレータを待機しているとき。("d"、"y"、"c"、などの
後)。omap-info 参照。
- 挿入モード: 置換モードでも使われます。
- コマンドラインモード: ":" もしくは "/" コマンドを入力したとき。
- 端末モード: 端末 :terminal バッファでの入力時。
例外として、ノーマルモードでカウント(コマンドの繰り返し回数)を入力しているとき
は、0 (ゼロ)に対するマップは適用されません。これは 0 がマップされていても、カ
ウントの指定でゼロを入力できるようにするためです。
map-overview map-modes
マップコマンドとモードの対応。詳細は以後に。
コマンド モード
:map :noremap :unmap ノーマル、ビジュアル、選択、オペレータ待機
:nmap :nnoremap :nunmap ノーマル
:vmap :vnoremap :vunmap ビジュアル、選択
:smap :snoremap :sunmap 選択
:xmap :xnoremap :xunmap ビジュアル
:omap :onoremap :ounmap オペレータ待機
:map! :noremap! :unmap! 挿入、コマンドライン
:imap :inoremap :iunmap 挿入
:lmap :lnoremap :lunmap 挿入、コマンドライン、Lang-Arg
:cmap :cnoremap :cunmap コマンドライン
:tmap :tnoremap :tunmap 端末ジョブ
{訳注: Lang-Argについては language-mapping を参照}
上記のマップコマンドの対応表:
map-table
モード | Norm | Ins | Cmd | Vis | Sel | Opr | Term | Lang |
コマンド +------+-----+-----+-----+-----+-----+------+------+
[nore]map | yes | - | - | yes | yes | yes | - | - |
n[nore]map | yes | - | - | - | - | - | - | - |
[nore]map! | - | yes | yes | - | - | - | - | - |
i[nore]map | - | yes | - | - | - | - | - | - |
c[nore]map | - | - | yes | - | - | - | - | - |
v[nore]map | - | - | - | yes | yes | - | - | - |
x[nore]map | - | - | - | yes | - | - | - | - |
s[nore]map | - | - | - | - | yes | - | - | - |
o[nore]map | - | - | - | - | - | yes | - | - |
t[nore]map | - | - | - | - | - | - | yes | - |
l[nore]map | - | yes | yes | - | - | - | - | yes |
コマンド モード
ノーマル ビジュアル+選択 オペレータ待機
:map :noremap :unmap :mapclear yes yes yes
:nmap :nnoremap :nunmap :nmapclear yes - -
:vmap :vnoremap :vunmap :vmapclear - yes -
:omap :onoremap :ounmap :omapclear - - yes
:nunmap は修道院の外でも使えます。{訳注: nunは修道女の意}
mapmode-x mapmode-s
いくつかのコマンドはビジュアルモードと選択モードの両方で機能しますが、そうでな
いコマンドもあります。「ビジュアル」という言葉がビジュアルモードと選択モードの
両方を指している場合が多々あるので注意してください。
Select-mode-mapping
NOTE: 選択モードで印字可能文字にマップを定義するとユーザーの混乱を招くかも
しれません。印字可能文字に対しては明示的に :xmap と :smap を使い分けるのがいい
でしょう。マップを定義したあとで :sunmap を使う方法もあります。
コマンド モード
ビジュアル 選択
:vmap :vnoremap :vunmap :vmapclear yes yes
:xmap :xnoremap :xunmap :xmapclear yes -
:smap :snoremap :sunmap :smapclear - yes
mapmode-ic mapmode-i mapmode-c mapmode-l
一部のコマンドは、挿入モードとコマンドラインモードの両方で使えますが、一部はそ
うではありません:
コマンド モード
挿入 コマンドライン Lang-Arg
:map! :noremap! :unmap! :mapclear! yes yes -
:imap :inoremap :iunmap :imapclear yes - -
:cmap :cnoremap :cunmap :cmapclear - yes -
:lmap :lnoremap :lunmap :lmapclear yes* yes* yes*
* もし 'iminsert' が 1 ならば、下記 language-mapping を参照してください。
オリジナルの Vi はノーマルモード、ビジュアルモード、オペレータ待機モード、でひ
とまとまり、挿入モード、コマンドラインモード、でさらにひとまとまりのマップを持
ち、それぞれ区別されていませんでした。そのため、Vim の ":map" と ":map!" コマ
ンドは複数のモードに対してマップを設定したり表示したりします。
Vim では ":nmap"、":vmap"、":omap"、":cmap"、":imap" を使い分けることで、それ
ぞれのモード別にマップを設定することができます。
mapmode-t
端末マップは、端末ウィンドウの中で動作しているジョブに対してキーが入力されたと
きに機能します。terminal-typing を参照してください。
omap-info
オペレータ待機マップを使うと、移動コマンドを定義できます。そして、オペレータと
組み合わせて使うことができます。簡単な例:
す。
マップ適用時のカーソル位置を無視し、異なるテキストを選択するには、omap 内でビ
ジュアルモードを開始して対象となるテキストを選択してください。例えば、現在行の
関数名を選択するには次のようにします:
マルモードコマンドを使って、最初の '(' 文字を探し、その前にある単語を選択しま
す。通常はこれで関数名を選択できるでしょう。
あるマップをノーマルモードとビジュアルモードで使用し、そして、オペレータ待機
モードでは使用しないという場合は、3つのモードに対してマップを定義してからオペ
レータ待機モードのマップだけを削除します:
ビジュアルモードとオペレータ待機モードの場合や、ノーマルモードとオペレータ待機
モードの場合も同様にします。
language-mapping
":lmap" で定義したマップ(以下、言語マップ)は次の場面で利用できます:
- 挿入モード
- コマンドラインモード
- 検索パターンを入力するとき
- "r" や "f" などのコマンドに続いて文字を入力するとき
- input() の入力
大まかに説明すると、Vim コマンドとしてではなく、テキストの一部として入力するよ
うなときにはいつでも利用できます。"Lang-Arg" は別個のモードではなく、そのよう
な場面の総称です。
ある言語用の言語マップをロードするには、オプション 'keymap' を設定するのが
簡単です。45.5を参照してください。
挿入モードとコマンドラインモードでは CTRL-^ で言語マップの使用の有無を切り替
えることができますi_CTRL-^ c_CTRL-^。これらのコマンドは 'iminsert' オプショ
ンの値を変更します。(検索パターンの入力ではなく)コマンドラインに入力するときに
は CTRL-^ で切り替えるまで言語マップは無効になっています。挿入モードと検索パ
ターンでの使用状態は別々に記録されます。挿入モードの使用状態は "f" や "t" など
のコマンドで文字を入力するときにも使用されます。
言語マップは、既にマップが適用された文字には適用されません。言語マップは入
力された文字に対してのみ使用されます。これは、言語マップは文字が入力されたとき
に適用されたはずという想定によるものです。
1.4 マップの一覧表示 map-listing
マップを一覧表示したときの行頭の2文字は使用できるモードを表しています:
文字 モード
<Space> ノーマル、ビジュアル、選択、オペレータ待機
n ノーマル
v ビジュアル、選択
s 選択
x ビジュアル
o オペレータ待機
! 挿入、コマンドライン
i 挿入
l 挿入、コマンドライン、Lang-Argでの ":lmap" マップ
c コマンドライン
t 端末ジョブ
{訳注: Lang-Argについては language-mapping を参照}
{rhs} の直前に特殊な文字が表示されているものは次のことを意味します:
* 再マップされません
& スクリプトローカルなマップだけが再マップされます
@ バッファローカルなマップです。
{lhs} の後ろの最初の非空白文字から行末 (もしくは '|') までのすべての文字は
{rhs} の一部です。そのため {rhs} の末尾を空白文字にすることができます。
Note: ビジュアルモードのマップでは "'<" マークが使えます。これはカレントバッ
ファで選択されていた範囲の開始位置を示しています'<。
何がマッピングされているか調べるのに :filter コマンドを使うことができます。
パターンは {lhs} と {rhs} に対しては、生の形式で {訳注: 実際のキャラクターコー
ドを用いて} マッチします。
マッピングが一覧表示されている際に、例えばタイマーコールバックなどからマッピン
グを追加したりクリアすることはできません。 E1309
:map-verbose
'verbose' がゼロ以外の場合、検出および使用された 'keyprotocol' の値が最初の行
に表示されます。また、キーマップには、最後に定義された場所も表示されます。
例:
詳しくは :verbose-cmd を参照してください。
1.5 特殊キーのマップ :map-special-keys
特殊キーをマップに含めるのには次の 3 つの方法があります:
1. Vi 互換の方法: 生のキーコードをマップします。それはほとんどの場合 <Esc> で
始まるキーコード列です。このようなマップを入力するには、まず ":map " と入力
し、CTRL-V を押してからファンクションキーを押します。Note: そのキーのキー
コードが termcap(t_options) にある場合は、自動的に内部コードの形式に変換さ
れ、次の 2. のようなマップになります ('cpoptions' に 'k' フラグが指定されて
いる場合は除く)
2. ファンクションキーの内部コードを使います。そのようなマップを入力するには、
CTRL-K を押してからファンクションキーを押します。もしくは、
"#1"、"#2"、.. "#9"、"#0"、"<Up>"、"<S-Down>"、"<S-F7>"、などの形式で指定し
ます。(キーの表は key-notation 参照。<Up> 以下のすべてのキーを使うことが
できます)。1 から 10 までのファンクションキーは二つの方法で定義できます:
"#2" のような番号だけの方法と、"<F2>" という表記で指定する方法です。この両
方がファンクションキー 2 を表します。"#0" はファンクションキー 10 を表し、
't_f10' で定義されます。"#0" は、キーボードによってはファンクションキー 0に
なることがあります。'cpoptions' に '<' フラグが指定されている場合は、<>表
記は使えません。
3. termcap エントリを <t_xx> という形式で指定します。"xx" は termcap エントリ
の名前です。どんなエントリの文字列も使うことができます。例:
グが指定されている場合は使えません。
2. と 3. の方法の利点は、異なる端末でもマップを修正する必要がないことです(ファ
ンクションキーは、同じ意味の内部コード、もしくは実際のキーコードに変換されま
す。使用している端末に依存しません。termcap が正しく設定されていれば、異なる端
末で同じマップを共有できます)。
詳細: まず Vim はキーボードから送られたキーコードがマップされているかどうかを
調べます。マップされていなければ、端末のキーコードかどうか調べます(参照
terminal-options)。端末コードであれば、内部コードで置き換えます。それからも
う一度、マップされているかどうかをチェックします (これにより内部コードをマップ
できます)。スクリプトファイルに書き込まれる内容は、どのように解釈されたかによ
ります。端末のキーコードがマップとして認識された場合は、キーコードそのものがス
クリプトファイルに書き込まれます。端末コードとして認識された場合は、内部コード
がスクリプトファイルに書き込まれます。
{訳注: > スクリプトファイルに書き込まれる...
おそらく -w の話。}
1.6 特殊文字 :map-special-chars
map_backslash map-backslash
Note: このドキュメントでは、マップや短縮入力を定義するときに、CTRL-V だけが特
殊な文字として触れられていますが、'cpoptions' が 'B' を含んでいない場合は、
バックスラッシュも CTRL-V と同様の特殊な働きをします。<> 表記も問題なく使用
できます。しかし、"<C-V>" を CTRL-V と同じように、(マップを入力するときに)次の
文字をエスケープする目的で使うことはできません。
バックスラッシュにマップしたり、バックスラッシュをそのまま {rhs} に使いたい場
合は、特別文字 "<Bslash>" を使います。マップを入れ子にした場合などにバックス
ラッシュを二重にする必要がなくなります。
map_CTRL-C map-CTRL-C
CTRL-C を {lhs} で使うことはできますが、それは Vim がキー入力を待機中のときだ
け機能します。Vim がビジー状態 (何かを実行中) のときは機能しません。Vim がビ
ジー状態の場合、CTRL-C は実行中のコマンドを中断します。
MS-Windows の GUI 環境では、CTRL-C にマップすることができるので、クリップボー
ドにコピーする機能を割り当てることができます。Vim の動作を中断するには
CTRL-Break を使います。
map_space_in_lhs map-space_in_lhs
{lhs} に空白文字を含めるには CTRL-V を前置してください (空白文字の前で CTRL-V
を二度押しで入力)。
map_space_in_rhs map-space_in_rhs
{rhs} を空白文字で開始するには "<Space>" を使ってください。Vi との互換性を完全
に保ちたい場合は <> 表記を使わずに、{rhs} の直前に CTRL-V (CTRL-V を二度押し
で入力)を前置してください。
map_empty_rhs map-empty-rhs
CTRL-V を1つだけ入力した後に (CTRL-Vを2度押しで入力) 何も入力しないことで空の
{rhs} を作ることもできます。残念ながらvimrcファイル内ではこの方法は使用できま
せん。
<Nop>
空のマップを作るには {rhs} に "<Nop>" を指定する方法が簡単です。これは <> 表
記を使えるようにしていれば動作します。例えば、ファンクションキー 8 は何もしな
い、としたい場合は次のようにします:
map-multibyte
マルチバイト文字をマップすることができます。ただし、マルチバイト文字の一部のバ
イトだけをマップすることはできません。それは次のような問題が起こるのを防ぐため
です:
(0xe1 または <M-a>) は UTF-8 では 0xc3 0xa1 の 2 バイトで表現されるので、0xc3
をマップしてしまうと á が入力できなくなってしまいます。
<Leader> mapleader
マップコマンドで特別な文字列 "<Leader>" を使用すると、その部分が変数
"g:mapleader" に設定された文字列で置き換わります。"g:mapleader" が空文字列のと
きや設定されていない場合にはバックスラッシュが使用されます。例:
Note: 変数 "g:mapleader" はマップを定義するときに使用されます。"g:mapleader"
を変更しても、すでに定義されているマップには影響しません。
<LocalLeader> maplocalleader
<LocalLeader> は <Leader> に似ていますが、"mapleader" ではなく
"maplocalleader" を使用します。<LocalLeader> はバッファローカルのマップに使用
するといいでしょう。例:
グローバルプラグインでは <Leader> を使用し、ファイルタイププラグインでは
<LocalLeader> を使用するといいでしょう。"mapleader" と "maplocalleader" の設定
は同じでも構いませんが、別の値を設定すれば、グローバルプラグインとファイルタイ
ププラグインのマップが重なる可能性が低くなります。設定例としては、"mapleader"
をバックスラッシュのままにしておいて、"maplocalleader" をアンダースコア (_) に
するなど。
map-<SID>
特別な文字列 "<SID>" を使ってスクリプトローカルなマップを定義できます。詳細は
<SID>を参照してください。
<Plug>
特別な文字列 "<Plug>" を使ってスクリプトの内部作業用のマップを定義できます。こ
れはどのキー入力にもマッチしません。プラグインを作成するときに便利です
using-<Plug>。
<MouseMove>
特別な文字列 "<MouseMove>" を使ってマウスの移動を取り扱えます。そのためには
'mousemoveevent' が有効になっている必要があります。現在、GUI でのみ動作します。
getmousepos() 関数がマウスの位置を取得するのに使えます。
<Char> <Char->
<Char> を使って、文字を10進数、8進数、16進数の数値指定でマップできます:
<Char-123> character 123
<Char-033> character 27
<Char-0x7f> character 127
<S-Char-114> character 114 ('r') shifted ('R')
これは 'keymap' ファイルで (マルチバイト) 文字を定義するのに便利です。表記は大
文字でも小文字でも構いません。
map-comments
マップコマンドでは '"' (ダブルクォート) も {lhs} や {rhs} の一部と見なされるた
め、マップコマンドの後ろにコメントを置くことはできません。しかし、|" を使うこ
とができます。これはコメント付きの空の新しいコマンドを開始するからです。
map_bar map-bar
'|' 文字は、マップコマンドと次のコマンドを分けるために使われるので、'|' 文字を
{rhs} に含めるには特殊な方法が必要です。
次の3つの方法があります:
方法 使用できる条件 例
<Bar> 'cpoptions'に'<'が含まれていない :map _l :!ls <Bar> more^M
\| 'cpoptions'に'b'が含まれていない :map _l :!ls \| more^M
^V| VimとViで常に使用できる :map _l :!ls ^V| more^M
(ここで ^V は CTRL-V を表します。一つの CTRL-V を挿入するには CTRL-V を二度押
しで入力します。この用途では、<>表記を使って "<C-V>" とすることはできません)。
'cpoptions' が標準設定のままなら、三つ全ての方法が使用できます。
'cpoptions' に 'b' が含まれている場合、"\|" は、'\' で終わるマップコマンドの後
に、別のコマンドが続いているとみなされます。これは Vi 互換ですが、他のコマンド
の場合を考えるとあまり論理的ではありません。
map_return map-return
マップに Ex コマンドを含める場合、そのコマンドラインを実行するために改行文字を
挿入する必要があります。これには <CR> を使うことが推奨されています(参照<>)。
例:
挿入モードやコマンドラインモードで、入力する文字がマップされないようにするに
は、その文字を入力する前に CTRL-V を (1回) 押してください。'paste' がオンの場
合には、挿入モードでマップを使用できません。
map-error
Note: マップを使用したときに、エラーが起きた場合 (エラーメッセージが出ます。
あるいはビープ音が出るかもしれません)、マップのまだ実行されていない部分は実行
されません。これはVi互換です。
Note: コマンド「@zZtTfF[]rm'`"v」と CTRL-X の引数にはマップは適用されません。
どのようなマップがあっても、レジスタやマークを指定できるようにするためです。
1.7 マップに使うキー map-which-keys
マップを定義するときに {lhs} に指定するキーを選ぶことができますが、Vim のコマ
ンドに使われているキーをマップしてしまうとそれらのコマンドを使用できなくなりま
す。そこで、いくつかの提案があります:
- ファンクションキー (<F2>、<F3>など) や Shift+ファンクションキー(<S-F1>、
<S-F2>など) を使用する。<F1> には既にヘルプコマンドが割り当てられています。
- Alt キー または Meta キーと任意のキーを押す。あなたのキーボードのアクセント
記号付き文字の使用頻度に依存します。 :map-alt-keys
- "_" や "," などの文字と別の文字を組み合わせて使用する。コマンド "_" と"," は
すでに存在していますが (_と,を参照)、使う機会はあまりないでしょう。
- 他に類するコマンドがあるキーを使用する。例えば、CTRL-P と CTRL-N。さらに多く
のマップを使用するには、複数文字を使用します。
- <Leader> と 1 つまたは複数のキーを組み合わせて使用する。これは特にスクリプト
で便利です。 mapleader
標準のキー操作を損なうことなくマップできるキーや、使われていないキーを探すには
index.txt を参照してください。":help {key}^D" を使用してそのキーが使われてい
るかどうかを調べることもできます ({key}は調べたいキー、^DはCTRL-Dの入力)。
1.8 例 map-examples
マップの例をいくつか示します (見た通り入力してください。"<CR>" は 4 文字です。
このような表記(<>)は 'cpoptions' に '<' が含まれていると使用できません)。
カウント指定の掛け算
マップの展開前にカウント指定が入力されると、そのカウントは {lhs} の前に入力さ
れたものとして扱われます。例えば、次のマップを定義したとき:
になります。カウントを掛けたい場合は式レジスタを使ってください:
1.9 マップを使う map-typing
Vim は、入力されたキーで始まるマップがあるかどうか調べ、そのようなマップがある
場合は、入力とマップが完全に一致するか一致しないと判断できるまで、次の入力を待
ちます。例えば、"qq" というマップがあるとして、最初に入力した 'q' は、次の文字
を入力するまで実際に入力されません。なぜなら、Vim には次に入力される文字が 'q'
であるかそうでないかを知ることができないからです。'timeout' がオンになっている
と (標準設定はオンです)、Vim は一秒間 (または 'timeoutlen' で指定されている時
間) だけ待機します。待機した後に、'q' という文字が入力されたのだと判断します。
ゆっくり入力したい場合や、遅いシステムを使用している場合は、'timeout' をオフに
してください。'ttimeout' を設定するのもいいでしょう。
map-precedence
バッファローカルなマップ(:map-<buffer>を使用して定義された)はどのグローバル
なマップよりも優先されます。バッファローカルなマップがグローバルなマップと同じ
場合、Vimはバッファローカルなマップを使用します。加えて、<nowait> で定義された
場合はより長いマップが同じ接頭辞を持っているとしても、直ちに完了したマップを使
用します。例えば、次の2つのマップがあるとします:
\abc を入力するかどうかを知るためにそれ以上の文字を待つことはしません。
map-keys-fails
次のような状況では、キーコードが認識されないことがあります:
- Vim がキーコードを部分的にしか読めない。これは最初の文字だけ読める場合が多い
です。特定の Unix 版と xterm の組み合わせで起こります。
- 文字(列)の後にキーコードがあるマップ。例、"<F1><F1>" や "g<F1>"。
このように、キーコードが認識されない状況では、そのようなマップを使用することが
できません。対処方が2つあります:
- 'cpoptions' から 'K' フラグを除く。そうすると Vim はファンクションキーの残り
のコードを待つようになります。
- <F1> から <F4> のキーによって生成される実際のキーコードが <xF1> から <xF4>
と同じ場合があります。<xF1> を <F1> へ、<xF2> を <F2>へ、といったマップが存
在しますが、これはマップの後半では認識されません。<F1> から <F4> のキーの
キーコードを正しく設定してください:
際のキーを入力してください。
マップを定義するときに二番目の特殊キーを実際のキーコードで指定することでも解決
できます:
てしまいます。
他にも、ALT や Meta キーを押しながらキーを入力したときに、コードの 8 ビット目
をセットする代わりにそのキーに ESC を前置するような端末で問題が起こることがあ
ります。:map-alt-keys を参照。
recursive_mapping
{rhs} の中に {lhs} を含めて、再帰マップを作成できます。{lhs} を入力すると
{rhs} に置き換えられ、{rhs} の中に {lhs} があるとその {lhs} がさらに {rhs} に
置き換えられ、さらに {rhs} の中の {lhs} が置き換えられ...。というようにコマン
ドを無限に繰り返すことができます。エラーを生じさせないと止めることができないの
が唯一の問題です。例外として、{rhs} が {lhs} で始まっている場合は、その文字は
再帰的にマップされません (これは Vi 互換です)。
例えば次のマップは:
されません。
二つのキーの意味を入れ換えるような場合は :noremap を使ってください。例えば:
普通の :map コマンドでマップを定義した場合、'remap' オプションがオンになってい
ると、そのマップが使用された後のテキスト ({rhs}) に {lhs} が含まれている限り、
マップが再帰的に繰り返されます。例えば、次のようなマップを使用する場合:
'maxmapdepth' に設定された回数だけ (標準設定は1000回) 繰り返し、"recursive
mapping" というエラーメッセージを表示します。
:map-undo
マップされたもの({rhs})がアンドゥコマンドを含んでいると、その操作を実行する前
の状態に戻すことになります。アンドゥが1回だけなら、その動作はオリジナルのVi互
換です(オリジナルのViでは、2回アンドゥしても意味がなく、最初のアンドゥを実行す
る前の状態に戻るだけです)。
1.10 ALT キーを使ったマップ :map-alt-keys
マッピングコマンドの読みやすさのため <A-k> の形式が使えます。Note <A-k> と
<A-K> は異なることに注意してください。後者は大文字を使います。実際には <A-K>
と <A-S-K> は同じです。"A" の代わりに "M" を使うこともできます。もし実際の
Meta 修飾キーがある場合は、:map-meta-keys を参照してください。
GUI では、Vim は Alt キーを直接取り扱うので、ALT キーを使ったマップは常に機能
します。CUI 端末では、Vim は受け取ったバイト列から、ALT キーが押されているかど
うかを割り出さなければなりません。
端末が modifyOtherKeys モードをサポートし、有効になっている場合、Vim はより多
くのキーの組み合わせを認識できます。以下の modifyOtherKeys を参照してくださ
い。
Kitty キーボードプロトコルも同じように動作します。kitty-keyboard-protocol を
参照してください。
初期設定では、ALT キーが押されているときは、文字の 8 ビット目が設定されるもの
と仮定しています。xterm、aterm、rxvt など、ほとんどの端末はこの方法で問題あり
ません。<A-k> のようなマップが動作しない場合は、その端末が、文字の前に ESC を
付けているのかもしれません。ユーザーが文字の前に ESC を入力することもできます
から、Vim は何が起きたか知ることはできません (ただし、ESC と文字の間に延滞があ
るかどうかをチェックする方法はあります。確実な方法ではありませんが)。
現在、gnome-terminal や konsole などの主要な端末が ESC を前置します。代わりに
8 ビット目を使うように設定する方法はないようです。Xterm では設定なしで機能しま
す。Aterm と rxvt では "--meta8" 引数を使えば機能します。"metaSendsEscape"、
"eightBitInput"、eightBitOutput" のようなリソースを設定することでも動作を変更
できます。
Linux コンソールでは、"setmetamode" コマンドで動作を切り替えることができます。
ESC の前置を使わないようにすると、他のプログラムで問題が起こる可能性があるので
注意してください。bash の "convert-meta" が "on" になっていることを確認し、
Meta キーバインディングが動作するようにしてください。(システム固有の設定変更を
していなければ、これは readline の標準の動作です)次の行を ~/.inputrc に追加す
ると、その設定をすることができます:
ファイルをはじめて作成した場合は、システム全体の設定を維持するために、次の行を
最初に加える必要があるかもしれません(そのファイルがシステムにある場合):
このように設定すると、ウムラウトのような特殊な文字を入力できなくなるかもしれま
せん。その場合は、文字の前に CTRL-V を入力してください。
convert-meta は UTF-8 ロケールでは問題を起こすことがすでに報告されています。
xterm のような端末では、起動しているときに、メニューの "Main Options" から
"metaSendsEscape" リソースを設定できます。メニューは端末を Ctrl-LeftClick する
と表示できます。他のアプリケーションでは ESC を使い、Vim では使いたくない、と
いう場合にこのリソースを使うと便利です。
1.11 META キーを使ったマップ :map-meta-keys
Meta 修飾子を使ったマッピングは Alt キーを使った場合と非常によく似た動きをしま
す。キーボードのどのキーが Meta 修飾子として動作するかはキーボードと設定に依存
します。
Note <M-a> マップは実際には Alt キーを使うことに注意してください。これは混乱す
るでしょう! 後方互換性がなくなるため、変更することはできません。
Meta 修飾子には文字 "T" が使われます。例えば挿入モードで Meta-b をマップするに
は:
1.12 SuperキーまたはCommandキーのマップ :map-super-keys :map-cmd-key
Super 修飾子は、Linux 上の gVim および Mac OS 上の MacVim の GUI モード
(gui_running が 1 の場合) で使用できます。Mac を使用している場合、これは
Command キーを表し、GTK GUI を使用する Linux では、Super キーを表します。
文字 "D" は、Super / Command 修飾子に使用されます。
例えば、挿入モードで Command-b をマップするには:
1.13 modifyOtherKeys モードのマップ modifyOtherKeys
xterm と他のいくつかの端末は、修飾子付きのキーが特別なエスケープコードで送信さ
れるモードにすることができます。Vim はこれらのコードを認識し、Backspace が文字
の 8 を送信した場合でも、CTRL-H と Backspace を区別できます。Tab と CTRL-I な
ど、他の方法では個別にマップできないさらに多くの特別なキーも区別できます。
xterm の場合、組み込みの termcap エントリで modifyOtherKeys が有効になっていま
す。これが使われない場合は、vimrc にこれらの行を追加して modifyOtherKeys を有
効にできます:
これは modifyOtherKeys をレベル 2 に設定します。Note modifyOtherKeys レベル 1
は動作しないことに注意してください。いくつかの端末はレベル 2 をサポートしてお
らず Vim が正しく認識できないキーコードを送信します。
modifyOtherKeys モードで問題が発生する場合は、無効にすることができます:
は、シェルコマンドを実行します。例: !ls。あるいはこれらの行を vimrc に書い
てください。
modifyOtherKeys が有効化されているときは <C-[> と <C-S-{> をマップすることがで
きます:
Note <C-S-[> や <C-S-{> ではなく <C-{> が使われていることに注意してください。
これは多くのキーボードで動作します。同様に、<C-}> は <C-S-]> もしくは <C-S-}>
のそして <C-|> は <C-S-\> もしくは <C-S-|> の代わりに使用されます。Note '|' は
マッピングにおいて特別な意味を持ちます、map-bar を参照。
警告: <C-[> をマップした場合、非常に多くのEscから開始するキーコードを破壊する
ことがあります。他のマッピングの「後」であることを確認してください。
xterm version 377 以降では Vim は modifyOtherKeys の状態を要求して検出すること
ができます。これには 't_RK' termcap エントリが使われます。その応答が見つかれば
Vim は modifyOtherKeys レベル 2 が有効化されているかを知り、それに応じてマップ
を扱います。
version 377 より前では Vim は modifyOtherKeys モードによって生成されたエスケー
プシーケンスを見つけた時に、それが有効化されていることを自動で検出します。Vim
がそのようなエスケープシーケンスを検出したかを見るには :verbose map を使いま
す。1 行目に "Seen modifyOtherKeys: true" (おそらく翻訳される) と表示されます。
この自動検出は "<1b>[27;" で始まるエスケープシーケンスを受信することに依存しま
す。これは xterm がこれらのキーコードを送信する通常の方法です。しかし、もし
formatOtherKeys リソースが他の形式を使って設定されているとこれが認識ができな
いため、formatOtherKeys を設定してはいけません。
既知の副作用として、挿入モードでは、CTRL-V キーの後に生のエスケープシーケンス
が挿入されます。これは、modifyOtherKeys が有効になっているかどうかを確認するた
めに使用できます。挿入モードで CTRL-SHIFT-V CTRL-V と入力し、1 バイトが得られ
たら modifyOtherKeys はオフで、<1b>[27;5;118~ が得られたらオンです。
Note xterm の version 376 までは Shift-Esc が通常の Esc を送信し、Shift 修飾子
がドロップするバグがあることに注意してください。
'esckeys' オプションがオフの時、修飾子付きのすべてのキーが挿入モードを終了させ
るのを防ぐため、挿入モードで modifyOtherKeys は無効化されます。
1.14 Kitty キーボードプロトコルを使ったマップ kitty-keyboard-protocol
'term' の値が "kitty" を含んでいる場合、Vim は Kitty キーボードプロトコルを有
効化するエスケープシーケンスを送出します。これは 'keyprotocol' オプションで変
更できます。
modifyOtherKeys と同様に、これはより多く修飾子付きキーを区別することを可能にし
ます。またこのプロトコルは Esc キーに対してもエスケープシーケンスを送信するた
め、Vim は受信した Esc キャラクタがタイプされた Esc キーを意味するのかエスケー
プシーケンスの開始なのかを知るためのタイムアウトを使う必要がありません。
Vim はステータス要求 (これは t_TI termcap エントリの一部のはずです) を見た時
に Kitty キーボードプロトコルが有効化されているかを自動で検出します。Vim がそ
のようなエスケープシーケンスを検出したかを見るには以下を使います:
す。{value} の意味は:
Unknown ステータスはまだ受信していない
Off プロトコルは使われていない
On プロトコルが使われている
Disabled プロトコルは使われているが 't_TE' で無効化されているこ
とが予想される
Cleared プロトコルは 't_TE' で無効化されていることが予想され、
以前の状態は不明
1.15 オペレータの作成 :map-operator
オペレータは {motion} コマンドと合わせて使われます。独自のオペレータを定義する
には、最初に 'operatorfunc' を設定し、そして、g@ オペレータを呼びます。ユー
ザーが {motion} コマンドを実行した後、設定した関数が実行されます。
g@ E774 E775
g@{motion} 'operatorfunc' に設定された関数を実行します。
'[ マークに {motion} で選択された範囲の最初の位置が設
定されます。'] マークには選択範囲の最後の位置が設定さ
れます。
関数の引数には、文字列が一つ渡されます:
"line" {motion} は行単位 linewise
"char" {motion} は文字単位 characterwise
"block" {motion} は矩形 blockwise-visual
タイプは強制することができます。forced-motion を参照し
てください。
{+eval が有効な場合のみ利用できます}
例を示します。これは <F4> を使ってスペースの数を数えます:
<expr> のマッピングを使うことでなんらかのカウントかレジスタの接頭詞を取ること
が可能になります。それにより、CmdlineEnter と CmdlineLeave の自動コマンドをト
リガーするコマンドラインの使用も回避します。
Note: 一時的に 'selection' を "inclusive" に設定し、'[ から '] まで選択した範
囲を正しくヤンクできるようにしています。
Note: 'clipboard' オプションの値に unnamed か unnamedplus が含まれている場
合、レジスタの "* や "+ が上書きされることを防ぐため、一時的に空に設定され
ます。
mode() 関数はオペレータが適用された後の状態を返します。
この例では現在行のテキストの外側にクォートを追加するノーマルモードのオペレータ
を作成するのにラムダ関数を使用しています:
==============================================================================
2. 短縮入力 (Abbreviations) abbreviations Abbreviations
短縮入力は、挿入モード、置換モード、コマンドラインモードで使えます。短縮入力と
して登録されている単語を入力すると、それが表す単語に置き換えられます。よく使う
長い単語を打ち込むときのタイプ数を減らしたり、明確なスペルミスを自動的に修正す
るのに使えます。
例:
:iab ms Microsoft
:iab tihs this
短縮入力には三つの種類があります:
full-id "full-id" タイプは完全なキーワード文字から構成されます('iskeyword'
オプションに含まれる文字です)。最も一般的な短縮入力です。
例: "foo", "g3", "-1"
end-id "end-id" タイプはキーワード文字で終わりますが、他の文字はキーワード
文字ではありません。
例: "#i", "..f", "$/7"
non-id "non-id" タイプは非キーワード文字で終わります。他の文字はスペースと
タブ文字以外のどんな文字でもよいです。{Vi では、このタイプはサポート
されていません}
例: "def#", "4/7$"
短縮入力にできない文字列の例: "a.b", "#def", "a b", "_$r"
短縮入力は非キーワード文字を入力したときに展開されます。これは、挿入モードを終
わらせる<Esc>を入力したり、コマンドを終わらせる<CR>を入力したときにも起こりま
す。短縮入力を終わらせる非キーワード文字は、短縮入力を展開した後に挿入されま
す。<C-]>文字は例外で、短縮入力だけが展開され挿入されます。
例:
"hh<C-]>" で "hello" に展開されます。
カーソルの前の文字が短縮入力とマッチする場合のみ機能します。短縮入力の種類に
よって、さらに条件があります:
full-id マッチした場所の前が非キーワード文字、行頭、挿入を開始した場所、であ
ること。例外: 短縮入力が1文字の場合、その前の文字がスペース、タブ、
以外の非キーワード文字なら短縮入力は展開されません。ただし、コマンド
ラインにおける "'<,'>" (もしくはその他のマーク) は無視され、コマンド
ラインがその後から始まっているように動作します。
end-id マッチした場所の前が非キーワード文字、スペース、タブ、行頭、挿入を開
始した場所、であること。
non-id マッチした場所の前がスペース、タブ、行頭、挿入を開始した場所、である
こと。
例: ({CURSOR}は非キーワード文字を入力する場所です)
" foobar{CURSOR}" は展開されません
"barfoo{CURSOR}" は展開されません
">#i{CURSOR}" は展開されません
"test ;;" は "test <endofline>" に展開されます
挿入モードで短縮入力の展開を避けるには、短縮入力を発動する可能性のある文字を入
力する前に CTRL-V を押します。 例:CTRL-V <Space> もしくは短縮入力の一部を入力
してから挿入モードを <Esc> で抜け、再度挿入モードに "a" で入って残りを入力しま
す。
コマンドラインモードで短縮入力の展開を避けるには、短縮入力の文字の途中でCTRL-V
を入力します (CTRL-V を2度押し)。展開されなかった場合、普通の文字の前のCTRL-V
は普通は無視されます。
短縮入力の後で、カーソルを動かすこともできます:
さらに手の込んだこともできます。例えば、短縮入力を展開するときに入力したスペー
スを消してしまうには:
標準設定されている短縮入力はありません。
短縮入力の展開は再帰的には行われません。":ab f f-o-o" という短縮入力を問題なく
使うことができます。しかし、展開された文字にはマップが適用されます。 {Vi のい
くつかのバージョンで再帰的な短縮入力をサポートしていますが、そこになんら明確な
理由はありません}
'paste' オプションがオンの場合、短縮入力は使用できません。
:abbreviate-local :abbreviate-<buffer>
マップと同じように、バッファローカルな短縮入力を作成できます。これは主に
filetype-pluginなどで使用されます。C言語用プラグインの例:
:ab :abbreviate
:ab[breviate] すべての短縮入力を一覧表示します。行頭の文字は、その短
縮入力を使用できるモードを示しています: 'i' は挿入モー
ド、'c' はコマンドラインモード、'!' はその両方。マップ
の一覧表示と同じです。map-listingを参照。
:abbreviate-verbose
'verbose' がゼロ以外のときに短縮入力一覧を表示すると、どこで定義されたのかも表
示されます。例:
詳しくは :verbose-cmd を参照してください。
:ab[breviate] {lhs} {lhs} で始まる短縮入力を一覧表示します。
{lhs} に入力した文字が短縮入力として展開されないように
するには CTRL-V (2度押しで入力する) を挿入します。そう
しないとコマンドライン用の短縮入力があった場合にそれが
展開されてしまいます。
:ab[breviate] [<expr>] [<buffer>] {lhs} {rhs}
{rhs} の短縮入力を {lhs} として定義します。既に {lhs}
が定義されていると、新しい {rhs} で置き換えられます。
{rhs} はスペースを含んでいてもかまいません。
<expr> 引数については:map-<expr>を参照してください。
<buffer> 引数については :map-<buffer> を参照してくだ
さい。
:una :unabbreviate
:una[bbreviate] [<buffer>] {lhs}
{lhs} という短縮入力を全て削除します。見つからなかった
場合は、{lhs} に入力した文字を各短縮入力の {rhs} から
探して見つかったものを削除します。これは短縮入力が展開
されてしまった状態でも削除できるようにするためです。短
縮入力の展開を防ぐには CTRL-V (2度押しで入力する) を挿
入します。
:norea :noreabbrev
:norea[bbrev] [<expr>] [<buffer>] [lhs] [rhs]
":ab" と同じですが、展開後にマップを適用しません。
:ca :cab :cabbrev
:ca[bbrev] [<expr>] [<buffer>] [lhs] [rhs]
":ab" と同じですが、コマンドラインモード用の短縮入力の
み対象です。
:cuna :cunabbrev
:cuna[bbrev] [<buffer>] {lhs}
":una" と同じですが、コマンドラインモード用の短縮入力
のみ対象です。
:cnorea :cnoreabbrev
:cnorea[bbrev] [<expr>] [<buffer>] [lhs] [rhs]
":ab" と同じですが、コマンドラインモード用の短縮入力の
み対象で、展開後にマップを適用しません。
:ia :iabbrev
:ia[bbrev] [<expr>] [<buffer>] [lhs] [rhs]
":ab" と同じですが、挿入モード用の短縮入力のみ対象で
す。
:iuna :iunabbrev
:iuna[bbrev] [<buffer>] {lhs}
":una" と同じですが、挿入モード用の短縮入力のみ対象で
す。
:inorea :inoreabbrev
:inorea[bbrev] [<expr>] [<buffer>] [lhs] [rhs]
":ab" と同じですが、挿入モード用の短縮入力のみ対象で、
展開後にマップを適用しません。
:abc :abclear
:abc[lear] [<buffer>] すべての短縮入力を削除します。
:iabc :iabclear
:iabc[lear] [<buffer>] 挿入モード用の短縮入力を削除します。
:cabc :cabclear
:cabc[lear] [<buffer>] コマンドラインモード用の短縮入力を削除します。
using_CTRL-V
特殊な文字を短縮入力の{rhs}で使うことができます。非印字可能文字の特殊な意味を
打ち消す(クォートする)には、CTRL-Vを使用します。必要なCTRL-Vの数は、どのような
短縮入力を作成するかによります。これはマップでも同様です。例を示します。
"esc" を実際の<Esc>文字を挿入する短縮入力にしたいとしましょう。Vim で ":ab" コ
マンドを使うときには、次のようにしなければなりません: (ここで^VはCTRL-Vで、
^[は<Esc>です)
入力: ab esc ^V^V^V^V^V^[
キー入力はすべて^Vによるクォートが適用されます。つまり、1番目、3番目、
5番目の^Vは、2番目と4番目の^Vと、^[がコマンドラインに入力されるように
しています。
見え方: ab esc ^V^V^[
コマンドラインには実際には2つの^Vと^[が表示されています。もしそうする
つもりがあれば、これは .exrc ファイルでの見え方になるはずです。始めの
^Vは2番目の^Vをクォートするためにあります。:abコマンドは^Vをクォート文
字として扱いますので、短縮入力の中で、クォートされた空白文字や '|' 文
字を使うことができます。:abコマンドは^[に対しては何も特殊な処理は行い
ません。だからクォートする必要もないです。(クォートしても問題はありま
せん。上の例は7(8はだめです!)個の^Vを入力しても動作します)。
格納: esc ^V^[
コマンドが解析された後、短い形式("esc")と長い形式("^V^[" の2文字)とし
て、短縮入力の一覧に加えられます。:ab コマンドを引数なしで実行したとき
に、この形の短縮入力が表示されます。
あとで、ユーザーが "esc" を入力し、短縮入力が展開されたとき、長い形式
は実際のキー入力と同様に^Vによるクォートが適用されます。つまり、^Vが
^[をクォートし、"挿入モードから抜ける" 文字として解釈されることを防ぐ
のです。その代わりに、^[がテキストに挿入されます。
展開: ^[
[例は Steve Kirkendall によって提供されました]
==============================================================================
3. ローカルマップとローカル関数(Local mappings and functions) script-local
いくつかの Vim script を併用すると、あるスクリプトで使われているマップや関数と
同じ名前のものが別のスクリプトでも使用される恐れがあります。それを避けるには、
スクリプトローカルなマップや関数を使用します。
<SID> <SNR> E81
マップやメニューに "<SID>" という特別な文字列を使用できます。これは 'cpoptions'
にフラグ '<' が含まれていると利用できません。これはスクリプトローカル関数を同
じスクリプト内のマッピングから呼びたい場合に便利です。
マップコマンドを実行すると、"<SID>" は、<SNR> という特別なキーコードとスクリプ
ト固有の番号、そしてアンダースコアに置換されます。例:
スクリプトで関数を作成するときに、関数名の前に "s:" を付けると、ローカル関数を
作成できます(Vim9 script ではプリフィックスなしの関数はスクリプトローカルに
なります)。しかし、その関数をマップで使用する場合、そのマップをスクリプト以外
の場所で実行すると、その関数がどのスクリプトで定義されたのか分かりません。これ
を解決するには、マップ中で "s:" ではなく "<SID>" を使用します。この場合も
"<SID>" は上記の例と同じように置換されます。これでローカル関数の呼び出しを含む
マップを定義できます。
ローカル関数は、その関数を定義したスクリプトのコンテキストで実行されます。その
ため、その関数内で新たに定義した関数やマップにも "s:" や "<SID>" を使用できま
す。その場合、その関数自身と同じスクリプト番号が使用されます。"s:var" といった
スクリプトローカル変数も同様です。
自動コマンドやユーザー定義コマンドもそれを定義したスクリプトのコンテキストで実
行されます。そのコマンドからローカル関数を呼び出したり、ローカルマップを使用す
ることができます。
<SID> が正しく展開されないコンテキストで値が使われる場合は、expand() 関数を使
います:
スクリプト以外の場所で "<SID>" を使うとエラーになります。
複雑な処理をするスクリプトで、スクリプト番号が必要な場合は、次の関数で番号を得
られます:
関数やマップを一覧表示するときには "<SNR>" も表示されます。それらがどのように
定義されているのか調べるときに便利です。
コマンド:scriptnamesを使って、それまでに実行されたスクリプトとそのスクリプト
番号を確認できます。
これらはすべて {+eval が有効な場合のみ利用できます}
==============================================================================
4. ユーザー定義コマンド (User-defined command) user-commands
ユーザー独自のExコマンドを定義することできます。ユーザー定義コマンドはビルトイ
ンコマンドと同様に振る舞うことができます(範囲指定や、引数を取ることができます。
引数の入力では、ファイル名、バッファ名などを補完できます)。違いは、コマンドが
実行されると、通常の Ex コマンドに変換してから実行されるということです。
まずはユーザーマニュアルの40.2を参照してください。
E183 E841 user-cmd-ambiguous
すべてのユーザー定義コマンドは大文字で開始する必要があります。これはビルトイン
コマンドと混同しないようにするためです。特例として次のようなビルトインコマンド
もありますが:
:Next
:X
これらの名前もユーザー定義コマンドには使えません。":Print" コマンドも存在しま
すがこれは非推奨 (deprecated) になっており、上書きすることができます。
ユーザーコマンドの開始文字以外は、大文字であっても小文字であっても、数字であっ
てもかまいません。数字を使う場合、数字を引数に取る他のコマンドが曖昧になるかも
しれないので注意してください。例えば、"Cc2" コマンドは ":Cc2" という引数なしの
ユーザーコマンドとしても、"2" という引数を取った ":Cc" コマンドとしても解釈で
きます。これらの問題を避けるため、コマンド名と引数の間にスペースを挿入すること
を勧めます。
ユーザー定義コマンドを使うときに、コマンドの省略形を使うこともできます。しかし
ながら、その省略形が唯一でなければエラーが起きます。加えて、ビルトインコマンド
が常に優先されます。
例:
スクリプトの中で使うときは、ユーザー定義コマンドの完全な名前を使うようにしま
しょう。
:com[mand] :com :command
すべてのユーザー定義コマンドを一覧表示します。表示中の
行頭の文字は次の意味です:
! -bang 属性を持つコマンド
" -register 属性を持つコマンド
| -bar 属性を持つコマンド
b カレントバッファのローカルコマンド
(属性に関する詳細は下記参照)
一覧は :filter を用いてコマンド名でフィルタできま
す。例えば名前に "Pyth" を含む全コマンドを一覧するなら
ば次のようにします:
:com[mand] {cmd} {cmd} で始まるユーザー定義コマンドを一覧表示します。
:command-verbose
'verbose' がゼロ以外のときにコマンド一覧を表示すると、そのコマンドが最後に定義
された場所と補完の引数も表示します。例:
TOhtml 0 % :call Convert2HTML(<line1>, <line2>)
Last set from /usr/share/vim/vim-7.0/plugin/tohtml.vim
詳しくは :verbose-cmd を参照してください。
E174 E182
:com[mand][!] [{attr}...] {cmd} {repl}
ユーザー定義コマンドを定義します。コマンド名は {cmd}
でそれを置き換えるテキストが {repl} です。{attr} はコ
マンド属性(下記参照)です。既にコマンドが存在している場
合はエラーになります。! を指定した場合は再定義されま
す。1つ例外があります: スクリプトを再読み込みする場合、
そのスクリプトで以前に定義されていたコマンドは、静かに
置き換えられます。
:delc[ommand] {cmd} :delc :delcommand E184
ユーザー定義コマンド {cmd} を削除します。
これはコマンドの一覧表示中には許可されません。例えばタ
イマーから呼ぶなど。E1311
:delc[ommand] -buffer {cmd} E1237
カレントバッファで定義されたユーザー定義コマンド {cmd}
を削除します。
:comc[lear] :comc :comclear
すべてのユーザー定義コマンドを削除します。
コマンド属性
command-attributes
ユーザー定義コマンドは、他のビルトインコマンドと同様に扱われます。引数や範囲も
指定できます。引数の入力時にはファイル名やバッファ名などを補完することができま
す。どのように動作するかはコマンドを定義するときに指定したコマンド属性に依存し
ます。
ユーザーコマンドをスクリプトで定義するときは、スクリプトにローカルな関数を呼
び、スクリプトにローカルなマッピングを使うことができます。ユーザーがそのユー
ザーコマンドを実行すると、そのスクリプトが定義されたコンテキストで実行されま
す。これはコマンド内で <SID> が使われているときに重要となります。
たくさんの属性がありますが、それらは、引数の扱い方、補完の種類、範囲指定の仕
方、特殊なケース、の4つの分野に分けることができます。以下、分野別に説明しま
す。
引数の扱い方
E175 E176 :command-nargs
属性を指定しなかった場合、ユーザー定義コマンドは引数を取りません(引数が与えら
れた場合はエラーになります)。-nargs属性を指定すると、ユーザー定義コマンドが引
数指定できるようになります。次の属性が指定できます:
-nargs=0 引数を取らない (デフォルト)
-nargs=1 1個の引数が必要 (空白で区切られない)
-nargs=* いくつでも引数を取れる (0個以上)
空白で区切られる
-nargs=? 0 もしくは 1 個の引数が取れる
-nargs=+ 引数が必ず必要。数はいくつでもよい
引数は (エスケープされていない) スペースやタブ文字で区切られます。ただし、引数
を 1 つだけ取る場合は空白は引数の一部として解釈されます。
Note: 引数は Vim script の式としてではなく、テキストとして解釈されることに注意
してください。具体的な例を上げると、"s:var" を引数として渡すと、そのコマンドを
実行したスクリプトのローカル変数ではなく、そのコマンドを定義したスクリプトの
ローカル変数が使用されます。例:
script1.vim:
代わりに関数呼び出しを使ってください。
補完の動作
:command-completion E179 E180 E181
:command-complete
属性を指定しない場合、ユーザー定義コマンドの入力時に引数は補完されません。下記
の属性のうちいずれか1つを指定することで、引数が補完されるようになります。
-complete=arglist 引数リスト内のファイル名
-complete=augroup 自動コマンドのグループ
-complete=behave :behave サブオプション
-complete=breakpoint :breakadd サブオプション
-complete=buffer バッファ
-complete=color カラースキーム
-complete=command Ex コマンド(と、引数)
-complete=compiler コンパイラ
-complete=cscope :cscope サブオプション
-complete=diff_buffer 差分バッファ
-complete=dir ディレクトリ
-complete=dir_in_path 'cdpath' 内のディレクトリ
-complete=environment 環境変数
-complete=event 自動コマンドのイベント
-complete=expression Vimの式
-complete=file ファイルとディレクトリ
-complete=file_in_path 'path' 内のファイルとディレクトリ
-complete=filetype ファイルタイプ名 'filetype'
-complete=function 関数
-complete=help ヘルプの主題
-complete=highlight ハイライトグループ
-complete=history :history サブオプション
-complete=keymap キーボードマッピング
-complete=locale ロケール名 (locale -a の出力)
-complete=mapclear バッファ引数
-complete=mapping マップ
-complete=menu メニュー
-complete=messages :messages サブオプション
-complete=option オプション
-complete=packadd オプショナルパッケージの pack-add 名
-complete=runtime 'runtimepath' 内のファイルとディレクトリ
-complete=scriptnames 読み込まれたスクリプト
-complete=shellcmd シェルコマンド
-complete=shellcmdline 最初はシェルコマンドで、後続はファイル名。
:!cmd と同じ動作である
-complete=sign :sign サブオプション
-complete=syntax シンタックスファイル名 'syntax'
-complete=syntime :syntime サブオプション
-complete=tag タグ
-complete=tag_listfiles CTRL-D を押した時にタグ、ファイル名を表示
-complete=user ユーザー名
-complete=var ユーザー変数
-complete=custom,{func} {func}によるユーザー定義の補完
-complete=customlist,{func} {func}によるユーザー定義の補完
補完するものがないとき(デフォルトは -nargs=0)に補完を指定すると E1208 になり
ます。
Note: いくつかの補完方法は環境変数を展開します。
ユーザー定義の補完
:command-completion-custom
:command-completion-customlist E467 E468
補完方法に "custom,{func}"、"customlist,{func}" を指定すると独自の補完を使用で
きます。{func}には次のような関数を指定します。
すべての引数を使う必要はありません。関数の戻り値として、補完候補のリストを返し
てください。
"custom" を使った場合は、補完候補のリストを一つずつ改行で区切ってください。
E1303
"customlist" を使った場合は、補完候補のリストを List で返してください。リス
ト中の文字列以外の変数は無視されます。
引数には次の意味があります:
ArgLead すでに入力されている補完対象の文字列
CmdLine コマンドライン全体
CursorPos カーソル位置 (バイト単位のインデックス)
これらの引数を使えば文脈を判断することができるでしょう。"custom" を使った場合、
補完候補のリストからArgLeadにそぐわない候補(ArgLeadで始まらない文字)を取り除く
必要はありません。Vimは補完関数を実行した後に自身の正規表現エンジンでふさわし
くない候補を取り除きます、おそらくその方がほとんどの場面で有用です。
'wildoptions' が "fuzzy" を含む場合、候補はファジーマッチ fuzzy-matching を
使用してフィルタされます。"customlist" 引数の場合、Vim は返された補完候補をフィ
ルタしないので、ユーザーが指定した関数が候補をフィルタする必要があります。
次の例はFingerコマンドでユーザー名を補完します
次の例では、'path' に指定されたディレクトリのファイル名を補完しています:
この例はファイル名にスペースが含まれていると機能しません!
範囲指定
E177 E178 :command-range :command-count
属性を指定しない場合、ユーザー定義コマンドは行番号による範囲指定を受け付けませ
ん。-range属性を指定して、コマンドが範囲指定を受け付けるようにできます。任意の
カウント値を取るようにすることもできます。この場合、行番号の位置(:splitコマ
ンドのように。-range=N)で指定するか、"count" 引数(:Nextコマンドのように。
-count=N)で指定します。カウント指定は <count> で取得できます。
次の属性が利用できます:
-range 範囲指定が可能になります、無指定時は現在行
-range=% 範囲指定が可能になります、無指定時はファイル全体(1,$)
-range=N カウント(無指定時はN)を行番号位置に指定できます
(例 :split)。行番号に 0 を指定可能になる。
-count=N カウント(無指定時はN)を行番号位置か、初期化引数に指定でき
ます (例 :Next)。
-count -count=0 と同じです
Note: -range=Nと-count=Nは相互に排他的であるということに注意してください。どち
らか一方のみを指定することができます。
:command-addr
範囲指定には .、$、% といった特殊文字を含むことができ、それぞれ現在行、最終行、
バッファ全体を表します。これらは引数、(ロードされた)バッファ、ウィンドウ及び
タブページに関連付けすることができます。
次の値を利用できます (2列目は一覧表示で使われる短い名前です):
-addr=lines 行 (-range のデフォルトです)
-addr=arguments arg 引数
-addr=buffers buf バッファ (ロードされていないバッファも)
-addr=loaded_buffers load ロードされたバッファ
-addr=windows win ウィンドウ
-addr=tabs tab タブページ
-addr=quickfix qf quickfix のエントリ
-addr=other ? 他の種類の範囲; "lines" をつけるのと同様に".",
"$", "%" が使えます (-count のデフォルトです)
特殊なケース
:command-bang :command-bar
:command-register :command-buffer
:command-keepscript
特殊なケースがいくつかあります:
-bang コマンドは!修飾子を取ることができます(:qや:wのように)
-bar コマンドは "|" を使用して別のコマンドを続けて実行すること
ができます。引数に "|" を含めることはできなくなります。" が
コメントの開始になってしまうことにも注意してください。
-register コマンドの1つ目の引数にレジスタ名を指定することができます
(:del、:put、:yankのように)。
-buffer コマンドはカレントバッファでのみ利用できます。
-keepscript 詳細メッセージにユーザーコマンドが定義された場所は使用せ
ず、ユーザーコマンドが呼び出された場所を使用します。
ユーザー定義コマンドの定義に-countや-registerが指定された場合に、その省略可能
な引数が与えられた場合、それは引数リストから削除され、それぞれの引数に対応する
特別な文字列が利用できるようになります。
Note これらの引数は省略できますが、これは廃止される機能です。新しいスクリプト
では完全な名前を使用して下さい。
置き換えテキスト
:command-repl
引数 {repl} は通常は1つの長い文字列で、分割のコマンド "|" と合せて利用できま
す。特殊な場合として引数が "{" であるなら、"}" で始まる行までのそれ以降の行が
利用され Vim9 の文法が適用されます。
例:
"{" の前に空白が必要です。ネストはサポートされず、インライン関数は使用できませ
ん。式の引数を持つコマンドなど、引数に "|" が出現する可能性のあるコマンドは、
"|" の後に別のコマンドを続けることはできません。
コマンドが Vim9 script (:vim9script で始まるスクリプトか :def 関数の中) で
定義されている場合、{repl} は Vim9 script 内で実行されます。つまりこれは、コマ
ンドがどこで使われたかではなく、どこで定義されたかに依存します。
ユーザー定義コマンドでは、<...>表記を使った特別な文字列 {repl} を使用できます。
その文字列はコマンドラインに入力された実際の引数に置き換えられます。その他のテ
キストは変更されません。そして特別な文字列を実際の引数で置換したものがExコマン
ドとして実行されます。<> 表記が置き換えられないようにするには、最初の < の代わ
りに <lt> を使ってください。例えば、"<bang>" をリテラル文字として使うには
"<lt>bang>" とします。
次のものを使用できます
<line1>
<line1> コマンド範囲の最初の行
<line2>
<line2> コマンド範囲の最後の行
<range>
<range> コマンド範囲を指定するために使われた要素の数: 0, 1 もしくは 2
<count>
<count> 与えられたカウント('-range' と '-count' 属性で記述されている)
<bang>
<bang> ('-bang' 属性を参照) コマンドが ! 修飾子付きで実行された場合に
! に置換されます。指定なしの場合は空文字列になります。
<mods> <q-mods> :command-modifiers
<mods> 指定されている場合はコマンド修飾子。されていない場合は何も展開
しません。対応している修飾子は以下の通り:
:aboveleft, :belowright,
:botright, :browse, :confirm, :hide, :horizontal,
:keepalt, :keepjumps, :keepmarks, :keeppatterns,
:leftabove, :lockmarks, :noautocmd, :noswapfile,
:rightbelow, :sandbox, :silent, :tab, :topleft,
:unsilent, :verbose, 加えて :vertical.
Note :filter には対応していないことに注意してください。
例:
<reg> <register>
<reg> ('-register' 属性を参照) レジスタ名に置換されます。指定なしの
場合は空文字列になります。<register>も同義です。
<args>
<args> 与えられた通りのコマンド引数(上記の通り、カウントやレジスタが
指定された場合は<args>に含まれません)。
<lt> 1つの '<' (小なり)文字。特別な文字列を文字どおりに使用したい場
合に必要となります。例えば<bang>を得るには<lt>bang>とします。
<q-args>
特別な文字列の始めの2文字が "q-" なら(例えば<q-args>)、引数は式で使えるように
クォートされます("で囲まれる)。これは引数を1つの値として扱います。引数がない場
合は <q-args> は空文字列になります。下記 q-args-example を参照してください。
<f-args>
ユーザー定義コマンドの引数を関数に渡すには、<f-args>("function args")が利用で
きます。これはコマンドの引数をスペースやタブ文字で区切り、それぞれの引数を別々
にクォート("で囲む)し、コンマで区切ったリストにして<f-args>と置き換えます。下
のMycmdの例をご覧下さい。引数がない場合は <f-args> は取り除かれます。
<f-args> の引数にスペースを含めるには、バックスラッシュを前置します。<f-args>
では二つのバックスラッシュ (\\) は一つのバックスラッシュに置換されます。スペー
スとバックスラッシュ以外の文字に付いているバックスラッシュはそのまま使われま
す。下記 f-args-example も参照してください。要約:
コマンド <f-args>
XX ab 'ab'
XX a\b 'a\b'
XX a\ b 'a b'
XX a\ b 'a ', 'b'
XX a\\b 'a\b'
XX a\\ b 'a\', 'b'
XX a\\\b 'a\\b'
XX a\\\ b 'a\ b'
XX a\\\\b 'a\\b'
XX a\\\\ b 'a\\', 'b'
XX [nothing]
Note "引数無し" の状況を扱う場合、関数が引数無しでも呼び出せるようにしなければ
ならないことに注意してください。コンパイル済み関数の場合、可変引数が使えます。
vim9-variable-arguments 参照。
ユーザーコマンドの例
f-args-example
ユーザー関数を呼ぶには (<f-args>の例)
次のように実行された場合は:
q-args-example
より現実的な例:
Allargsコマンドは、引数としてどのVimコマンドでも取ることができ、引数リスト
argument-listのすべてのファイルに対して与えられたコマンドを実行します。使い
方の例 ("e" フラグをつけてエラーを無視しており、また "update" コマンドで変更さ
れたバッファを書き込んでいるので注意してください):
vim:tw=78:ts=8:noet:ft=help:norl:
VIMリファレンスマニュアル by Bram Moolenaar
キーマップ、短縮入力、ユーザー定義コマンドについて。
ユーザーマニュアルの05.4、24.7、40.1でこの機能について紹介しています。
1. マップ key-mapping
1.1 マップコマンド :map-commands
1.2 特別な引数 :map-arguments
1.3 マップとモード :map-modes
1.4 マップの一覧表示 map-listing
1.5 特殊キーのマップ :map-special-keys
1.6 特殊文字 :map-special-chars
1.7 マップに使うキー map-which-keys
1.8 例 map-examples
1.9 マップを使う map-typing
1.10 Altキーを使ったマップ :map-alt-keys
1.11 Metaキーを使ったマップ :map-meta-keys
1.12 superキーまたはcommandキーのマップ :map-super-keys
1.13 modifyOtherKeys モードのマップ modifyOtherKeys
1.14 Kitty キーボードプロトコルを使ったマップ kitty-keyboard-protocol
1.15 オペレータの作成 :map-operator
2. 短縮入力 abbreviations
3. ローカルマップとローカル関数 script-local
4. ユーザー定義コマンド user-commands
==============================================================================
1. マップ (Key mapping) key-mapping mapping macro
マップは入力キーの動作を変更するために使われます。一般的にはファンクションキー
にコマンドを割り当てるのに使われます。例:
:map <F2> a<C-R>=strftime("%c")<CR><Esc>
このマップはカーソルの位置に現在の日時を挿入します。(<F2>などは<>表記法を参照)
1.1 マップコマンド :map-commands
マップを新しく作成、削除、一覧表示するコマンドがあります。マップコマンドの種類
とモードの関係については map-overviewを参照してください。
{lhs} left-hand-side (左辺値) の略 {lhs}
{rhs} right-hand-side (右辺値) の略 {rhs}
:map {lhs} {rhs} mapmode-nvo :map
:nm[ap] {lhs} {rhs} mapmode-n :nm :nmap
:vm[ap] {lhs} {rhs} mapmode-v :vm :vmap
:xm[ap] {lhs} {rhs} mapmode-x :xm :xmap
:smap {lhs} {rhs} mapmode-s :smap
:om[ap] {lhs} {rhs} mapmode-o :om :omap
:map! {lhs} {rhs} mapmode-ic :map!
:im[ap] {lhs} {rhs} mapmode-i :im :imap
:lm[ap] {lhs} {rhs} mapmode-l :lm :lma :lmap
:cm[ap] {lhs} {rhs} mapmode-c :cm :cmap
:tma[p] {lhs} {rhs} mapmode-t :tma :tmap
キー入力 {lhs} を {rhs} に割り当てます。作成したマップ
は、マップコマンドに対応したモードで使用できます。マッ
プが使用されたときに {rhs} が調べられ、再マップされま
す。マップを入れ子にしたり再帰的にすることができます。
Note: 空白は有効なノーマルモードのコマンドであるため、
末尾の空白は {rhs} に含まれます。
map-trailing-white を参照。
:nore :norem
:no[remap] {lhs} {rhs} mapmode-nvo :no :noremap :nor
:nn[oremap] {lhs} {rhs} mapmode-n :nn :nnoremap
:vn[oremap] {lhs} {rhs} mapmode-v :vn :vnoremap
:xn[oremap] {lhs} {rhs} mapmode-x :xn :xnoremap
:snor[emap] {lhs} {rhs} mapmode-s :snor :snore :snoremap
:ono[remap] {lhs} {rhs} mapmode-o :ono :onoremap
:no[remap]! {lhs} {rhs} mapmode-ic :no! :noremap!
:ino[remap] {lhs} {rhs} mapmode-i :ino :inor :inoremap
:ln[oremap] {lhs} {rhs} mapmode-l :ln :lnoremap
:cno[remap] {lhs} {rhs} mapmode-c :cno :cnor :cnoremap
:tno[remap] {lhs} {rhs} mapmode-t :tno :tnoremap
キー入力 {lhs} を {rhs} に割り当てます。作成したマップ
は、マップコマンドに対応したモードで使用できます。
{rhs} は再マップされないので、マップが入れ子になったり
再帰的になることはありません。コマンドを再定義するとき
によく使われます。
Note: {rhs} 内のキーも、i_CTRL-] と c_CTRL-] を除
き、短縮入力をトリガーしません。
Note: {rhs} に <Plug> が表れる場合は再マップが許可され
ていなくてもその部分には常に適用{訳注:再マップ}されま
す。
:unm[ap] {lhs} mapmode-nvo :unm :unmap
:nun[map] {lhs} mapmode-n :nun :nunmap
:vu[nmap] {lhs} mapmode-v :vu :vunmap
:xu[nmap] {lhs} mapmode-x :xu :xunmap
:sunm[ap] {lhs} mapmode-s :sunm :sunmap
:ou[nmap] {lhs} mapmode-o :ou :ounmap
:unm[ap]! {lhs} mapmode-ic :unm! :unmap!
:iu[nmap] {lhs} mapmode-i :iu :iunmap
:lu[nmap] {lhs} mapmode-l :lu :lunmap
:cu[nmap] {lhs} mapmode-c :cu :cun :cunmap
:tunma[p] {lhs} mapmode-t :tunma :tunmap
マップコマンドに対応したモードの {lhs} というマップを
削除します。他のモードのマップは残ります。
{lhs} がマッピングの {rhs} にマッチするときも機能しま
す。これは略語が適用された場合に使用します。
Note: 末尾の空白は {lhs} に含まれます。
map-trailing-white を参照。
:mapc[lear] mapmode-nvo :mapc :mapclear
:nmapc[lear] mapmode-n :nmapc :nmapclear
:vmapc[lear] mapmode-v :vmapc :vmapclear
:xmapc[lear] mapmode-x :xmapc :xmapclear
:smapc[lear] mapmode-s :smapc :smapclear
:omapc[lear] mapmode-o :omapc :omapclear
:mapc[lear]! mapmode-ic :mapc! :mapclear!
:imapc[lear] mapmode-i :imapc :imapclear
:lmapc[lear] mapmode-l :lmapc :lmapclear
:cmapc[lear] mapmode-c :cmapc :cmapclear
:tmapc[lear] mapmode-t :tmapc :tmapclear
マップコマンドに対応したモードのすべてのマップを削除し
ます。
バッファローカルなマップを削除するには <buffer> 引数を
付けてください :map-<buffer>。
警告: Mac の標準マップ mac-standard-mappings と
MS-DOS の標準マップ dos-standard-mappings も削除され
ます。
:map mapmode-nvo
:nm[ap] mapmode-n
:vm[ap] mapmode-v
:xm[ap] mapmode-x
:sm[ap] mapmode-s
:om[ap] mapmode-o
:map! mapmode-ic
:im[ap] mapmode-i
:lm[ap] mapmode-l
:cm[ap] mapmode-c
:tma[p] mapmode-t
マップコマンドに対応したモードのすべてのマップを一覧表
示します。Note: ":map" と ":map!" は複数のモードを表示
できるのでよく使われます。
:map {lhs} mapmode-nvo :map_l
:nm[ap] {lhs} mapmode-n :nmap_l
:vm[ap] {lhs} mapmode-v :vmap_l
:xm[ap] {lhs} mapmode-x :xmap_l
:sm[ap] {lhs} mapmode-s :smap_l
:om[ap] {lhs} mapmode-o :omap_l
:map! {lhs} mapmode-ic :map_l!
:im[ap] {lhs} mapmode-i :imap_l
:lm[ap] {lhs} mapmode-l :lmap_l
:cm[ap] {lhs} mapmode-c :cmap_l
:tma[p] {lhs} mapmode-t :tmap_l
マップコマンドに対応したモードの {lhs} で始まるマップ
を一覧表示します。
マップコマンドを使うと、単キーまたは複数キーの入力を別の文字列にマップできま
す。ファンクションキーにコマンド列を割り当てたり、あるキーを別のキーに変換した
りできます。マップを保存、復元する方法については :mkexrc を参照してくださ
い。
map-ambiguous
二つのマップがあって、両方とも同じ文字で始まっている場合、どちらを使用するかが
あいまいになってしまいます。例:
:imap aa foo
:imap aaa bar
"aa" と入力したとき、"aa" と "aaa" のどちらを使用するかを決定するためには、次:imap aaa bar
の文字が必要になります。そのため、"aa" が入力された時点ではまだマップは適用さ
れず、次の入力まで待機状態になります。例えば空白文字を入力すれば "foo" と空白
文字が挿入されます。"a" を入力すれば "bar" が挿入されます。
末尾空白
map-trailing-white
このunmapコマンドは動作しません:
:map @@ foo
:unmap @@ | print
:unmap @@ | print
なぜなら unmap "@@ " を試行するとき、コマンド区切りの "|" の前の空白を含んでい
るためです。他の末尾空白の例として:
unmap @@
unmap @@ # Vim9 script コメント
unmap @@ " 旧来のスクリプトのコメント
unmap @@ # Vim9 script コメント
unmap @@ " 旧来のスクリプトのコメント
unmap @@ の末尾が空白文字のためエラーになりますが、これは見えないので特定す
るのが非常に困難です。
一般的な解決策はマップしたキーの後の右にコマンド区切りの "|" を置くことです。
その後に空白とコメントを続けます:
unmap @@| # Vim9 script コメント
unmap @@| " 旧来のスクリプトのコメント
unmap @@| " 旧来のスクリプトのコメント
1.2 特別な引数 :map-arguments
引数に "<buffer>"、"<nowait>"、"<silent>"、"<special>"、"<script>"、"<expr>"、
"<unique>" を指定できます。マップコマンドの直後 (他の引数の前) に置いてくださ
い。
:map-local :map-<buffer> :map-buffer
E224 E225
カレントバッファだけで使用できるマップを作成するには、マップコマンドの引数に
"<buffer>" を指定します。例:
:map <buffer> ,w /[.,;]<CR>
この場合、他のバッファで、",w" に対して別の操作を割り当てることができます: :map <buffer> ,w /[#&!]<CR>
バッファローカルなマップは通常のマップよりも優先して使用されます。長いグローバルなマップが存在する場合に短いローカルなマップが影響を受けないようにするには下
記の <nowait> を参照して下さい。
"<buffer>" はマップを削除するときにも指定できます:
:unmap <buffer> ,w
:mapclear <buffer>
バッファローカルなマップはそのバッファが削除されるときにいっしょに消去されま:mapclear <buffer>
す。アンロード(:bunload)では消去されません。ローカルオプションと同じです。
また、map-precedence を参照して下さい。
:map-<nowait> :map-nowait
"," にバッファローカルなマップを定義する場合に "," から始まるグローバルなマッ
プがあるかもしれません。その場合はVimが "," のマップか、あるいはより長いマップ
を使用するかどうか知るために別の文字を入力する必要があります。これを避けるには
引数に <nowait> を追加します。そしてそのマップは一致する場合に使用され、Vimは
それ以上入力される文字を待ちません。しかし、既に文字が入力されていた場合はそれ
が使われます。
Note: これが動作するのは <nowait> なマッピングが完全にマッチし、なんらかの部分
マッチの前に見付かるときです。これが動作するのは:
- バッファローカルなマッピングで唯一のマッチがあるとき。なぜなら常にグローバル
なマッピングより先に見付かるからです。
- これとは別のバッファローカルなマッピングが部分マッチするが、より早く定義され
ているとき (最後に定義したマッピングが最初に見付かる)。
:map-<silent> :map-silent
実行するコマンドがコマンドラインに表示されないようにするには、マップコマンドの
引数に "<silent>" を指定します。例:
:map <silent> ,h /Header<CR>
このマップを使用するとき、検索文字列はコマンドラインに表示されません。しかし、実行されたコマンドが出力するメッセージは表示されてしまいます。それを静かにさせ
るには ":silent" を使います:
:map <silent> ,h :exe ":silent normal /Header\r"<CR>
Note コマンドの効果も静かにさせられることに注意してください。例えば、このマップがコマンドライン補完の別のエントリを選択するとき、それは表示されません。
それでもまだ、例えば inputdialog() のプロンプトなどは表示されます。
"<silent>" は短縮入力にも使えますが、コマンドラインで使うと正しく表示されなく
なります。
:map-<special> :map-special
'cpoptions' に "<" フラグが入っている場合でも、<> 表記を使って特殊キーを記述で
きます。'cpoptions' を設定することで副作用を発生させたくない場合に使ってくださ
い。例:
:map <special> <F12> /Header<CR>
:map-<script> :map-script
マップや短縮入力を定義するときに "<script>" 引数を指定すると、{rhs} の中の
"<SID>" で始まるスクリプトローカルなマップだけが再マップされます。別の場所で
マップが定義されていても (例えば mswin.vim で CTRL-V にマップが定義されていて
も)、その影響を避けることができます。その場合でも同じスクリプトで定義された
マップは使うことができます。
Note: ":map <script>" と ":noremap <script>" の動作は同じです。コマンド名より
"<script>" の効果が優先されます。再マップが制限されることが明確になるため
":noremap <script>" を使う方がいいでしょう。
:map-<unique> :map-unique E226 E227
マップや短縮入力を定義するときに "<unique>" 引数を指定すると、同じ名前のものが
すでに定義されていた場合に、コマンドは失敗します。例:
:map <unique> ,w /[#&!]<CR>
バッファローカルのマップを定義するときは、通常のマップも検査の対象となります。失敗する例:
:map ,w /[#&!]<CR>
:map <buffer> <unique> ,w /[.,;]<CR>
すでにマップされている機能をそのままに、新たにマップを設定したい場合は、:map <buffer> <unique> ,w /[.,;]<CR>
maparg() を参照してください。
:map-<expr> :map-expression
マップや短縮入力を定義するときに "<expr>" 引数を指定すると、引数が式 (スクリプ
ト) として扱われます。マップが実行されたときに、式が評価され、その値が {rhs}
として使われます。例:
:inoremap <expr> . <SID>InsertDot()
s:InsertDot() 関数の戻り値が挿入されます。カーソルの前のテキストをチェックして、ある条件に一致するなら omni 補完を開始する、というようなことができます。
グローバルな名前空間の汚染を回避するには、スクリプトローカル関数を利用すること
が望しいです。RHS内に <SID> を使ってマッピングが定義されたスクリプトを見付けら
れるようにします。
短縮入力では、入力されて短縮入力展開のトリガーとなった文字が v:char にセット
されます。これを使って {lhs} の展開方法を決めることもできます。自分で v:char
を挿入したり変更したりすべきではありません。
マッピングで何も実行させない場合は、評価結果が空文字列になるようにします。も
し、なんからの{訳注:状態などの}変更で Vim がメインループを通過する必要があるも
のなら (例えば、画面の更新など)、"\<Ignore>" を返すようにします。
これは、"何もしない" と同義ですが Vim はループから入力待ちに戻ります。例:
func s:OpenPopup()
call popup_create(... arguments ...)
return "\<Ignore>"
endfunc
nnoremap <expr> <F3> <SID>OpenPopup()
call popup_create(... arguments ...)
return "\<Ignore>"
endfunc
nnoremap <expr> <F3> <SID>OpenPopup()
前のコマンドが実行される前に、先行入力を探す時に式が評価されることがあることを
覚えておいてください。例:
func StoreColumn()
let g:column = col('.')
return 'x'
endfunc
nnoremap <expr> x StoreColumn()
nmap ! f!x
g:column に "f!" 実行前の値がある、つまり "x" が評価されるのが "f!" の実行前でlet g:column = col('.')
return 'x'
endfunc
nnoremap <expr> x StoreColumn()
nmap ! f!x
あることに気付くでしょう。
これは評価のマッピングの文字の前に <Ignore> を挿入することで解決できます:
nmap ! f!<Ignore>x
Vim9 script 内でのマッピング定義時は、式がそのスクリプトのコンテキストで評価
されます。これは式内でスクリプトローカルの要素についてアクセスできることを意味
します。
副作用に注意してください。式は文字の取得中に評価されるため、簡単に異常動作を起
こせてしまいます。そのため、次のものは制限されます:
- バッファのテキストの変更 textlock。
- 他のバッファの編集。
- :normal コマンド。
- カーソルの移動は可能ですが、後で元に戻されます。
以上のことを実現したい場合は、そのためのコマンド文字列を返してください。もしく
は代わりに <Cmd> マッピングを使用してください。
getchar() が使用できます。先行入力があればそれが消費されます。例えば次のような
マップを定義します:
inoremap <expr> <C-L> nr2char(getchar())
inoremap <expr> <C-L>x "foo"
そして CTRL-L を押してみます。すぐには何も起きません。どのマップを使うかを決定inoremap <expr> <C-L>x "foo"
するためには文字がもう一つ必要です。次に 'x' を押すと後者のマップが使われ、
"foo" が挿入されます。他のキーを押すと前者のマップが使われ、その文字が
getchar() によって取得され、返されます。
例を示します。リスト番号を自動的に増加させつつ挿入します:
let counter = 0
inoremap <expr> <C-L> ListItem()
inoremap <expr> <C-R> ListReset()
inoremap <expr> <C-L> ListItem()
inoremap <expr> <C-R> ListReset()
func ListItem()
let g:counter += 1
return g:counter .. '. '
endfunc
let g:counter += 1
return g:counter .. '. '
endfunc
func ListReset()
let g:counter = 0
return ''
endfunc
let g:counter = 0
return ''
endfunc
CTRL-L で次の番号を挿入し、CTRL-R で番号をリセットします。CTRL-R は空文字列を
返すので、何も挿入されません。
Note: テキストの末尾以外で 0x80 をシングルバイトとして使った場合、それは機能し
ません。特殊キーとして認識されます。
<Cmd> :map-cmd
特別な文字列 <Cmd> は "コマンドマッピング" を開始し、モードを変化させずにコマ
ンドを直に実行します。マッピングの {rhs} で ":...<CR>" を使うなら、代わりに
"<Cmd>...<CR>" が使えます。例:
noremap x <Cmd>echo mode(1)<CR>
これはビジュアルおよびオペレータ待機モードでの :<C-U>、挿入モードでの
<C-O>: より柔軟で、なぜなら常にノーマルモードへ移行する代わりにコマンド実行
が現在のモードのままでだからです。ビジュアルモードでは gv での{訳注:選択の}
維持のトリックが不要です。コマンドをコマンドラインモードで直に動かせます (これ
でないならタイマーでのハックが必要です)。
挿入モードを跨いで <Cmd> を使う例:
nnoremap <F3> aText <Cmd>echo mode(1)<CR> Added<Esc>
<expr> マッピングとは異なり、<Cmd> コマンドに特別な制約はありません: あたかも
(制約のない) autocommand が呼び出されたかのように実行されます。
<ScriptCmd>
<ScriptCmd> は <Cmd> に似ていますが、コマンド実行時のコンテキストはマッピング
が定義された箇所のスクリプトのものが設定されます。これは Vim9 script で特に
便利です。また、インポートでの参照でも動作するので、autoload されるかもしれな
いスクリプトを使用するプラグインで便利です:
vim9script
import autoload 'implementation.vim' as impl
nnoremap <F4> <ScriptCmd>impl.DoTheWork()<CR>
import autoload 'implementation.vim' as impl
nnoremap <F4> <ScriptCmd>impl.DoTheWork()<CR>
<F4> がどこで入力されたとしても、"impl" のインポートはマッピングが定義された
場所のスクリプトのコンテキストで検出されます。この例のように autoload のイン
ポートをする場合、マッピングが定義された時点ではなく、一度 <F4> が入力された時
にのみ "implementation.vim" スクリプトがロードされます。
<ScriptCmd> がない時は "s:impl" は "E121: Undefined variable" という結果になり
ます。
Note:
- <Cmd> と <ScriptCmd> はモード変更を回避するので、ユーザーの介入を必要としな
いため、CmdlineEnter と CmdlineLeave イベントをトリガーしません。
- 同じ理由により、<C-R><C-W> のようなキーコード keycodes は通常の、マッピン
グされていないキーとして解釈されます。
- コマンドは echo されません、<silent> は不要です。
- {rhs} は、マッピングが再帰的であっても、短縮入力や他のマッピングの対象にはな
りません。
- ビジュアルモードでは、line('v') と col('v') を使って、ビジュアルエリアの
一端を取得でき、カーソルは反対の端にいます。
E1255 E1136
<Cmd> と <ScriptCmd> コマンドではマッピング定義の {rhs} が <CR> で終わる必要が
あります。Command-line に入ることはありません。{rhs} でリテラル <CR> を使用
するには、<lt> を使用します。
1.3 マップとモード :map-modes
mapmode-nvo mapmode-n mapmode-v mapmode-o
マップには 7 つの種類があります。
- ノーマルモード: ノーマルモードのコマンドを入力するとき。
- ビジュアルモード: ビジュアルモードのコマンドを入力するとき。
- 選択モード: ビジュアルモードに似ていますが入力したテキストによって選択範囲が
置換されます。
- オペレータ待機モード: オペレータを待機しているとき。("d"、"y"、"c"、などの
後)。omap-info 参照。
- 挿入モード: 置換モードでも使われます。
- コマンドラインモード: ":" もしくは "/" コマンドを入力したとき。
- 端末モード: 端末 :terminal バッファでの入力時。
例外として、ノーマルモードでカウント(コマンドの繰り返し回数)を入力しているとき
は、0 (ゼロ)に対するマップは適用されません。これは 0 がマップされていても、カ
ウントの指定でゼロを入力できるようにするためです。
map-overview map-modes
マップコマンドとモードの対応。詳細は以後に。
コマンド モード
:map :noremap :unmap ノーマル、ビジュアル、選択、オペレータ待機
:nmap :nnoremap :nunmap ノーマル
:vmap :vnoremap :vunmap ビジュアル、選択
:smap :snoremap :sunmap 選択
:xmap :xnoremap :xunmap ビジュアル
:omap :onoremap :ounmap オペレータ待機
:map! :noremap! :unmap! 挿入、コマンドライン
:imap :inoremap :iunmap 挿入
:lmap :lnoremap :lunmap 挿入、コマンドライン、Lang-Arg
:cmap :cnoremap :cunmap コマンドライン
:tmap :tnoremap :tunmap 端末ジョブ
{訳注: Lang-Argについては language-mapping を参照}
上記のマップコマンドの対応表:
map-table
モード | Norm | Ins | Cmd | Vis | Sel | Opr | Term | Lang |
コマンド +------+-----+-----+-----+-----+-----+------+------+
[nore]map | yes | - | - | yes | yes | yes | - | - |
n[nore]map | yes | - | - | - | - | - | - | - |
[nore]map! | - | yes | yes | - | - | - | - | - |
i[nore]map | - | yes | - | - | - | - | - | - |
c[nore]map | - | - | yes | - | - | - | - | - |
v[nore]map | - | - | - | yes | yes | - | - | - |
x[nore]map | - | - | - | yes | - | - | - | - |
s[nore]map | - | - | - | - | yes | - | - | - |
o[nore]map | - | - | - | - | - | yes | - | - |
t[nore]map | - | - | - | - | - | - | yes | - |
l[nore]map | - | yes | yes | - | - | - | - | yes |
コマンド モード
ノーマル ビジュアル+選択 オペレータ待機
:map :noremap :unmap :mapclear yes yes yes
:nmap :nnoremap :nunmap :nmapclear yes - -
:vmap :vnoremap :vunmap :vmapclear - yes -
:omap :onoremap :ounmap :omapclear - - yes
:nunmap は修道院の外でも使えます。{訳注: nunは修道女の意}
mapmode-x mapmode-s
いくつかのコマンドはビジュアルモードと選択モードの両方で機能しますが、そうでな
いコマンドもあります。「ビジュアル」という言葉がビジュアルモードと選択モードの
両方を指している場合が多々あるので注意してください。
Select-mode-mapping
NOTE: 選択モードで印字可能文字にマップを定義するとユーザーの混乱を招くかも
しれません。印字可能文字に対しては明示的に :xmap と :smap を使い分けるのがいい
でしょう。マップを定義したあとで :sunmap を使う方法もあります。
コマンド モード
ビジュアル 選択
:vmap :vnoremap :vunmap :vmapclear yes yes
:xmap :xnoremap :xunmap :xmapclear yes -
:smap :snoremap :sunmap :smapclear - yes
mapmode-ic mapmode-i mapmode-c mapmode-l
一部のコマンドは、挿入モードとコマンドラインモードの両方で使えますが、一部はそ
うではありません:
コマンド モード
挿入 コマンドライン Lang-Arg
:map! :noremap! :unmap! :mapclear! yes yes -
:imap :inoremap :iunmap :imapclear yes - -
:cmap :cnoremap :cunmap :cmapclear - yes -
:lmap :lnoremap :lunmap :lmapclear yes* yes* yes*
* もし 'iminsert' が 1 ならば、下記 language-mapping を参照してください。
オリジナルの Vi はノーマルモード、ビジュアルモード、オペレータ待機モード、でひ
とまとまり、挿入モード、コマンドラインモード、でさらにひとまとまりのマップを持
ち、それぞれ区別されていませんでした。そのため、Vim の ":map" と ":map!" コマ
ンドは複数のモードに対してマップを設定したり表示したりします。
Vim では ":nmap"、":vmap"、":omap"、":cmap"、":imap" を使い分けることで、それ
ぞれのモード別にマップを設定することができます。
mapmode-t
端末マップは、端末ウィンドウの中で動作しているジョブに対してキーが入力されたと
きに機能します。terminal-typing を参照してください。
omap-info
オペレータ待機マップを使うと、移動コマンドを定義できます。そして、オペレータと
組み合わせて使うことができます。簡単な例:
:omap { w
を定義した場合、"y{" が "yw" として、"d{" が "dw" として機能するようになります。
マップ適用時のカーソル位置を無視し、異なるテキストを選択するには、omap 内でビ
ジュアルモードを開始して対象となるテキストを選択してください。例えば、現在行の
関数名を選択するには次のようにします:
onoremap <silent> F :<C-U>normal! 0f(hviw<CR>
CTRL-U (<C-U>) を使って (Vimによって挿入される) 範囲指定を削除しています。ノーマルモードコマンドを使って、最初の '(' 文字を探し、その前にある単語を選択しま
す。通常はこれで関数名を選択できるでしょう。
あるマップをノーマルモードとビジュアルモードで使用し、そして、オペレータ待機
モードでは使用しないという場合は、3つのモードに対してマップを定義してからオペ
レータ待機モードのマップだけを削除します:
:map xx something-difficult
:ounmap xx
:ounmap xx
ビジュアルモードとオペレータ待機モードの場合や、ノーマルモードとオペレータ待機
モードの場合も同様にします。
language-mapping
":lmap" で定義したマップ(以下、言語マップ)は次の場面で利用できます:
- 挿入モード
- コマンドラインモード
- 検索パターンを入力するとき
- "r" や "f" などのコマンドに続いて文字を入力するとき
- input() の入力
大まかに説明すると、Vim コマンドとしてではなく、テキストの一部として入力するよ
うなときにはいつでも利用できます。"Lang-Arg" は別個のモードではなく、そのよう
な場面の総称です。
ある言語用の言語マップをロードするには、オプション 'keymap' を設定するのが
簡単です。45.5を参照してください。
挿入モードとコマンドラインモードでは CTRL-^ で言語マップの使用の有無を切り替
えることができますi_CTRL-^ c_CTRL-^。これらのコマンドは 'iminsert' オプショ
ンの値を変更します。(検索パターンの入力ではなく)コマンドラインに入力するときに
は CTRL-^ で切り替えるまで言語マップは無効になっています。挿入モードと検索パ
ターンでの使用状態は別々に記録されます。挿入モードの使用状態は "f" や "t" など
のコマンドで文字を入力するときにも使用されます。
言語マップは、既にマップが適用された文字には適用されません。言語マップは入
力された文字に対してのみ使用されます。これは、言語マップは文字が入力されたとき
に適用されたはずという想定によるものです。
1.4 マップの一覧表示 map-listing
マップを一覧表示したときの行頭の2文字は使用できるモードを表しています:
文字 モード
<Space> ノーマル、ビジュアル、選択、オペレータ待機
n ノーマル
v ビジュアル、選択
s 選択
x ビジュアル
o オペレータ待機
! 挿入、コマンドライン
i 挿入
l 挿入、コマンドライン、Lang-Argでの ":lmap" マップ
c コマンドライン
t 端末ジョブ
{訳注: Lang-Argについては language-mapping を参照}
{rhs} の直前に特殊な文字が表示されているものは次のことを意味します:
* 再マップされません
& スクリプトローカルなマップだけが再マップされます
@ バッファローカルなマップです。
{lhs} の後ろの最初の非空白文字から行末 (もしくは '|') までのすべての文字は
{rhs} の一部です。そのため {rhs} の末尾を空白文字にすることができます。
Note: ビジュアルモードのマップでは "'<" マークが使えます。これはカレントバッ
ファで選択されていた範囲の開始位置を示しています'<。
何がマッピングされているか調べるのに :filter コマンドを使うことができます。
パターンは {lhs} と {rhs} に対しては、生の形式で {訳注: 実際のキャラクターコー
ドを用いて} マッチします。
マッピングが一覧表示されている際に、例えばタイマーコールバックなどからマッピン
グを追加したりクリアすることはできません。 E1309
:map-verbose
'verbose' がゼロ以外の場合、検出および使用された 'keyprotocol' の値が最初の行
に表示されます。また、キーマップには、最後に定義された場所も表示されます。
例:
:verbose map <C-W>*
Kitty keyboard protocol: Cleared
n <C-W>* * <C-W><C-S>*
Last set from /home/abcd/.vimrc
Kitty keyboard protocol: Cleared
n <C-W>* * <C-W><C-S>*
Last set from /home/abcd/.vimrc
詳しくは :verbose-cmd を参照してください。
1.5 特殊キーのマップ :map-special-keys
特殊キーをマップに含めるのには次の 3 つの方法があります:
1. Vi 互換の方法: 生のキーコードをマップします。それはほとんどの場合 <Esc> で
始まるキーコード列です。このようなマップを入力するには、まず ":map " と入力
し、CTRL-V を押してからファンクションキーを押します。Note: そのキーのキー
コードが termcap(t_options) にある場合は、自動的に内部コードの形式に変換さ
れ、次の 2. のようなマップになります ('cpoptions' に 'k' フラグが指定されて
いる場合は除く)
2. ファンクションキーの内部コードを使います。そのようなマップを入力するには、
CTRL-K を押してからファンクションキーを押します。もしくは、
"#1"、"#2"、.. "#9"、"#0"、"<Up>"、"<S-Down>"、"<S-F7>"、などの形式で指定し
ます。(キーの表は key-notation 参照。<Up> 以下のすべてのキーを使うことが
できます)。1 から 10 までのファンクションキーは二つの方法で定義できます:
"#2" のような番号だけの方法と、"<F2>" という表記で指定する方法です。この両
方がファンクションキー 2 を表します。"#0" はファンクションキー 10 を表し、
't_f10' で定義されます。"#0" は、キーボードによってはファンクションキー 0に
なることがあります。'cpoptions' に '<' フラグが指定されている場合は、<>表
記は使えません。
3. termcap エントリを <t_xx> という形式で指定します。"xx" は termcap エントリ
の名前です。どんなエントリの文字列も使うことができます。例:
:map <t_F3> G
これはファンクションキー 13 を "G" にマップします。'cpoptions' に '<' フラグが指定されている場合は使えません。
2. と 3. の方法の利点は、異なる端末でもマップを修正する必要がないことです(ファ
ンクションキーは、同じ意味の内部コード、もしくは実際のキーコードに変換されま
す。使用している端末に依存しません。termcap が正しく設定されていれば、異なる端
末で同じマップを共有できます)。
詳細: まず Vim はキーボードから送られたキーコードがマップされているかどうかを
調べます。マップされていなければ、端末のキーコードかどうか調べます(参照
terminal-options)。端末コードであれば、内部コードで置き換えます。それからも
う一度、マップされているかどうかをチェックします (これにより内部コードをマップ
できます)。スクリプトファイルに書き込まれる内容は、どのように解釈されたかによ
ります。端末のキーコードがマップとして認識された場合は、キーコードそのものがス
クリプトファイルに書き込まれます。端末コードとして認識された場合は、内部コード
がスクリプトファイルに書き込まれます。
{訳注: > スクリプトファイルに書き込まれる...
おそらく -w の話。}
1.6 特殊文字 :map-special-chars
map_backslash map-backslash
Note: このドキュメントでは、マップや短縮入力を定義するときに、CTRL-V だけが特
殊な文字として触れられていますが、'cpoptions' が 'B' を含んでいない場合は、
バックスラッシュも CTRL-V と同様の特殊な働きをします。<> 表記も問題なく使用
できます。しかし、"<C-V>" を CTRL-V と同じように、(マップを入力するときに)次の
文字をエスケープする目的で使うことはできません。
バックスラッシュにマップしたり、バックスラッシュをそのまま {rhs} に使いたい場
合は、特別文字 "<Bslash>" を使います。マップを入れ子にした場合などにバックス
ラッシュを二重にする必要がなくなります。
map_CTRL-C map-CTRL-C
CTRL-C を {lhs} で使うことはできますが、それは Vim がキー入力を待機中のときだ
け機能します。Vim がビジー状態 (何かを実行中) のときは機能しません。Vim がビ
ジー状態の場合、CTRL-C は実行中のコマンドを中断します。
MS-Windows の GUI 環境では、CTRL-C にマップすることができるので、クリップボー
ドにコピーする機能を割り当てることができます。Vim の動作を中断するには
CTRL-Break を使います。
map_space_in_lhs map-space_in_lhs
{lhs} に空白文字を含めるには CTRL-V を前置してください (空白文字の前で CTRL-V
を二度押しで入力)。
map_space_in_rhs map-space_in_rhs
{rhs} を空白文字で開始するには "<Space>" を使ってください。Vi との互換性を完全
に保ちたい場合は <> 表記を使わずに、{rhs} の直前に CTRL-V (CTRL-V を二度押し
で入力)を前置してください。
map_empty_rhs map-empty-rhs
CTRL-V を1つだけ入力した後に (CTRL-Vを2度押しで入力) 何も入力しないことで空の
{rhs} を作ることもできます。残念ながらvimrcファイル内ではこの方法は使用できま
せん。
<Nop>
空のマップを作るには {rhs} に "<Nop>" を指定する方法が簡単です。これは <> 表
記を使えるようにしていれば動作します。例えば、ファンクションキー 8 は何もしな
い、としたい場合は次のようにします:
:map <F8> <Nop>
:map! <F8> <Nop>
:map! <F8> <Nop>
map-multibyte
マルチバイト文字をマップすることができます。ただし、マルチバイト文字の一部のバ
イトだけをマップすることはできません。それは次のような問題が起こるのを防ぐため
です:
:set encoding=latin1
:imap <M-C> foo
:set encoding=utf-8
latin1 環境で文字「Ã」(0xc3 または <M-C>) をマップしています。例えば、「á」:imap <M-C> foo
:set encoding=utf-8
(0xe1 または <M-a>) は UTF-8 では 0xc3 0xa1 の 2 バイトで表現されるので、0xc3
をマップしてしまうと á が入力できなくなってしまいます。
<Leader> mapleader
マップコマンドで特別な文字列 "<Leader>" を使用すると、その部分が変数
"g:mapleader" に設定された文字列で置き換わります。"g:mapleader" が空文字列のと
きや設定されていない場合にはバックスラッシュが使用されます。例:
map <Leader>A oanother line<Esc>
これは次のものと同じ意味です: map \A oanother line<Esc>
しかし次のように設定したあとでは (旧来のスクリプト): let mapleader = ","
あるいは (Vim9 script): g:mapleader = ","
次のものと同じ意味になります: map ,A oanother line<Esc>
Note: 変数 "g:mapleader" はマップを定義するときに使用されます。"g:mapleader"
を変更しても、すでに定義されているマップには影響しません。
<LocalLeader> maplocalleader
<LocalLeader> は <Leader> に似ていますが、"mapleader" ではなく
"maplocalleader" を使用します。<LocalLeader> はバッファローカルのマップに使用
するといいでしょう。例:
:map <buffer> <LocalLeader>A oanother line<Esc>
グローバルプラグインでは <Leader> を使用し、ファイルタイププラグインでは
<LocalLeader> を使用するといいでしょう。"mapleader" と "maplocalleader" の設定
は同じでも構いませんが、別の値を設定すれば、グローバルプラグインとファイルタイ
ププラグインのマップが重なる可能性が低くなります。設定例としては、"mapleader"
をバックスラッシュのままにしておいて、"maplocalleader" をアンダースコア (_) に
するなど。
map-<SID>
特別な文字列 "<SID>" を使ってスクリプトローカルなマップを定義できます。詳細は
<SID>を参照してください。
<Plug>
特別な文字列 "<Plug>" を使ってスクリプトの内部作業用のマップを定義できます。こ
れはどのキー入力にもマッチしません。プラグインを作成するときに便利です
using-<Plug>。
<MouseMove>
特別な文字列 "<MouseMove>" を使ってマウスの移動を取り扱えます。そのためには
'mousemoveevent' が有効になっている必要があります。現在、GUI でのみ動作します。
getmousepos() 関数がマウスの位置を取得するのに使えます。
<Char> <Char->
<Char> を使って、文字を10進数、8進数、16進数の数値指定でマップできます:
<Char-123> character 123
<Char-033> character 27
<Char-0x7f> character 127
<S-Char-114> character 114 ('r') shifted ('R')
これは 'keymap' ファイルで (マルチバイト) 文字を定義するのに便利です。表記は大
文字でも小文字でも構いません。
map-comments
マップコマンドでは '"' (ダブルクォート) も {lhs} や {rhs} の一部と見なされるた
め、マップコマンドの後ろにコメントを置くことはできません。しかし、|" を使うこ
とができます。これはコメント付きの空の新しいコマンドを開始するからです。
map_bar map-bar
'|' 文字は、マップコマンドと次のコマンドを分けるために使われるので、'|' 文字を
{rhs} に含めるには特殊な方法が必要です。
次の3つの方法があります:
方法 使用できる条件 例
<Bar> 'cpoptions'に'<'が含まれていない :map _l :!ls <Bar> more^M
\| 'cpoptions'に'b'が含まれていない :map _l :!ls \| more^M
^V| VimとViで常に使用できる :map _l :!ls ^V| more^M
(ここで ^V は CTRL-V を表します。一つの CTRL-V を挿入するには CTRL-V を二度押
しで入力します。この用途では、<>表記を使って "<C-V>" とすることはできません)。
'cpoptions' が標準設定のままなら、三つ全ての方法が使用できます。
'cpoptions' に 'b' が含まれている場合、"\|" は、'\' で終わるマップコマンドの後
に、別のコマンドが続いているとみなされます。これは Vi 互換ですが、他のコマンド
の場合を考えるとあまり論理的ではありません。
map_return map-return
マップに Ex コマンドを含める場合、そのコマンドラインを実行するために改行文字を
挿入する必要があります。これには <CR> を使うことが推奨されています(参照<>)。
例:
:map _ls :!ls -l %:S<CR>:echo "the end"<CR>
挿入モードやコマンドラインモードで、入力する文字がマップされないようにするに
は、その文字を入力する前に CTRL-V を (1回) 押してください。'paste' がオンの場
合には、挿入モードでマップを使用できません。
map-error
Note: マップを使用したときに、エラーが起きた場合 (エラーメッセージが出ます。
あるいはビープ音が出るかもしれません)、マップのまだ実行されていない部分は実行
されません。これはVi互換です。
Note: コマンド「@zZtTfF[]rm'`"v」と CTRL-X の引数にはマップは適用されません。
どのようなマップがあっても、レジスタやマークを指定できるようにするためです。
1.7 マップに使うキー map-which-keys
マップを定義するときに {lhs} に指定するキーを選ぶことができますが、Vim のコマ
ンドに使われているキーをマップしてしまうとそれらのコマンドを使用できなくなりま
す。そこで、いくつかの提案があります:
- ファンクションキー (<F2>、<F3>など) や Shift+ファンクションキー(<S-F1>、
<S-F2>など) を使用する。<F1> には既にヘルプコマンドが割り当てられています。
- Alt キー または Meta キーと任意のキーを押す。あなたのキーボードのアクセント
記号付き文字の使用頻度に依存します。 :map-alt-keys
- "_" や "," などの文字と別の文字を組み合わせて使用する。コマンド "_" と"," は
すでに存在していますが (_と,を参照)、使う機会はあまりないでしょう。
- 他に類するコマンドがあるキーを使用する。例えば、CTRL-P と CTRL-N。さらに多く
のマップを使用するには、複数文字を使用します。
- <Leader> と 1 つまたは複数のキーを組み合わせて使用する。これは特にスクリプト
で便利です。 mapleader
標準のキー操作を損なうことなくマップできるキーや、使われていないキーを探すには
index.txt を参照してください。":help {key}^D" を使用してそのキーが使われてい
るかどうかを調べることもできます ({key}は調べたいキー、^DはCTRL-Dの入力)。
1.8 例 map-examples
マップの例をいくつか示します (見た通り入力してください。"<CR>" は 4 文字です。
このような表記(<>)は 'cpoptions' に '<' が含まれていると使用できません)。
:map <F3> o#include
:map <M-g> /foo<CR>cwbar<Esc>
:map _x d/END/e<CR>
:map! qq quadrillion questions
:map <M-g> /foo<CR>cwbar<Esc>
:map _x d/END/e<CR>
:map! qq quadrillion questions
カウント指定の掛け算
マップの展開前にカウント指定が入力されると、そのカウントは {lhs} の前に入力さ
れたものとして扱われます。例えば、次のマップを定義したとき:
:map <F4> 3w
2<F4> は "23w" となります。つまり、2 * 3 単語移動するのではなく、23 単語の移動になります。カウントを掛けたい場合は式レジスタを使ってください:
:map <F4> @='3w'<CR>
クォートで囲まれた部分が実行される式です。@=1.9 マップを使う map-typing
Vim は、入力されたキーで始まるマップがあるかどうか調べ、そのようなマップがある
場合は、入力とマップが完全に一致するか一致しないと判断できるまで、次の入力を待
ちます。例えば、"qq" というマップがあるとして、最初に入力した 'q' は、次の文字
を入力するまで実際に入力されません。なぜなら、Vim には次に入力される文字が 'q'
であるかそうでないかを知ることができないからです。'timeout' がオンになっている
と (標準設定はオンです)、Vim は一秒間 (または 'timeoutlen' で指定されている時
間) だけ待機します。待機した後に、'q' という文字が入力されたのだと判断します。
ゆっくり入力したい場合や、遅いシステムを使用している場合は、'timeout' をオフに
してください。'ttimeout' を設定するのもいいでしょう。
map-precedence
バッファローカルなマップ(:map-<buffer>を使用して定義された)はどのグローバル
なマップよりも優先されます。バッファローカルなマップがグローバルなマップと同じ
場合、Vimはバッファローカルなマップを使用します。加えて、<nowait> で定義された
場合はより長いマップが同じ接頭辞を持っているとしても、直ちに完了したマップを使
用します。例えば、次の2つのマップがあるとします:
:map <buffer> <nowait> \a :echo "Local \a"<CR>
:map \abc :echo "Global \abc"<CR>
\a を入力するとバッファローカルなマップが直ちに使用されます。Vimはユーザーが:map \abc :echo "Global \abc"<CR>
\abc を入力するかどうかを知るためにそれ以上の文字を待つことはしません。
map-keys-fails
次のような状況では、キーコードが認識されないことがあります:
- Vim がキーコードを部分的にしか読めない。これは最初の文字だけ読める場合が多い
です。特定の Unix 版と xterm の組み合わせで起こります。
- 文字(列)の後にキーコードがあるマップ。例、"<F1><F1>" や "g<F1>"。
このように、キーコードが認識されない状況では、そのようなマップを使用することが
できません。対処方が2つあります:
- 'cpoptions' から 'K' フラグを除く。そうすると Vim はファンクションキーの残り
のコードを待つようになります。
- <F1> から <F4> のキーによって生成される実際のキーコードが <xF1> から <xF4>
と同じ場合があります。<xF1> を <F1> へ、<xF2> を <F2>へ、といったマップが存
在しますが、これはマップの後半では認識されません。<F1> から <F4> のキーの
キーコードを正しく設定してください:
:set <F1>=<type CTRL-V><type F1>
<F1> を四文字として入力してください。"=" の後の部分は文字通りにではなく、実際のキーを入力してください。
マップを定義するときに二番目の特殊キーを実際のキーコードで指定することでも解決
できます:
:map <F1><Esc>OP :echo "yes"<CR>
本物の <Esc> を入力しないでください。Vim がキーコードを認識し、<F1> に置き換えてしまいます。
他にも、ALT や Meta キーを押しながらキーを入力したときに、コードの 8 ビット目
をセットする代わりにそのキーに ESC を前置するような端末で問題が起こることがあ
ります。:map-alt-keys を参照。
recursive_mapping
{rhs} の中に {lhs} を含めて、再帰マップを作成できます。{lhs} を入力すると
{rhs} に置き換えられ、{rhs} の中に {lhs} があるとその {lhs} がさらに {rhs} に
置き換えられ、さらに {rhs} の中の {lhs} が置き換えられ...。というようにコマン
ドを無限に繰り返すことができます。エラーを生じさせないと止めることができないの
が唯一の問題です。例外として、{rhs} が {lhs} で始まっている場合は、その文字は
再帰的にマップされません (これは Vi 互換です)。
例えば次のマップは:
:map ab abcd
"a" コマンドを実行して "bcd" を挿入します。{rhs} の中の "ab" は再帰的にマップされません。
二つのキーの意味を入れ換えるような場合は :noremap を使ってください。例えば:
:noremap k j
:noremap j k
これは、カーソルの上下移動のコマンドを入れ換えます。:noremap j k
普通の :map コマンドでマップを定義した場合、'remap' オプションがオンになってい
ると、そのマップが使用された後のテキスト ({rhs}) に {lhs} が含まれている限り、
マップが再帰的に繰り返されます。例えば、次のようなマップを使用する場合:
:map x y
:map y x
Vim はまず、x を y で置き換え、それから y を x で置き換え、...。これを:map y x
'maxmapdepth' に設定された回数だけ (標準設定は1000回) 繰り返し、"recursive
mapping" というエラーメッセージを表示します。
:map-undo
マップされたもの({rhs})がアンドゥコマンドを含んでいると、その操作を実行する前
の状態に戻すことになります。アンドゥが1回だけなら、その動作はオリジナルのVi互
換です(オリジナルのViでは、2回アンドゥしても意味がなく、最初のアンドゥを実行す
る前の状態に戻るだけです)。
1.10 ALT キーを使ったマップ :map-alt-keys
マッピングコマンドの読みやすさのため <A-k> の形式が使えます。Note <A-k> と
<A-K> は異なることに注意してください。後者は大文字を使います。実際には <A-K>
と <A-S-K> は同じです。"A" の代わりに "M" を使うこともできます。もし実際の
Meta 修飾キーがある場合は、:map-meta-keys を参照してください。
GUI では、Vim は Alt キーを直接取り扱うので、ALT キーを使ったマップは常に機能
します。CUI 端末では、Vim は受け取ったバイト列から、ALT キーが押されているかど
うかを割り出さなければなりません。
端末が modifyOtherKeys モードをサポートし、有効になっている場合、Vim はより多
くのキーの組み合わせを認識できます。以下の modifyOtherKeys を参照してくださ
い。
Kitty キーボードプロトコルも同じように動作します。kitty-keyboard-protocol を
参照してください。
初期設定では、ALT キーが押されているときは、文字の 8 ビット目が設定されるもの
と仮定しています。xterm、aterm、rxvt など、ほとんどの端末はこの方法で問題あり
ません。<A-k> のようなマップが動作しない場合は、その端末が、文字の前に ESC を
付けているのかもしれません。ユーザーが文字の前に ESC を入力することもできます
から、Vim は何が起きたか知ることはできません (ただし、ESC と文字の間に延滞があ
るかどうかをチェックする方法はあります。確実な方法ではありませんが)。
現在、gnome-terminal や konsole などの主要な端末が ESC を前置します。代わりに
8 ビット目を使うように設定する方法はないようです。Xterm では設定なしで機能しま
す。Aterm と rxvt では "--meta8" 引数を使えば機能します。"metaSendsEscape"、
"eightBitInput"、eightBitOutput" のようなリソースを設定することでも動作を変更
できます。
Linux コンソールでは、"setmetamode" コマンドで動作を切り替えることができます。
ESC の前置を使わないようにすると、他のプログラムで問題が起こる可能性があるので
注意してください。bash の "convert-meta" が "on" になっていることを確認し、
Meta キーバインディングが動作するようにしてください。(システム固有の設定変更を
していなければ、これは readline の標準の動作です)次の行を ~/.inputrc に追加す
ると、その設定をすることができます:
set convert-meta on
ファイルをはじめて作成した場合は、システム全体の設定を維持するために、次の行を
最初に加える必要があるかもしれません(そのファイルがシステムにある場合):
$include /etc/inputrc
このように設定すると、ウムラウトのような特殊な文字を入力できなくなるかもしれま
せん。その場合は、文字の前に CTRL-V を入力してください。
convert-meta は UTF-8 ロケールでは問題を起こすことがすでに報告されています。
xterm のような端末では、起動しているときに、メニューの "Main Options" から
"metaSendsEscape" リソースを設定できます。メニューは端末を Ctrl-LeftClick する
と表示できます。他のアプリケーションでは ESC を使い、Vim では使いたくない、と
いう場合にこのリソースを使うと便利です。
1.11 META キーを使ったマップ :map-meta-keys
Meta 修飾子を使ったマッピングは Alt キーを使った場合と非常によく似た動きをしま
す。キーボードのどのキーが Meta 修飾子として動作するかはキーボードと設定に依存
します。
Note <M-a> マップは実際には Alt キーを使うことに注意してください。これは混乱す
るでしょう! 後方互換性がなくなるため、変更することはできません。
Meta 修飾子には文字 "T" が使われます。例えば挿入モードで Meta-b をマップするに
は:
:imap <T-b> terrible
1.12 SuperキーまたはCommandキーのマップ :map-super-keys :map-cmd-key
Super 修飾子は、Linux 上の gVim および Mac OS 上の MacVim の GUI モード
(gui_running が 1 の場合) で使用できます。Mac を使用している場合、これは
Command キーを表し、GTK GUI を使用する Linux では、Super キーを表します。
文字 "D" は、Super / Command 修飾子に使用されます。
例えば、挿入モードで Command-b をマップするには:
:imap <D-b> barritone
1.13 modifyOtherKeys モードのマップ modifyOtherKeys
xterm と他のいくつかの端末は、修飾子付きのキーが特別なエスケープコードで送信さ
れるモードにすることができます。Vim はこれらのコードを認識し、Backspace が文字
の 8 を送信した場合でも、CTRL-H と Backspace を区別できます。Tab と CTRL-I な
ど、他の方法では個別にマップできないさらに多くの特別なキーも区別できます。
xterm の場合、組み込みの termcap エントリで modifyOtherKeys が有効になっていま
す。これが使われない場合は、vimrc にこれらの行を追加して modifyOtherKeys を有
効にできます:
let &t_TI = "\<Esc>[>4;2m"
let &t_TE = "\<Esc>[>4;m"
let &t_TE = "\<Esc>[>4;m"
これは modifyOtherKeys をレベル 2 に設定します。Note modifyOtherKeys レベル 1
は動作しないことに注意してください。いくつかの端末はレベル 2 をサポートしてお
らず Vim が正しく認識できないキーコードを送信します。
modifyOtherKeys モードで問題が発生する場合は、無効にすることができます:
let &t_TI = ""
let &t_TE = ""
これはすぐには有効になりません。Vim を再起動せずにこれが動作するようにするにlet &t_TE = ""
は、シェルコマンドを実行します。例: !ls。あるいはこれらの行を vimrc に書い
てください。
modifyOtherKeys が有効化されているときは <C-[> と <C-S-{> をマップすることがで
きます:
imap <C-[> [[[
imap <C-{> {{{
modifyOtherKeys 無しだと <C-[> と <C-{> は Esc と区別することができません。imap <C-{> {{{
Note <C-S-[> や <C-S-{> ではなく <C-{> が使われていることに注意してください。
これは多くのキーボードで動作します。同様に、<C-}> は <C-S-]> もしくは <C-S-}>
のそして <C-|> は <C-S-\> もしくは <C-S-|> の代わりに使用されます。Note '|' は
マッピングにおいて特別な意味を持ちます、map-bar を参照。
警告: <C-[> をマップした場合、非常に多くのEscから開始するキーコードを破壊する
ことがあります。他のマッピングの「後」であることを確認してください。
xterm version 377 以降では Vim は modifyOtherKeys の状態を要求して検出すること
ができます。これには 't_RK' termcap エントリが使われます。その応答が見つかれば
Vim は modifyOtherKeys レベル 2 が有効化されているかを知り、それに応じてマップ
を扱います。
version 377 より前では Vim は modifyOtherKeys モードによって生成されたエスケー
プシーケンスを見つけた時に、それが有効化されていることを自動で検出します。Vim
がそのようなエスケープシーケンスを検出したかを見るには :verbose map を使いま
す。1 行目に "Seen modifyOtherKeys: true" (おそらく翻訳される) と表示されます。
この自動検出は "<1b>[27;" で始まるエスケープシーケンスを受信することに依存しま
す。これは xterm がこれらのキーコードを送信する通常の方法です。しかし、もし
formatOtherKeys リソースが他の形式を使って設定されているとこれが認識ができな
いため、formatOtherKeys を設定してはいけません。
既知の副作用として、挿入モードでは、CTRL-V キーの後に生のエスケープシーケンス
が挿入されます。これは、modifyOtherKeys が有効になっているかどうかを確認するた
めに使用できます。挿入モードで CTRL-SHIFT-V CTRL-V と入力し、1 バイトが得られ
たら modifyOtherKeys はオフで、<1b>[27;5;118~ が得られたらオンです。
Note xterm の version 376 までは Shift-Esc が通常の Esc を送信し、Shift 修飾子
がドロップするバグがあることに注意してください。
'esckeys' オプションがオフの時、修飾子付きのすべてのキーが挿入モードを終了させ
るのを防ぐため、挿入モードで modifyOtherKeys は無効化されます。
1.14 Kitty キーボードプロトコルを使ったマップ kitty-keyboard-protocol
'term' の値が "kitty" を含んでいる場合、Vim は Kitty キーボードプロトコルを有
効化するエスケープシーケンスを送出します。これは 'keyprotocol' オプションで変
更できます。
modifyOtherKeys と同様に、これはより多く修飾子付きキーを区別することを可能にし
ます。またこのプロトコルは Esc キーに対してもエスケープシーケンスを送信するた
め、Vim は受信した Esc キャラクタがタイプされた Esc キーを意味するのかエスケー
プシーケンスの開始なのかを知るためのタイムアウトを使う必要がありません。
Vim はステータス要求 (これは t_TI termcap エントリの一部のはずです) を見た時
に Kitty キーボードプロトコルが有効化されているかを自動で検出します。Vim がそ
のようなエスケープシーケンスを検出したかを見るには以下を使います:
:verbose map
1 行目に "Kitty keyboard protocol: {value}" (おそらく翻訳される) と表示されます。{value} の意味は:
Unknown ステータスはまだ受信していない
Off プロトコルは使われていない
On プロトコルが使われている
Disabled プロトコルは使われているが 't_TE' で無効化されているこ
とが予想される
Cleared プロトコルは 't_TE' で無効化されていることが予想され、
以前の状態は不明
1.15 オペレータの作成 :map-operator
オペレータは {motion} コマンドと合わせて使われます。独自のオペレータを定義する
には、最初に 'operatorfunc' を設定し、そして、g@ オペレータを呼びます。ユー
ザーが {motion} コマンドを実行した後、設定した関数が実行されます。
g@ E774 E775
g@{motion} 'operatorfunc' に設定された関数を実行します。
'[ マークに {motion} で選択された範囲の最初の位置が設
定されます。'] マークには選択範囲の最後の位置が設定さ
れます。
関数の引数には、文字列が一つ渡されます:
"line" {motion} は行単位 linewise
"char" {motion} は文字単位 characterwise
"block" {motion} は矩形 blockwise-visual
タイプは強制することができます。forced-motion を参照し
てください。
{+eval が有効な場合のみ利用できます}
例を示します。これは <F4> を使ってスペースの数を数えます:
nnoremap <expr> <F4> CountSpaces()
xnoremap <expr> <F4> CountSpaces()
" <F4> 2回で行に作用
nnoremap <expr> <F4><F4> CountSpaces() .. '_'
xnoremap <expr> <F4> CountSpaces()
" <F4> 2回で行に作用
nnoremap <expr> <F4><F4> CountSpaces() .. '_'
function CountSpaces(context = {}, type = '') abort
if a:type == ''
let context = #{
\ dot_command: v:false,
\ extend_block: '',
\ virtualedit: [&l:virtualedit, &g:virtualedit],
\ }
let &operatorfunc = function('CountSpaces', [context])
set virtualedit=block
return 'g@'
endif
if a:type == ''
let context = #{
\ dot_command: v:false,
\ extend_block: '',
\ virtualedit: [&l:virtualedit, &g:virtualedit],
\ }
let &operatorfunc = function('CountSpaces', [context])
set virtualedit=block
return 'g@'
endif
let save = #{
\ clipboard: &clipboard,
\ selection: &selection,
\ virtualedit: [&l:virtualedit, &g:virtualedit],
\ register: getreginfo('"'),
\ visual_marks: [getpos("'<"), getpos("'>")],
\ }
\ clipboard: &clipboard,
\ selection: &selection,
\ virtualedit: [&l:virtualedit, &g:virtualedit],
\ register: getreginfo('"'),
\ visual_marks: [getpos("'<"), getpos("'>")],
\ }
try
set clipboard= selection=inclusive virtualedit=
let commands = #{
\ line: "'[V']",
\ char: "`[v`]",
\ block: "`[\<C-V>`]",
\ }[a:type]
let [_, _, col, off] = getpos("']")
if off != 0
let vcol = getline("'[")->strpart(0, col + off)->strdisplaywidth()
if vcol >= [line("'["), '$']->virtcol() - 1
let a:context.extend_block = '$'
else
let a:context.extend_block = vcol .. '|'
endif
endif
if a:context.extend_block != ''
let commands ..= 'oO' .. a:context.extend_block
endif
let commands ..= 'y'
execute 'silent noautocmd keepjumps normal! ' .. commands
echomsg getreg('"')->count(' ')
finally
call setreg('"', save.register)
call setpos("'<", save.visual_marks[0])
call setpos("'>", save.visual_marks[1])
let &clipboard = save.clipboard
let &selection = save.selection
let [&l:virtualedit, &g:virtualedit] = get(a:context.dot_command ? save : a:context, 'virtualedit')
let a:context.dot_command = v:true
endtry
endfunction
set clipboard= selection=inclusive virtualedit=
let commands = #{
\ line: "'[V']",
\ char: "`[v`]",
\ block: "`[\<C-V>`]",
\ }[a:type]
let [_, _, col, off] = getpos("']")
if off != 0
let vcol = getline("'[")->strpart(0, col + off)->strdisplaywidth()
if vcol >= [line("'["), '$']->virtcol() - 1
let a:context.extend_block = '$'
else
let a:context.extend_block = vcol .. '|'
endif
endif
if a:context.extend_block != ''
let commands ..= 'oO' .. a:context.extend_block
endif
let commands ..= 'y'
execute 'silent noautocmd keepjumps normal! ' .. commands
echomsg getreg('"')->count(' ')
finally
call setreg('"', save.register)
call setpos("'<", save.visual_marks[0])
call setpos("'>", save.visual_marks[1])
let &clipboard = save.clipboard
let &selection = save.selection
let [&l:virtualedit, &g:virtualedit] = get(a:context.dot_command ? save : a:context, 'virtualedit')
let a:context.dot_command = v:true
endtry
endfunction
<expr> のマッピングを使うことでなんらかのカウントかレジスタの接頭詞を取ること
が可能になります。それにより、CmdlineEnter と CmdlineLeave の自動コマンドをト
リガーするコマンドラインの使用も回避します。
Note: 一時的に 'selection' を "inclusive" に設定し、'[ から '] まで選択した範
囲を正しくヤンクできるようにしています。
Note: 'clipboard' オプションの値に unnamed か unnamedplus が含まれている場
合、レジスタの "* や "+ が上書きされることを防ぐため、一時的に空に設定され
ます。
mode() 関数はオペレータが適用された後の状態を返します。
この例では現在行のテキストの外側にクォートを追加するノーマルモードのオペレータ
を作成するのにラムダ関数を使用しています:
nnoremap <F4> <Cmd>let &opfunc='{t ->
\ getline(".")
\ ->split("\\zs")
\ ->insert("\"", col("'']"))
\ ->insert("\"", col("''[") - 1)
\ ->join("")
\ ->setline(".")}'<CR>g@
\ getline(".")
\ ->split("\\zs")
\ ->insert("\"", col("'']"))
\ ->insert("\"", col("''[") - 1)
\ ->join("")
\ ->setline(".")}'<CR>g@
==============================================================================
2. 短縮入力 (Abbreviations) abbreviations Abbreviations
短縮入力は、挿入モード、置換モード、コマンドラインモードで使えます。短縮入力と
して登録されている単語を入力すると、それが表す単語に置き換えられます。よく使う
長い単語を打ち込むときのタイプ数を減らしたり、明確なスペルミスを自動的に修正す
るのに使えます。
例:
:iab ms Microsoft
:iab tihs this
短縮入力には三つの種類があります:
full-id "full-id" タイプは完全なキーワード文字から構成されます('iskeyword'
オプションに含まれる文字です)。最も一般的な短縮入力です。
例: "foo", "g3", "-1"
end-id "end-id" タイプはキーワード文字で終わりますが、他の文字はキーワード
文字ではありません。
例: "#i", "..f", "$/7"
non-id "non-id" タイプは非キーワード文字で終わります。他の文字はスペースと
タブ文字以外のどんな文字でもよいです。{Vi では、このタイプはサポート
されていません}
例: "def#", "4/7$"
短縮入力にできない文字列の例: "a.b", "#def", "a b", "_$r"
短縮入力は非キーワード文字を入力したときに展開されます。これは、挿入モードを終
わらせる<Esc>を入力したり、コマンドを終わらせる<CR>を入力したときにも起こりま
す。短縮入力を終わらせる非キーワード文字は、短縮入力を展開した後に挿入されま
す。<C-]>文字は例外で、短縮入力だけが展開され挿入されます。
例:
:ab hh hello
"hh<Space>" で "hello<Space>" に展開されます。"hh<C-]>" で "hello" に展開されます。
カーソルの前の文字が短縮入力とマッチする場合のみ機能します。短縮入力の種類に
よって、さらに条件があります:
full-id マッチした場所の前が非キーワード文字、行頭、挿入を開始した場所、であ
ること。例外: 短縮入力が1文字の場合、その前の文字がスペース、タブ、
以外の非キーワード文字なら短縮入力は展開されません。ただし、コマンド
ラインにおける "'<,'>" (もしくはその他のマーク) は無視され、コマンド
ラインがその後から始まっているように動作します。
end-id マッチした場所の前が非キーワード文字、スペース、タブ、行頭、挿入を開
始した場所、であること。
non-id マッチした場所の前がスペース、タブ、行頭、挿入を開始した場所、である
こと。
例: ({CURSOR}は非キーワード文字を入力する場所です)
:ab foo four old otters
" foo{CURSOR}" は " four old otters" に展開されます" foobar{CURSOR}" は展開されません
"barfoo{CURSOR}" は展開されません
:ab #i #include
"#i{CURSOR}" は "#include" に展開されます">#i{CURSOR}" は展開されません
:ab ;; <endofline>
"test;;" は展開されません"test ;;" は "test <endofline>" に展開されます
挿入モードで短縮入力の展開を避けるには、短縮入力を発動する可能性のある文字を入
力する前に CTRL-V を押します。 例:CTRL-V <Space> もしくは短縮入力の一部を入力
してから挿入モードを <Esc> で抜け、再度挿入モードに "a" で入って残りを入力しま
す。
コマンドラインモードで短縮入力の展開を避けるには、短縮入力の文字の途中でCTRL-V
を入力します (CTRL-V を2度押し)。展開されなかった場合、普通の文字の前のCTRL-V
は普通は無視されます。
短縮入力の後で、カーソルを動かすこともできます:
:iab if if ()<Left>
これは、'cpoptions' に '<' フラグが含まれていると、うまく動作しません。<>さらに手の込んだこともできます。例えば、短縮入力を展開するときに入力したスペー
スを消してしまうには:
func Eatchar(pat)
let c = nr2char(getchar(0))
return (c =~ a:pat) ? '' : c
endfunc
iabbr <silent> if if ()<Left><C-R>=Eatchar('\s')<CR>
let c = nr2char(getchar(0))
return (c =~ a:pat) ? '' : c
endfunc
iabbr <silent> if if ()<Left><C-R>=Eatchar('\s')<CR>
標準設定されている短縮入力はありません。
短縮入力の展開は再帰的には行われません。":ab f f-o-o" という短縮入力を問題なく
使うことができます。しかし、展開された文字にはマップが適用されます。 {Vi のい
くつかのバージョンで再帰的な短縮入力をサポートしていますが、そこになんら明確な
理由はありません}
'paste' オプションがオンの場合、短縮入力は使用できません。
:abbreviate-local :abbreviate-<buffer>
マップと同じように、バッファローカルな短縮入力を作成できます。これは主に
filetype-pluginなどで使用されます。C言語用プラグインの例:
:abb <buffer> FF for (i = 0; i < ; ++i)
:ab :abbreviate
:ab[breviate] すべての短縮入力を一覧表示します。行頭の文字は、その短
縮入力を使用できるモードを示しています: 'i' は挿入モー
ド、'c' はコマンドラインモード、'!' はその両方。マップ
の一覧表示と同じです。map-listingを参照。
:abbreviate-verbose
'verbose' がゼロ以外のときに短縮入力一覧を表示すると、どこで定義されたのかも表
示されます。例:
:verbose abbreviate
! teh the
Last set from /home/abcd/vim/abbr.vim
! teh the
Last set from /home/abcd/vim/abbr.vim
詳しくは :verbose-cmd を参照してください。
:ab[breviate] {lhs} {lhs} で始まる短縮入力を一覧表示します。
{lhs} に入力した文字が短縮入力として展開されないように
するには CTRL-V (2度押しで入力する) を挿入します。そう
しないとコマンドライン用の短縮入力があった場合にそれが
展開されてしまいます。
:ab[breviate] [<expr>] [<buffer>] {lhs} {rhs}
{rhs} の短縮入力を {lhs} として定義します。既に {lhs}
が定義されていると、新しい {rhs} で置き換えられます。
{rhs} はスペースを含んでいてもかまいません。
<expr> 引数については:map-<expr>を参照してください。
<buffer> 引数については :map-<buffer> を参照してくだ
さい。
:una :unabbreviate
:una[bbreviate] [<buffer>] {lhs}
{lhs} という短縮入力を全て削除します。見つからなかった
場合は、{lhs} に入力した文字を各短縮入力の {rhs} から
探して見つかったものを削除します。これは短縮入力が展開
されてしまった状態でも削除できるようにするためです。短
縮入力の展開を防ぐには CTRL-V (2度押しで入力する) を挿
入します。
:norea :noreabbrev
:norea[bbrev] [<expr>] [<buffer>] [lhs] [rhs]
":ab" と同じですが、展開後にマップを適用しません。
:ca :cab :cabbrev
:ca[bbrev] [<expr>] [<buffer>] [lhs] [rhs]
":ab" と同じですが、コマンドラインモード用の短縮入力の
み対象です。
:cuna :cunabbrev
:cuna[bbrev] [<buffer>] {lhs}
":una" と同じですが、コマンドラインモード用の短縮入力
のみ対象です。
:cnorea :cnoreabbrev
:cnorea[bbrev] [<expr>] [<buffer>] [lhs] [rhs]
":ab" と同じですが、コマンドラインモード用の短縮入力の
み対象で、展開後にマップを適用しません。
:ia :iabbrev
:ia[bbrev] [<expr>] [<buffer>] [lhs] [rhs]
":ab" と同じですが、挿入モード用の短縮入力のみ対象で
す。
:iuna :iunabbrev
:iuna[bbrev] [<buffer>] {lhs}
":una" と同じですが、挿入モード用の短縮入力のみ対象で
す。
:inorea :inoreabbrev
:inorea[bbrev] [<expr>] [<buffer>] [lhs] [rhs]
":ab" と同じですが、挿入モード用の短縮入力のみ対象で、
展開後にマップを適用しません。
:abc :abclear
:abc[lear] [<buffer>] すべての短縮入力を削除します。
:iabc :iabclear
:iabc[lear] [<buffer>] 挿入モード用の短縮入力を削除します。
:cabc :cabclear
:cabc[lear] [<buffer>] コマンドラインモード用の短縮入力を削除します。
using_CTRL-V
特殊な文字を短縮入力の{rhs}で使うことができます。非印字可能文字の特殊な意味を
打ち消す(クォートする)には、CTRL-Vを使用します。必要なCTRL-Vの数は、どのような
短縮入力を作成するかによります。これはマップでも同様です。例を示します。
"esc" を実際の<Esc>文字を挿入する短縮入力にしたいとしましょう。Vim で ":ab" コ
マンドを使うときには、次のようにしなければなりません: (ここで^VはCTRL-Vで、
^[は<Esc>です)
入力: ab esc ^V^V^V^V^V^[
キー入力はすべて^Vによるクォートが適用されます。つまり、1番目、3番目、
5番目の^Vは、2番目と4番目の^Vと、^[がコマンドラインに入力されるように
しています。
見え方: ab esc ^V^V^[
コマンドラインには実際には2つの^Vと^[が表示されています。もしそうする
つもりがあれば、これは .exrc ファイルでの見え方になるはずです。始めの
^Vは2番目の^Vをクォートするためにあります。:abコマンドは^Vをクォート文
字として扱いますので、短縮入力の中で、クォートされた空白文字や '|' 文
字を使うことができます。:abコマンドは^[に対しては何も特殊な処理は行い
ません。だからクォートする必要もないです。(クォートしても問題はありま
せん。上の例は7(8はだめです!)個の^Vを入力しても動作します)。
格納: esc ^V^[
コマンドが解析された後、短い形式("esc")と長い形式("^V^[" の2文字)とし
て、短縮入力の一覧に加えられます。:ab コマンドを引数なしで実行したとき
に、この形の短縮入力が表示されます。
あとで、ユーザーが "esc" を入力し、短縮入力が展開されたとき、長い形式
は実際のキー入力と同様に^Vによるクォートが適用されます。つまり、^Vが
^[をクォートし、"挿入モードから抜ける" 文字として解釈されることを防ぐ
のです。その代わりに、^[がテキストに挿入されます。
展開: ^[
[例は Steve Kirkendall によって提供されました]
==============================================================================
3. ローカルマップとローカル関数(Local mappings and functions) script-local
いくつかの Vim script を併用すると、あるスクリプトで使われているマップや関数と
同じ名前のものが別のスクリプトでも使用される恐れがあります。それを避けるには、
スクリプトローカルなマップや関数を使用します。
<SID> <SNR> E81
マップやメニューに "<SID>" という特別な文字列を使用できます。これは 'cpoptions'
にフラグ '<' が含まれていると利用できません。これはスクリプトローカル関数を同
じスクリプト内のマッピングから呼びたい場合に便利です。
マップコマンドを実行すると、"<SID>" は、<SNR> という特別なキーコードとスクリプ
ト固有の番号、そしてアンダースコアに置換されます。例:
:map <SID>Add
これは "<SNR>23_Add" といったマップを定義します。スクリプトで関数を作成するときに、関数名の前に "s:" を付けると、ローカル関数を
作成できます(Vim9 script ではプリフィックスなしの関数はスクリプトローカルに
なります)。しかし、その関数をマップで使用する場合、そのマップをスクリプト以外
の場所で実行すると、その関数がどのスクリプトで定義されたのか分かりません。これ
を解決するには、マップ中で "s:" ではなく "<SID>" を使用します。この場合も
"<SID>" は上記の例と同じように置換されます。これでローカル関数の呼び出しを含む
マップを定義できます。
ローカル関数は、その関数を定義したスクリプトのコンテキストで実行されます。その
ため、その関数内で新たに定義した関数やマップにも "s:" や "<SID>" を使用できま
す。その場合、その関数自身と同じスクリプト番号が使用されます。"s:var" といった
スクリプトローカル変数も同様です。
自動コマンドやユーザー定義コマンドもそれを定義したスクリプトのコンテキストで実
行されます。そのコマンドからローカル関数を呼び出したり、ローカルマップを使用す
ることができます。
<SID> が正しく展開されないコンテキストで値が使われる場合は、expand() 関数を使
います:
let &includexpr = expand('<SID>') .. 'My_includeexpr()'
スクリプト以外の場所で "<SID>" を使うとエラーになります。
複雑な処理をするスクリプトで、スクリプト番号が必要な場合は、次の関数で番号を得
られます:
func s:ScriptNumber()
return matchstr(expand('<SID>'), '<SNR>\zs\d\+\ze_')
endfunc
return matchstr(expand('<SID>'), '<SNR>\zs\d\+\ze_')
endfunc
関数やマップを一覧表示するときには "<SNR>" も表示されます。それらがどのように
定義されているのか調べるときに便利です。
コマンド:scriptnamesを使って、それまでに実行されたスクリプトとそのスクリプト
番号を確認できます。
これらはすべて {+eval が有効な場合のみ利用できます}
==============================================================================
4. ユーザー定義コマンド (User-defined command) user-commands
ユーザー独自のExコマンドを定義することできます。ユーザー定義コマンドはビルトイ
ンコマンドと同様に振る舞うことができます(範囲指定や、引数を取ることができます。
引数の入力では、ファイル名、バッファ名などを補完できます)。違いは、コマンドが
実行されると、通常の Ex コマンドに変換してから実行されるということです。
まずはユーザーマニュアルの40.2を参照してください。
E183 E841 user-cmd-ambiguous
すべてのユーザー定義コマンドは大文字で開始する必要があります。これはビルトイン
コマンドと混同しないようにするためです。特例として次のようなビルトインコマンド
もありますが:
:Next
:X
これらの名前もユーザー定義コマンドには使えません。":Print" コマンドも存在しま
すがこれは非推奨 (deprecated) になっており、上書きすることができます。
ユーザーコマンドの開始文字以外は、大文字であっても小文字であっても、数字であっ
てもかまいません。数字を使う場合、数字を引数に取る他のコマンドが曖昧になるかも
しれないので注意してください。例えば、"Cc2" コマンドは ":Cc2" という引数なしの
ユーザーコマンドとしても、"2" という引数を取った ":Cc" コマンドとしても解釈で
きます。これらの問題を避けるため、コマンド名と引数の間にスペースを挿入すること
を勧めます。
ユーザー定義コマンドを使うときに、コマンドの省略形を使うこともできます。しかし
ながら、その省略形が唯一でなければエラーが起きます。加えて、ビルトインコマンド
が常に優先されます。
例:
:command Rename ...
:command Renumber ...
:Rena " "Rename" を意味します
:Renu " "Renumber" を意味します
:Ren " エラー - 曖昧
:command Paste ...
:P " ビルトインコマンドの:Print です
:command Renumber ...
:Rena " "Rename" を意味します
:Renu " "Renumber" を意味します
:Ren " エラー - 曖昧
:command Paste ...
:P " ビルトインコマンドの:Print です
スクリプトの中で使うときは、ユーザー定義コマンドの完全な名前を使うようにしま
しょう。
:com[mand] :com :command
すべてのユーザー定義コマンドを一覧表示します。表示中の
行頭の文字は次の意味です:
! -bang 属性を持つコマンド
" -register 属性を持つコマンド
| -bar 属性を持つコマンド
b カレントバッファのローカルコマンド
(属性に関する詳細は下記参照)
一覧は :filter を用いてコマンド名でフィルタできま
す。例えば名前に "Pyth" を含む全コマンドを一覧するなら
ば次のようにします:
filter Pyth command
:com[mand] {cmd} {cmd} で始まるユーザー定義コマンドを一覧表示します。
:command-verbose
'verbose' がゼロ以外のときにコマンド一覧を表示すると、そのコマンドが最後に定義
された場所と補完の引数も表示します。例:
:verbose command TOhtml
Name Args Range Complete DefinitionTOhtml 0 % :call Convert2HTML(<line1>, <line2>)
Last set from /usr/share/vim/vim-7.0/plugin/tohtml.vim
詳しくは :verbose-cmd を参照してください。
E174 E182
:com[mand][!] [{attr}...] {cmd} {repl}
ユーザー定義コマンドを定義します。コマンド名は {cmd}
でそれを置き換えるテキストが {repl} です。{attr} はコ
マンド属性(下記参照)です。既にコマンドが存在している場
合はエラーになります。! を指定した場合は再定義されま
す。1つ例外があります: スクリプトを再読み込みする場合、
そのスクリプトで以前に定義されていたコマンドは、静かに
置き換えられます。
:delc[ommand] {cmd} :delc :delcommand E184
ユーザー定義コマンド {cmd} を削除します。
これはコマンドの一覧表示中には許可されません。例えばタ
イマーから呼ぶなど。E1311
:delc[ommand] -buffer {cmd} E1237
カレントバッファで定義されたユーザー定義コマンド {cmd}
を削除します。
:comc[lear] :comc :comclear
すべてのユーザー定義コマンドを削除します。
コマンド属性
command-attributes
ユーザー定義コマンドは、他のビルトインコマンドと同様に扱われます。引数や範囲も
指定できます。引数の入力時にはファイル名やバッファ名などを補完することができま
す。どのように動作するかはコマンドを定義するときに指定したコマンド属性に依存し
ます。
ユーザーコマンドをスクリプトで定義するときは、スクリプトにローカルな関数を呼
び、スクリプトにローカルなマッピングを使うことができます。ユーザーがそのユー
ザーコマンドを実行すると、そのスクリプトが定義されたコンテキストで実行されま
す。これはコマンド内で <SID> が使われているときに重要となります。
たくさんの属性がありますが、それらは、引数の扱い方、補完の種類、範囲指定の仕
方、特殊なケース、の4つの分野に分けることができます。以下、分野別に説明しま
す。
引数の扱い方
E175 E176 :command-nargs
属性を指定しなかった場合、ユーザー定義コマンドは引数を取りません(引数が与えら
れた場合はエラーになります)。-nargs属性を指定すると、ユーザー定義コマンドが引
数指定できるようになります。次の属性が指定できます:
-nargs=0 引数を取らない (デフォルト)
-nargs=1 1個の引数が必要 (空白で区切られない)
-nargs=* いくつでも引数を取れる (0個以上)
空白で区切られる
-nargs=? 0 もしくは 1 個の引数が取れる
-nargs=+ 引数が必ず必要。数はいくつでもよい
引数は (エスケープされていない) スペースやタブ文字で区切られます。ただし、引数
を 1 つだけ取る場合は空白は引数の一部として解釈されます。
Note: 引数は Vim script の式としてではなく、テキストとして解釈されることに注意
してください。具体的な例を上げると、"s:var" を引数として渡すと、そのコマンドを
実行したスクリプトのローカル変数ではなく、そのコマンドを定義したスクリプトの
ローカル変数が使用されます。例:
script1.vim:
:let s:error = "None"
:command -nargs=1 Error echoerr <args>
script2.vim::command -nargs=1 Error echoerr <args>
:source script1.vim
:let s:error = "Wrong!"
:Error s:error
script2.vimを実行すると "None" が表示されます。期待した結果とは違うでしょう。:let s:error = "Wrong!"
:Error s:error
代わりに関数呼び出しを使ってください。
補完の動作
:command-completion E179 E180 E181
:command-complete
属性を指定しない場合、ユーザー定義コマンドの入力時に引数は補完されません。下記
の属性のうちいずれか1つを指定することで、引数が補完されるようになります。
-complete=arglist 引数リスト内のファイル名
-complete=augroup 自動コマンドのグループ
-complete=behave :behave サブオプション
-complete=breakpoint :breakadd サブオプション
-complete=buffer バッファ
-complete=color カラースキーム
-complete=command Ex コマンド(と、引数)
-complete=compiler コンパイラ
-complete=cscope :cscope サブオプション
-complete=diff_buffer 差分バッファ
-complete=dir ディレクトリ
-complete=dir_in_path 'cdpath' 内のディレクトリ
-complete=environment 環境変数
-complete=event 自動コマンドのイベント
-complete=expression Vimの式
-complete=file ファイルとディレクトリ
-complete=file_in_path 'path' 内のファイルとディレクトリ
-complete=filetype ファイルタイプ名 'filetype'
-complete=function 関数
-complete=help ヘルプの主題
-complete=highlight ハイライトグループ
-complete=history :history サブオプション
-complete=keymap キーボードマッピング
-complete=locale ロケール名 (locale -a の出力)
-complete=mapclear バッファ引数
-complete=mapping マップ
-complete=menu メニュー
-complete=messages :messages サブオプション
-complete=option オプション
-complete=packadd オプショナルパッケージの pack-add 名
-complete=runtime 'runtimepath' 内のファイルとディレクトリ
-complete=scriptnames 読み込まれたスクリプト
-complete=shellcmd シェルコマンド
-complete=shellcmdline 最初はシェルコマンドで、後続はファイル名。
:!cmd と同じ動作である
-complete=sign :sign サブオプション
-complete=syntax シンタックスファイル名 'syntax'
-complete=syntime :syntime サブオプション
-complete=tag タグ
-complete=tag_listfiles CTRL-D を押した時にタグ、ファイル名を表示
-complete=user ユーザー名
-complete=var ユーザー変数
-complete=custom,{func} {func}によるユーザー定義の補完
-complete=customlist,{func} {func}によるユーザー定義の補完
補完するものがないとき(デフォルトは -nargs=0)に補完を指定すると E1208 になり
ます。
Note: いくつかの補完方法は環境変数を展開します。
ユーザー定義の補完
:command-completion-custom
:command-completion-customlist E467 E468
補完方法に "custom,{func}"、"customlist,{func}" を指定すると独自の補完を使用で
きます。{func}には次のような関数を指定します。
:function {func}(ArgLead, CmdLine, CursorPos)
すべての引数を使う必要はありません。関数の戻り値として、補完候補のリストを返し
てください。
"custom" を使った場合は、補完候補のリストを一つずつ改行で区切ってください。
E1303
"customlist" を使った場合は、補完候補のリストを List で返してください。リス
ト中の文字列以外の変数は無視されます。
引数には次の意味があります:
ArgLead すでに入力されている補完対象の文字列
CmdLine コマンドライン全体
CursorPos カーソル位置 (バイト単位のインデックス)
これらの引数を使えば文脈を判断することができるでしょう。"custom" を使った場合、
補完候補のリストからArgLeadにそぐわない候補(ArgLeadで始まらない文字)を取り除く
必要はありません。Vimは補完関数を実行した後に自身の正規表現エンジンでふさわし
くない候補を取り除きます、おそらくその方がほとんどの場面で有用です。
'wildoptions' が "fuzzy" を含む場合、候補はファジーマッチ fuzzy-matching を
使用してフィルタされます。"customlist" 引数の場合、Vim は返された補完候補をフィ
ルタしないので、ユーザーが指定した関数が候補をフィルタする必要があります。
次の例はFingerコマンドでユーザー名を補完します
:com -complete=custom,ListUsers -nargs=1 Finger !finger <args>
:fun ListUsers(A,L,P)
: return system("cut -d: -f1 /etc/passwd")
:endfun
:fun ListUsers(A,L,P)
: return system("cut -d: -f1 /etc/passwd")
:endfun
次の例では、'path' に指定されたディレクトリのファイル名を補完しています:
:com -nargs=1 -bang -complete=customlist,EditFileComplete
\ EditFile edit<bang> <args>
:fun EditFileComplete(A,L,P)
: return split(globpath(&path, a:A), "\n")
:endfun
\ EditFile edit<bang> <args>
:fun EditFileComplete(A,L,P)
: return split(globpath(&path, a:A), "\n")
:endfun
この例はファイル名にスペースが含まれていると機能しません!
範囲指定
E177 E178 :command-range :command-count
属性を指定しない場合、ユーザー定義コマンドは行番号による範囲指定を受け付けませ
ん。-range属性を指定して、コマンドが範囲指定を受け付けるようにできます。任意の
カウント値を取るようにすることもできます。この場合、行番号の位置(:splitコマ
ンドのように。-range=N)で指定するか、"count" 引数(:Nextコマンドのように。
-count=N)で指定します。カウント指定は <count> で取得できます。
次の属性が利用できます:
-range 範囲指定が可能になります、無指定時は現在行
-range=% 範囲指定が可能になります、無指定時はファイル全体(1,$)
-range=N カウント(無指定時はN)を行番号位置に指定できます
(例 :split)。行番号に 0 を指定可能になる。
-count=N カウント(無指定時はN)を行番号位置か、初期化引数に指定でき
ます (例 :Next)。
-count -count=0 と同じです
Note: -range=Nと-count=Nは相互に排他的であるということに注意してください。どち
らか一方のみを指定することができます。
:command-addr
範囲指定には .、$、% といった特殊文字を含むことができ、それぞれ現在行、最終行、
バッファ全体を表します。これらは引数、(ロードされた)バッファ、ウィンドウ及び
タブページに関連付けすることができます。
次の値を利用できます (2列目は一覧表示で使われる短い名前です):
-addr=lines 行 (-range のデフォルトです)
-addr=arguments arg 引数
-addr=buffers buf バッファ (ロードされていないバッファも)
-addr=loaded_buffers load ロードされたバッファ
-addr=windows win ウィンドウ
-addr=tabs tab タブページ
-addr=quickfix qf quickfix のエントリ
-addr=other ? 他の種類の範囲; "lines" をつけるのと同様に".",
"$", "%" が使えます (-count のデフォルトです)
特殊なケース
:command-bang :command-bar
:command-register :command-buffer
:command-keepscript
特殊なケースがいくつかあります:
-bang コマンドは!修飾子を取ることができます(:qや:wのように)
-bar コマンドは "|" を使用して別のコマンドを続けて実行すること
ができます。引数に "|" を含めることはできなくなります。" が
コメントの開始になってしまうことにも注意してください。
-register コマンドの1つ目の引数にレジスタ名を指定することができます
(:del、:put、:yankのように)。
-buffer コマンドはカレントバッファでのみ利用できます。
-keepscript 詳細メッセージにユーザーコマンドが定義された場所は使用せ
ず、ユーザーコマンドが呼び出された場所を使用します。
ユーザー定義コマンドの定義に-countや-registerが指定された場合に、その省略可能
な引数が与えられた場合、それは引数リストから削除され、それぞれの引数に対応する
特別な文字列が利用できるようになります。
Note これらの引数は省略できますが、これは廃止される機能です。新しいスクリプト
では完全な名前を使用して下さい。
置き換えテキスト
:command-repl
引数 {repl} は通常は1つの長い文字列で、分割のコマンド "|" と合せて利用できま
す。特殊な場合として引数が "{" であるなら、"}" で始まる行までのそれ以降の行が
利用され Vim9 の文法が適用されます。
例:
:command MyCommand {
echo 'hello'
g:calledMyCommand = true
}
E1231echo 'hello'
g:calledMyCommand = true
}
"{" の前に空白が必要です。ネストはサポートされず、インライン関数は使用できませ
ん。式の引数を持つコマンドなど、引数に "|" が出現する可能性のあるコマンドは、
"|" の後に別のコマンドを続けることはできません。
コマンドが Vim9 script (:vim9script で始まるスクリプトか :def 関数の中) で
定義されている場合、{repl} は Vim9 script 内で実行されます。つまりこれは、コマ
ンドがどこで使われたかではなく、どこで定義されたかに依存します。
ユーザー定義コマンドでは、<...>表記を使った特別な文字列 {repl} を使用できます。
その文字列はコマンドラインに入力された実際の引数に置き換えられます。その他のテ
キストは変更されません。そして特別な文字列を実際の引数で置換したものがExコマン
ドとして実行されます。<> 表記が置き換えられないようにするには、最初の < の代わ
りに <lt> を使ってください。例えば、"<bang>" をリテラル文字として使うには
"<lt>bang>" とします。
次のものを使用できます
<line1>
<line1> コマンド範囲の最初の行
<line2>
<line2> コマンド範囲の最後の行
<range>
<range> コマンド範囲を指定するために使われた要素の数: 0, 1 もしくは 2
<count>
<count> 与えられたカウント('-range' と '-count' 属性で記述されている)
<bang>
<bang> ('-bang' 属性を参照) コマンドが ! 修飾子付きで実行された場合に
! に置換されます。指定なしの場合は空文字列になります。
<mods> <q-mods> :command-modifiers
<mods> 指定されている場合はコマンド修飾子。されていない場合は何も展開
しません。対応している修飾子は以下の通り:
:aboveleft, :belowright,
:botright, :browse, :confirm, :hide, :horizontal,
:keepalt, :keepjumps, :keepmarks, :keeppatterns,
:leftabove, :lockmarks, :noautocmd, :noswapfile,
:rightbelow, :sandbox, :silent, :tab, :topleft,
:unsilent, :verbose, 加えて :vertical.
Note :filter には対応していないことに注意してください。
例:
command! -nargs=+ -complete=file MyEdit
\ for f in expand(<q-args>, 0, 1) |
\ exe '<mods> split ' .. f |
\ endfor
\ for f in expand(<q-args>, 0, 1) |
\ exe '<mods> split ' .. f |
\ endfor
function! SpecialEdit(files, mods)
for f in expand(a:files, 0, 1)
exe a:mods .. ' split ' .. f
endfor
endfunction
command! -nargs=+ -complete=file Sedit
\ call SpecialEdit(<q-args>, <q-mods>)
for f in expand(a:files, 0, 1)
exe a:mods .. ' split ' .. f
endfor
endfunction
command! -nargs=+ -complete=file Sedit
\ call SpecialEdit(<q-args>, <q-mods>)
<reg> <register>
<reg> ('-register' 属性を参照) レジスタ名に置換されます。指定なしの
場合は空文字列になります。<register>も同義です。
<args>
<args> 与えられた通りのコマンド引数(上記の通り、カウントやレジスタが
指定された場合は<args>に含まれません)。
<lt> 1つの '<' (小なり)文字。特別な文字列を文字どおりに使用したい場
合に必要となります。例えば<bang>を得るには<lt>bang>とします。
<q-args>
特別な文字列の始めの2文字が "q-" なら(例えば<q-args>)、引数は式で使えるように
クォートされます("で囲まれる)。これは引数を1つの値として扱います。引数がない場
合は <q-args> は空文字列になります。下記 q-args-example を参照してください。
<f-args>
ユーザー定義コマンドの引数を関数に渡すには、<f-args>("function args")が利用で
きます。これはコマンドの引数をスペースやタブ文字で区切り、それぞれの引数を別々
にクォート("で囲む)し、コンマで区切ったリストにして<f-args>と置き換えます。下
のMycmdの例をご覧下さい。引数がない場合は <f-args> は取り除かれます。
<f-args> の引数にスペースを含めるには、バックスラッシュを前置します。<f-args>
では二つのバックスラッシュ (\\) は一つのバックスラッシュに置換されます。スペー
スとバックスラッシュ以外の文字に付いているバックスラッシュはそのまま使われま
す。下記 f-args-example も参照してください。要約:
コマンド <f-args>
XX ab 'ab'
XX a\b 'a\b'
XX a\ b 'a b'
XX a\ b 'a ', 'b'
XX a\\b 'a\b'
XX a\\ b 'a\', 'b'
XX a\\\b 'a\\b'
XX a\\\ b 'a\ b'
XX a\\\\b 'a\\b'
XX a\\\\ b 'a\\', 'b'
XX [nothing]
Note "引数無し" の状況を扱う場合、関数が引数無しでも呼び出せるようにしなければ
ならないことに注意してください。コンパイル済み関数の場合、可変引数が使えます。
vim9-variable-arguments 参照。
ユーザーコマンドの例
" 現在行から最後行までを削除します
:com Ddel +,$d
:com Ddel +,$d
" カレントバッファ名を変更します
:com -nargs=1 -bang -complete=file Ren f <args>|w<bang>
:com -nargs=1 -bang -complete=file Ren f <args>|w<bang>
" 指定された範囲をあるファイルの内容に置き換えます
" (1行に書きます)
:com -range -nargs=1 -complete=file
Replace <line1>-pu_|<line1>,<line2>d|r <args>|<line1>d
" (1行に書きます)
:com -range -nargs=1 -complete=file
Replace <line1>-pu_|<line1>,<line2>d|r <args>|<line1>d
" 指定された範囲の行数を数える
:com! -range -nargs=0 Lines echo <line2> - <line1> + 1 "lines"
:com! -range -nargs=0 Lines echo <line2> - <line1> + 1 "lines"
f-args-example
ユーザー関数を呼ぶには (<f-args>の例)
:com -nargs=* Mycmd call Myfunc(<f-args>)
次のように実行された場合は:
:Mycmd arg1 arg2
次のものを実行します: :call Myfunc("arg1","arg2")
q-args-example
より現実的な例:
:function Allargs(command)
: let i = 0
: while i < argc()
: if filereadable(argv(i))
: execute "e " .. argv(i)
: execute a:command
: endif
: let i = i + 1
: endwhile
:endfunction
:command -nargs=+ -complete=command Allargs call Allargs(<q-args>)
: let i = 0
: while i < argc()
: if filereadable(argv(i))
: execute "e " .. argv(i)
: execute a:command
: endif
: let i = i + 1
: endwhile
:endfunction
:command -nargs=+ -complete=command Allargs call Allargs(<q-args>)
Allargsコマンドは、引数としてどのVimコマンドでも取ることができ、引数リスト
argument-listのすべてのファイルに対して与えられたコマンドを実行します。使い
方の例 ("e" フラグをつけてエラーを無視しており、また "update" コマンドで変更さ
れたバッファを書き込んでいるので注意してください):
:Allargs %s/foo/bar/ge|update
これは、次のものを起動します: :call Allargs("%s/foo/bar/ge|update")
vim:tw=78:ts=8:noet:ft=help:norl: