-
Notifications
You must be signed in to change notification settings - Fork 64
/
map.jax
1888 lines (1572 loc) · 101 KB
/
map.jax
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
*map.txt* For Vim バージョン 9.1. Last change: 2023 May 28
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 modifyOtherKeys モードのマップ |modifyOtherKeys|
1.13 Kitty キーボードプロトコルを使ったマップ |kitty-keyboard-protocol|
1.14 オペレータの作成 |: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} に <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" のどちらを使用するかを決定するためには、次
の文字が必要になります。そのため、"aa" が入力された時点ではまだマップは適用さ
れず、次の入力まで待機状態になります。例えば空白文字を入力すれば "foo" と空白
文字が挿入されます。"a" を入力すれば "bar" が挿入されます。
末尾空白 ~
*map-trailing-white*
このunmapコマンドは動作しません: >
:map @@ foo
:unmap @@ | print
なぜなら unmap "@@ " を試行するとき、コマンド区切りの "|" の前の空白を含んでい
るためです。他の末尾空白の例として: >
unmap @@
unmap @@ # Vim9 script コメント
unmap @@ " 旧来のスクリプトのコメント
`unmap @@ ` の末尾が空白文字のためエラーになりますが、これは見えないので特定す
るのが非常に困難です。
一般的な解決策はマップしたキーの後の右にコマンド区切りの "|" を置くことです。
その後に空白とコメントを続けます: >
unmap @@| # Vim9 script コメント
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>
バッファローカルなマップはそのバッファが削除されるときにいっしょに消去されま
す。アンロード(|: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>
すでにマップされている機能をそのままに、新たにマップを設定したい場合は、
|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()
前のコマンドが実行される前に、先行入力を探す時に式が評価されることがあることを
覚えておいてください。例: >
func StoreColumn()
let g:column = col('.')
return 'x'
endfunc
nnoremap <expr> x StoreColumn()
nmap ! f!x
g:column に "f!" 実行前の値がある、つまり "x" が評価されるのが "f!" の実行前で
あることに気付くでしょう。
これは評価のマッピングの文字の前に <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 を押してみます。すぐには何も起きません。どのマップを使うかを決定
するためには文字がもう一つ必要です。次に 'x' を押すと後者のマップが使われ、
"foo" が挿入されます。他のキーを押すと前者のマップが使われ、その文字が
getchar() によって取得され、返されます。
例を示します。リスト番号を自動的に増加させつつ挿入します: >
let counter = 0
inoremap <expr> <C-L> ListItem()
inoremap <expr> <C-R> ListReset()
func ListItem()
let g:counter += 1
return g:counter .. '. '
endfunc
func ListReset()
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>
<
<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| に入ることはありません。
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
ビジュアルモードとオペレータ待機モードの場合や、ノーマルモードとオペレータ待機
モードの場合も同様にします。
*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' がゼロ以外のときにマップ一覧を表示すると、どこで定義されたのかも表示
されます。例: >
:verbose map <C-W>*
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-multibyte*
マルチバイト文字をマップすることができます。ただし、マルチバイト文字の一部のバ
イトだけをマップすることはできません。それは次のような問題が起こるのを防ぐため
です: >
:set encoding=latin1
:imap <M-C> foo
:set encoding=utf-8
latin1 環境で文字「Ã」(0xc3 または <M-C>) をマップしています。例えば、「á」
(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
カウント指定の掛け算
マップの展開前にカウント指定が入力されると、そのカウントは {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はユーザーが
\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
これは、カーソルの上下移動のコマンドを入れ換えます。
普通の :map コマンドでマップを定義した場合、'remap' オプションがオンになってい
ると、そのマップが使用された後のテキスト ({rhs}) に {lhs} が含まれている限り、
マップが再帰的に繰り返されます。例えば、次のようなマップを使用する場合: >
:map x y
:map y x
Vim はまず、x を y で置き換え、それから 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 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"
これは modifyOtherKeys をレベル 2 に設定します。Note modifyOtherKeys レベル 1
は動作しないことに注意してください。いくつかの端末はレベル 2 をサポートしてお
らず Vim が正しく認識できないキーコードを送信します。
modifyOtherKeys モードで問題が発生する場合は、無効にすることができます: >
let &t_TI = ""
let &t_TE = ""
これはすぐには有効になりません。Vim を再起動せずにこれが動作するようにするに
は、シェルコマンドを実行します。例: `!ls`。あるいはこれらの行を |vimrc| に書い
てください。
modifyOtherKeys が有効化されているときは <C-[> と <C-S-{> をマップすることがで
きます: >
imap <C-[> [[[