forked from ma6174/vim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinsert.cnx
executable file
·1588 lines (1207 loc) · 70.7 KB
/
insert.cnx
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
*insert.txt* For Vim version 7.3. 最近更新: 2010年8月
VIM 参考手册 by Bram Moolenaar
译者: Willis,tocer
http://vimcdoc.sf.net
*Insert* *Insert-mode*
插入和替换文本 *mode-ins-repl*
本文件主要讨论插入和替换模式。最后讨论一些其它方式插入文本的命令。
最常用的命令的总览可以在用户手册第 24 章 |usr_24.txt| 找到。
1. 特殊键 |ins-special-keys|
2. 特殊的特殊键 |ins-special-special|
3. 'textwidth' 和 'wrapmargin' 选项 |ins-textwidth|
4. 'expandtab'、'smarttab' 和 'softtabstop' 选项 |ins-expandtab|
5. 替换模式 |Replace-mode|
6. 虚拟替换模式 |Virtual-Replace-mode|
7. 插入模式补全 |ins-completion|
8. 插入模式命令 |inserting|
9. Ex 插入命令 |inserting-ex|
10. 插入文件 |inserting-file|
关于如何移动光标到没有字符的位置,另见 'virtualedit'。对编辑表格有用。
==============================================================================
1. 特殊键 *ins-special-keys*
在插入和替换模式里,以下字符有特殊含义;其它字符被直接插入。要插入这些特殊字符
到缓冲区里,在前面加上 CTRL-V。要插入 <Nul> 字符,使用 "CTRL-V CTRL-@" 或者
"CTRL-V 000"。在有的系统上,你必须使用 "CTRL-V 003" 来插入 CTRL-C。注意: 如果
CTRL-V 被映射,你也许会经常使用 CTRL-Q 来代替 |i_CTRL-Q|。
如果插入时你在特殊的语言模式下工作,参见 'langmap' 选项 |'langmap'| 了解如何避
免反复进出这些模式。
如果置位了 'insertmode',<Esc> 和一些其它的键有另外的含义。见 |'insertmode'|。
字符 动作 ~
-----------------------------------------------------------------------
*i_CTRL-[* *i_<Esc>*
<Esc> 或 CTRL-[ 结束插入或替换模式,回到普通模式。结束缩写。
注意: 如果你很难在键盘上敲上 <Esc> 键,训练自己使用 CTRL-[。
*i_CTRL-C*
CTRL-C 退出插入模式,回到普通模式。不检查缩写。不激活 |InsertLeave|
自动命令事件。
*i_CTRL-@*
CTRL-@ 插入最近插入的文本,并停止插入 {Vi: 仅当敲入第一个字符时,而且
只限于前 128 个字符}
*i_CTRL-A*
CTRL-A 插入最近插入的文本。{Vi 无此功能}
*i_CTRL-H* *i_<BS>* *i_BS*
<BS> 或 CTRL-H 删除光标前的字符 (关于连接行,见 |i_backspacing|)。
如果你的 <BS> 键不正确,见 |:fixdel|。{Vi: 不删除自动的缩进}
*i_<Del>* *i_DEL*
<Del> 删除光标下的字符。如果光标在行尾,并且 'backspace' 选项包括
"eol",删除 <EOL>;下一行就此附加于当前行之后。
如果你的 <Del> 键不正确,见 |:fixdel|。{Vi: 不删除自动的缩进}
{Vi 无此功能}
*i_CTRL-W*
CTRL-W 删除光标前的单词 (关于连接行,见 |i_backspacing|)。关于单词的
定义,见 |word-motions| 关于 "单词动作" 的定义。
*i_CTRL-U*
CTRL-U 删除光标所有输入的字符 (关于连接行,见 |i_backspacing|)。
*i_CTRL-I* *i_<Tab>* *i_Tab*
<Tab> 或 CTRL-I 插入制表。如果打开 'expandtab' 选项,等价数目的空格被插入 (使
用 CTRL-V <Tab> 避免这种扩展: 如果 CTRL-V 被映射,可以使用
CTRL-Q <Tab>。|i_CTRL-Q|)。另见 'smarttab' 选项和
|ins-expandtab|。
*i_CTRL-J* *i_<NL>*
<NL> 或 CTRL-J 开始新行。
*i_CTRL-M* *i_<CR>*
<CR> 或 CTRL-M 开始新行。
*i_CTRL-K*
CTRL-K {char1} [char2]
输入二合字母 (见 |digraphs|)。当 {char1} 为特殊字符时,该键的
键码以 <> 形式插入。例如字符串 "<S-Space>" 可以这样输入:
<C-K><S-Space> (两个键)。两个键都不考虑映射。 {Vi 无此功能}
CTRL-N 查找下一个关键字 (见 |i_CTRL-N|)。{Vi 无此功能}
CTRL-P 查找上一个关键字 (见 |i_CTRL-P|)。{Vi 无此功能}
CTRL-R {0-9a-z"%#*+:.-=} *i_CTRL-R*
插入寄存器内容。在输入 CTRL-R 和第二个字符之间,'"' 会显示出
来,以提示你需要输入寄存器的名字。文本插入方式和直接输入相同,
但不使用映射和缩写。如果设置了 'textwidth'、'formatoptions' 或
'autoindent',插入的结果会受到影响。这和使用 "p" 命令和用鼠标
粘贴文本不同。
特殊寄存器:
'"' 无名寄存器,包含最近删除或抽出的文本
'%' 当前文件名
'#' 轮换文件名
'*' 剪贴板内容 (X11: 主选择)
'+' 剪贴板内容
'/' 最近的搜索模式
':' 最近的命令行
'.' 最近插入的文本
'-' 最近的行内 (少于一行) 删除
*i_CTRL-R_=*
'=' 表达式寄存器;你会被提示输入一个表达式 (见
|expression|)
注意 0x80 (十进制 128) 用于特殊键。例如,你可
以这样移动光标向上:
CTRL-R ="\<Up>"
用 CTRL-R CTRL-R 可以按本义插入文本。
如果结果是 |List|,里面的项目被看作行,之间以
换行符连接。
如果结果是浮点数,自动转化为字符串。
关于寄存器见 |registers|。{Vi 无此功能}
CTRL-R CTRL-R {0-9a-z"%#*+/:.-=} *i_CTRL-R_CTRL-R*
插入寄存器内容。和单个 CTRL-R 类似,但是文本按本义插入,而不是
像键盘输入那样。这意味着如果寄存器包含 <BS> 这样的字符,结果会
不同。例如,如果寄存器包含 "ab^Hc": >
CTRL-R a 产生 "ac"。
CTRL-R CTRL-R a 产生 "ab^Hc"。
< 'textwidth'、'formatoptions' 等等选项仍然适用。如果你连这些都
想避免,使用 "<C-R><C-O>r",见下。
'.' 寄存器 (最近插入的文本) 依然如同键盘输入那样的方式插入。
{Vi 无此功能}
CTRL-R CTRL-O {0-9a-z"%#*+/:.-=} *i_CTRL-R_CTRL-O*
按本义插入寄存器内容,并且不进行自动缩进。和鼠标粘贴文本相同
|<MiddleMouse>|。
不会替换字符!
'.' 寄存器 (最近插入的文本) 依然如同键盘输入那样的方式插入。
{Vi 无此功能}
CTRL-R CTRL-P {0-9a-z"%#*+/:.-=} *i_CTRL-R_CTRL-P*
按本义插入寄存器内容,修正缩进,和 |[<MiddleMouse>| 类似。
不会替换字符!
'.' 寄存器 (最近插入的文本) 依然如同键盘输入那样的方式插入。
{Vi 无此功能}
*i_CTRL-T*
CTRL-T 在当前行开始处插入一个 shiftwidth 的缩进。缩进总是取整到
'shiftwidth' 的倍数 (这是 vi 兼容的)。
{Vi: 只有在缩进内部才能用}
*i_CTRL-D*
CTRL-D 在当前行开始处删除一个 shiftwidth 的缩进。缩进总是取整到
'shiftwidth' 的倍数 (这是 vi 兼容的)。
{Vi: CTRL-D 只有在使用自动缩进之后才有效}
*i_0_CTRL-D*
0 CTRL-D 删除所有当前行的缩进。
{Vi: CTRL-D 只有在使用自动缩进之后才有效}
*i_^_CTRL-D*
^ CTRL-D 删除当前行的所有缩进。缩进在下一行上恢复。这可以用于插入卷标。
{Vi: CTRL-D 只有在使用自动缩进之后才有效}
*i_CTRL-V*
CTRL-V 如果下一个是非数字,按本义插入。对特殊键而言,插入其终端代码。
不然,输入的是字符的十、八或十六进制值。|i_CTRL-V_digit|。
CTRL-V 之后紧接着输入的字符不经过映射。
{Vi: 没有十进制字节输入}
注意: 当 CTRL-V 被映射时 (例如,用来粘贴文本),你可能经常需要
使用 CTRL-Q 来代替。|i_CTRL-Q|。
*i_CTRL-Q*
CTRL-Q 等同于 CTRL-V。
注意: 有的终端连接会吃掉 CTRL-Q,导致该快捷键无效。在 GUI 版本
里就不会出现这样的问题。
CTRL-X 进入 CTRL-X 模式,一个子模式。那里你可以给出命令来补全单词或者
滚动窗口。见 |i_CTRL-X| 和 |ins-completion|。{Vi 无此功能}
*i_CTRL-E*
CTRL-E 插入光标下面的字符。{Vi 无此功能}
*i_CTRL-Y*
CTRL-Y 插入光标上面的字符。{Vi 无此功能}
注意 CTRL-E 和 CTRL-Y 不使用 'textwidth',从而可以从长行里复制
字符。
*i_CTRL-_*
CTRL-_ 切换语言,如下:
- 在从右到左的窗口里,切换 revins 和 nohkmap,因为在这种情况
下英语的输入可能就是倒过来的。
- 在非从右到左的窗口里,切换 revins 和 hkmap。因为希伯来语等
语种可能是倒过来输入的。
CTRL-_ 移动光标到输入文本的尾部。
该命令只有在 'allowrevins' 选项置位的时候才有效。
请参考 |rileft.txt|,那里可以了解到更多有关从右到左模式的信
息。{Vi 无此功能}
只有在编译时加入 |+rightleft| 特性才有效。
*i_CTRL-^*
CTRL-^ 切换语言字符输入的使用方式。
如果定义了语言映射 |:lmap|:
- 如果 'iminsert' 为 1 (使用 langmap 映射),变成 0 (不使用
langmap 映射)。
- 如果 'iminsert' 为其它值,变成 1,这样打开了 langmap 映射。
如果没有定义语言映射:
- 如果 'iminsert' 为 2 (使用输入方法 (Input Method)),变成 0
(不使用输入方法)。
- 如果 'iminsert' 为其它值,变成 2,从而打开输入方法。
如果 "b:keymap_name" 变量的值设为 1,'keymap' 选项或者
"<lang>" 出现在状态行上。语言映射通常用来输入不同于键盘上能直
接产生的字符。'keymap' 选项用来安装若干完整的映射表。{Vi 无此
功能}
*i_CTRL-]*
CTRL-] 切换缩写,不插入字符。{Vi 无此功能}
*i_<Insert>*
<Insert> 切换插入和替换模式。{Vi 无此功能}
-----------------------------------------------------------------------
*i_backspacing*
<BS>、CTRL-W 和 CTRL-U 的效果决定于 'backspace' 选项 (除非置位了 'revins')。这
时一个逗号分隔的项目列表:
项目 动作 ~
indent 允许退格删除自动缩进
eol 允许退格删除换行符 (连接行)
start 允许退格删除插入开始之前的位置;CTRL-W 和 CTRL-U 在开始位置停止
如果 'backspace' 为空,则使用 Vi 兼容的退格方式。不能退格删除自动缩进、回到第
一列之前、或者超过插入开始的地方。
为了后向兼容起见,取值 "0"、"1" 和 "2" 也是允许的,见 |'backspace'|。
如果 'backspace' 选项的确包含 "eol",光标在第一列,而使用了这三个键中的一个,
当前行会和上一行连接。这实际上删除了光标之前的 <EOL>。
{Vi: 不会跨行,不会删除插入开始位置之前的内容}
*i_CTRL-V_digit*
使用 CTRL-V,字符的十、八、十六进制值可以直接输入。这样你可以输入任何字符,除
了换行符 (<NL>,其值为 10)。有五个方法可以输入字符值:
第一个字符 模式 最大字符数 最大值 ~
(无) 十进制 3 255
o 或 O 八进制 3 377 (255)
x 或 X 十六进制 2 ff (255)
u 十六进制 4 ffff (65535)
U 十六进制 8 7fffffff (2147483647)
通常你会输入最大数目的字符数。这样,要输入空格 (值为 32),你需要键入
<C-V>032。你可以忽略开头的零,这时,数字之后的字符必须不能再是数字。其它模式下
也一样: 一旦你输入在该模式下不合法的字符,那么这之前的值就会被使用,而 "非法"
的这个字符以正常的方式继续处理。
如果你输入的值为 10,在文件中最后会以 0 出现。10 是 <NL>,内部被用来代表 <Nul>
字符。在写入文件时,<NL> 字符被翻译成 <Nul>。而在每行的最后写入 <NL>。所以,如
果你想在文件中插入 <NL> 字符,你需要使用换行。
*i_CTRL-X* *insert_expand*
CTRL-X 进入一个子模式,那里可以使用若干命令。绝大多数命令执行关键字补全;见
|ins-completion|。只有在 Vim 编译时加入 |+insert_expand| 特性才能使用这些功
能。
有两个命令可以在不退出插入模式的前提下上下滚动窗口:
*i_CTRL-X_CTRL-E*
CTRL-X CTRL-E 窗口滚动上移一行。
补全时看这里:|complete_CTRL-E|
*i_CTRL-X_CTRL-Y*
CTRL-X CTRL-Y 窗口滚动下移一行。
补全时看这里:|complete_CTRL-Y|
按了 CTRL-X 以后,每个 CTRL-E (CTRL-Y) 滚动窗口上 (下) 移一行,除非这使得光标
不得不离开当前文件中所在的位置。一旦按了另外一个键,CTRL-X 模式就会退出,而回
到插入模式下解释该键。
==============================================================================
2. 特殊的特殊键 *ins-special-special*
一些的键是特殊的。它们停止当前的插入,做一些事情,然后重新插入。这意味着你可以
不脱离插入模式的情况下做一些事情。这适合于经常使用插入模式的用户,就像编辑器没
有单独的普通模式一样。这时,也可以设置 'backspace' 选项为 "indent,eol,start"
还有置位 'insertmode' 选项。如果你想给功能键映射到一个命令,你可以使用
CTRL-O。
这些键前后的改动 (插入或者删除字符) 可以分别撤销。只有最后的改动可以重做,而其
行为和 "i" 命令相当。
字符 动作 ~
-----------------------------------------------------------------------
<Up> 光标上移一行 *i_<Up>*
<Down> 光标下移一行 *i_<Down>*
CTRL-G <Up> 光标上移一行,到插入开始时所在的列 *i_CTRL-G_<Up>*
CTRL-G k 光标上移一行,到插入开始时所在的列 *i_CTRL-G_k*
CTRL-G CTRL-K 光标上移一行,到插入开始时所在的列 *i_CTRL-G_CTRL-K*
CTRL-G <Down> 光标下移一行,到插入开始时所在的列 *i_CTRL-G_<Down>*
CTRL-G j 光标下移一行,到插入开始时所在的列 *i_CTRL-G_j*
CTRL-G CTRL-J 光标下移一行,到插入开始时所在的列 *i_CTRL-G_CTRL-J*
<Left> 光标左移一个字符 *i_<Left>*
<Right> 光标右移一个字符 *i_<Right>*
<S-Left> 光标反向一个单词 (像 "b" 命令那样) *i_<S-Left>*
<C-Left> 光标反向一个单词 (像 "b" 命令那样) *i_<C-Left>*
<S-Right> 光标正向一个单词 (像 "w" 命令那样) *i_<S-Right>*
<C-Right> 光标正向一个单词 (像 "w" 命令那样) *i_<C-Right>*
<Home> 光标移到该行第一个字符 *i_<Home>*
<End> 光标移到该行最后一个字符 *i_<End>*
<C-Home> 光标移到该文件第一个字符 *i_<C-Home>*
<C-End> 光标移到该文件最后一个字符 *i_<C-End>*
<LeftMouse> 光标移动鼠标点击处 *i_<LeftMouse>*
<S-Up> 上翻窗口一页 *i_<S-Up>*
<PageUp> 上翻窗口一页 *i_<PageUp>*
<S-Down> 下翻窗口一页 *i_<S-Down>*
<PageDown> 下翻窗口一页 *i_<PageDown>*
<ScrollWheelDown> 窗口向下滚动三行 *i_<ScrollWheelDown>*
<S-ScrollWheelDown> 窗口向下滚动一个整页 *i_<S-ScrollWheelDown>*
<ScrollWheelUp> 窗口向上滚动三行 *i_<ScrollWheelUp>*
<S-ScrollWheelUp> 窗口向上滚动一个整页 *i_<S-ScrollWheelUp>*
<ScrollWheelLeft> 窗口向左滚动六列 *i_<ScrollWheelLeft>*
<S-ScrollWheelLeft> 窗口向左滚动一个整页 *i_<S-ScrollWheelLeft>*
<ScrollWheelRight> 窗口向右滚动六列 *i_<ScrollWheelRight>*
<S-ScrollWheelRight> 窗口向右滚动一个整页 *i_<S-ScrollWheelRight>*
CTRL-O 执行命令,然后返回到插入模式 *i_CTRL-O*
CTRL-\ CTRL-O 类似于 CTRL-O,但不移动光标 *i_CTRL-\_CTRL-O*
CTRL-L 置位 'insertmode' 时: 转到普通模式 *i_CTRL-L*
CTRL-G u 打断撤销序列,开始新的改变 *i_CTRL-G_u*
-----------------------------------------------------------------------
注意: 如果光标键把你带出插入模式,查查 'noesckeys' 选项。
CTRL-O 命令有时有副作用: 如果光标在行尾之后,它会先被移动该行最后一个字符上。
在映射里,通常更好的方法是使用 <Esc> (先在文本中放一个 "x",<Esc> 这时总会把
光标放到它的上面)。或者使用 CTRL-\ CTRL-O,不过这时要注意光标可能移到行尾之外
的位置。
不是在所有的终端上都能用 Shift + 光标键。
另外一个副作用是 "i" 或 "a" 命令之前指定的计数会被忽略。这是因为要实现 CTRL-O
之后的命令的重复执行太复杂了。
一个使用 CTRL-G u 的例子: >
:inoremap <C-H> <C-G>u<C-H>
它重定义退格键开始新的撤销序列。你可以撤销退格键的效果,而不会改变你之前输入的
内容,就像 CTRL-O u 那样。
CTRL-O 的使用分割撤销: 之前输入的文本和之后的被分别撤销。如果不想如此 (比如用
在映射里),你可以用 CTRL-R = |i_CTRL-R|。例如,要调用函数: >
:imap <F2> <C-R>=MyFunc()<CR>
如果正确设置 'whichwrap' 选项,在一行的第一个/最后一个字符上按 <Left> 和
<Right> 键使得光标回绕到上一行/下一行。
CTRL-G j 和 CTRL-G k 命令可以用来在某一列前插入文本。例如: >
int i;
int j;
把光标定位在第一个 "int" 上,输入 "istatic <C-G>j "。结果是: >
static int i;
int j;
要把相同的文本插入在每行的某列之前,使用可视列块命令 "I" |v_b_I|。
==============================================================================
3. 'textwidth' 和 'wrapmargin' 选项 *ins-textwidth*
'textwidth' 选项可以用来在行变得很长之前自动断行。设置 'textwidth' 选项为希望
的最大行长。如果你输入更多字符 (不是空格或者制表),最后一个单词会放在一个新行
上 (除非这是该行唯一一个单词)。如果你设置 'textwidth' 为 0,关闭该特性。
'wrapmargin' 选项做的事情基本相同。区别在于 'textwidth' 是一个固定的宽度,而
'wrapmargin' 根据屏幕的宽度设置。如果设置 'wrapmargin',这等价于 'textwidth'
设为 (columns - 'wrapmargin'),其中 columns 是屏幕的宽度。
如果同时设置 'textwidth' 和 'wrapmargin',使用 'textwidth'。
如果你并不真的想断开行,而只是想文本行在合适的位置回绕,见 'linebreak' 选项。
文本行只有在插入模式下或者附加到行后的时候才会自动断开。在替换模式下,只要行的
长度没有变,就不会断行。
长行在你输入一个出现在边界之后的非空白字符的时候断开。什么时候断行的限制还可以
通过在 'formatoptions' 选项增加如下字母决定:
"l" 断行只有在插入开始时文本行的长度不超过 'textwidth' 才会发生。
"v" 只有在当前插入命令中输入的空白字符上才会断行。这是和 Vi 最兼容的行为。
"lv" 断行只有在插入开始时文本行的长度不超过 'textwidth' 并且在当前插入命令中输
入的空白字符上才会发生。和 "l" 唯一的不同在超过 'textwidth' 边界之后输入
非空白字符的时候。
通常使用内部函数来决定哪里断行。如果你想使用不同的方法,设置 'formatexpr' 选项
为一个表达式,它处理换行的行为。
如果你想排版文本块,可以使用 "gq" 操作符。输入 "gq" 和可以移动光标到块尾的移动
命令。在许多情况下,命令 "gq}" 会做你想要做的事情 (排版直到段落尾部)。或者,你
可以使用 "gqap"。它会排版整个段落,和当前光标所在的位置无关。或者,你可以使用
可视模式: 敲击 "v",移动到块尾,然后输入 "gq"。另见 |gq|。
==============================================================================
4. 'expandtab'、'smarttab' 和 'softtabstop' 选项 *ins-expandtab*
如果打开 'expandtab' 选项,空格可以用来填充制表键的空白位置。如果你需要输入一
个真正的 <Tab>,先输入 CTRL-V (用 CTRL-Q 如果 CTRL-V 被映射的话 |i_CTRL-Q|)。
缺省 'expandtab' 选项是关闭的。注意 在替换模式里,一个字符被多个空格字符所代
替。结果是,行内的字符数会增加。退格键只会一次删一个空格键。原来的字符只有在一
个空格 (最后一个) 上退格才能得回来 {Vi 没有 'expandtab' 选项}
*ins-smarttab*
当 'smarttab' 选项打开时,<Tab> 在行首插入 'shiftwidth' 个位置,而在其它地方插
入 'tabstop' 个。这意味着经常会插入空格而不是 <Tab> 字符。当 'smarttab' 关闭
时,<Tab> 总是插入 'tabstop' 个位置,而 'shiftwidth' 只有在 ">>" 和类似的命令
中才会用到。{Vi 无此功能}
*ins-softtabstop*
如果 'softtabstop' 选项不为零,<Tab> 插入 'softtabstop' 个位置,而过去用来删除
空格的 <BS>,现在会删除 'softtabstop' 个位置。感觉上, 'tabstop' 被设成了
'softtabstop' 的值,但实际上一个真正的 <Tab> 字符还是占据 'tabstop' 个位置。从
而,你的文件在别的应用程序里看起来还是正确的。
如果 'softtabstop' 不为零,<BS> 会试图删除尽量多的空白,以便能够回到往前
'softtabstop' 的位置,除非前面一个插入的字符正好就是一个空格,这时它只会删除光
标前的那个字符。否则,你不一定总能删除光标前的一个字符。你需要先删除
'softabstop' 个字符,然后再输入额外的空格,以到达你想要的地方。
==============================================================================
5. 替换模式 *Replace* *Replace-mode* *mode-replace*
在普通模式里输入 "R" 命令进入替换模式。
在替换模式里,行内的单个字符在你输入字符的时候被删除。如果没有字符可以删了 (在
行尾),输入的字符被附加 (和插入模式一样)。这样,一行内的字符数保持不变,直到你
到达行尾为止。如果输入了 <NL>,插入一个换行符,但不会删除任何字符。
要小心 <Tab> 字符。如果你输入一个正常的打印字符在它上面,字符数仍然一样,但是
列数看起来少了。
如果你在替换模式下删除字符 (用 <BS>、CTRL-W 或 CTRL-U),实际发生的事是你删除了
改变。被替换的字符被复原了。如果你的输入超过已有的部分,新增的字符被删除了。实
际上,这可以看作是一次一个字符的撤销。
如果打开了 'expandtab' 选项,<Tab> 会用多个空格替换一个字符。结果是,行内的字
符数增加了。退格键只能一次删一个空格。原来的字符只有在一个空格 (最后一个) 上退
格才能得回来 {Vi 没有 'expandtab' 选项}
==============================================================================
6. 虚拟替换模式 *vreplace-mode* *Virtual-Replace-mode*
在普通模式里输入 "gR" 命令进入虚拟替换模式。
{仅当编译时加入 |+vreplace| 特性才会有效}
{Vi 没有虚拟替换模式}
虚拟替换模式和替换模式类似,但不是替换文件里的实际字符,而是替换屏幕的领地。这
样,文件里的字符看起来不会移动。
所以,如果你输入了 <Tab>,它会替换多个普通的字符,而如果你在 <Tab> 上输入字
母,它可能什么都没有代替,因为 <Tab> 还是会占据相同的位置。
输入 <NL> 不是导致文件后面的字符看起来在移动。结果是,当前行的后面部分被 <NL>
所替换 (也就是,它们被删除),而替换继续在下一行进行。新行_不_会被插入,除非你
到达文件尾部之后。
输入 CTRL-T 和 CTRL-D 会看到有趣的效果。光标前面的字符向一边移动,跟平常一样,
但是光标后面的字符保持不动。CTRL-T 会隐藏一些被移动字符遮盖的旧行,但是 CTRL-D
会重新让它们显现出来。
和替换模式一样,使用 <BS> 等会恢复被替换的字符。即使和 'smartindent'、CTRL-T
和 CTRL-D、'expandtab'、'smarttab'、'softtabstop' 等一起使用的效果也是如此。
在 'list' 模式下,虚拟替换模式的行为和不在 'list' 模式下一样,除非 'cpoptions'
里设置了 "L"。
注意 唯一不在光标位置上的字符看起来在移动的可能是在 'list' 模式下,偶尔也会在
置位 'wrap' 的时候出现 (这时行改变长度,使得比屏幕宽度更窄或者更宽),难得也会
在输入 CTRL 字符的时候。CTRL 字符占据两个屏幕位置。如果用两个普通字符替换,第
一个会被插入,而第二个会替换 CTRL 字符。
该模式对编辑 <Tab> 分隔表格列的时候很有用,因为输入新的数据的时候同时还能保持
所有的列对齐。
==============================================================================
7. 插入模式补全 *ins-completion*
在插入和替换模式下,有若干命令可以补全输入的部分关键字或者行。这可以用于使用复
杂关键字的场合 (例如,函数名里有大写字母或者下划线)。
如果编译时关闭了 |+insert_expand| 特性,这些功能都不可用。
补全可以是针对:
1. 整行 |i_CTRL-X_CTRL-L|
2. 当前文件内的关键字 |i_CTRL-X_CTRL-N|
3. 'dictionary' 的关键字 |i_CTRL-X_CTRL-K|
4. 'thesaurus' 的关键字,同义词风格 |i_CTRL-X_CTRL-T|
5. 当前和头文件内的关键字 |i_CTRL-X_CTRL-I|
6. 标签 |i_CTRL-X_CTRL-]|
7. 文件名 |i_CTRL-X_CTRL-F|
8. 定义或宏 |i_CTRL-X_CTRL-D|
9. Vim 命令 |i_CTRL-X_CTRL-V|
10. 用户定义的补全 |i_CTRL-X_CTRL-U|
11. 全能 (omni) 补全 |i_CTRL-X_CTRL-O|
12. 拼写建议 |i_CTRL-X_s|
13. 'complete' 的关键字 |i_CTRL-N|
所有这些 (除了 2 以外 (译者注: 原文如此)) 都通过 CTRL-X 模式完成。这是插入和替
换模式的一个子模式。你可以键入 CTRL-X 和一个 CTRL-X 命令进入 CTRL-X 模式。要退
出,输入不合法的 CTRL-X 模式的命令。合法的键包括 CTRL-X 命令本身,CTRL-N (下一
个) 和 CTRL-P (前一个)。
如果你想调整匹配的大小写,参见 'infercase' 选项。
*complete_CTRL-E*
如果补全处于激活状态,可以用 CTRL-E 来停止补全并回到原来录入的文字。CTRL-E 本
身不会被插入。
*complete_CTRL-Y*
如果已经弹出菜单,可以使用 CTRL-Y 停止补全并接受当前的选择项。CTRL-Y 本身不会
被插入。键入空格、回车或者其他不可显示字符将离开补全模式并插入键入的字符。
弹出菜单显示时,有一些特殊键可用,见 |popupmenu-keys|。
注意: CTRL-X 模式下合法的键不经过映射。这使得 ":map ^F ^X^F" 能够工作 (其中 ^F
是 CTRL-F 而 ^X 是 CTRL-X)。能够使得 CTRL-X 模式退出的键 (任何不是合法 CTRL-X
模式命令的键) 则经过映射。
另外,通过 'complete' 的补全也使用映射。
注意: 补全激活时,不能递归使用插入模式。以某种方式调用 ":normal i.." 的映射将
产生 E523 错误。
建议使用以下映射来使得输入补全命令简单一点 (不过它们可能屏蔽其它的命令): >
:inoremap ^] ^X^]
:inoremap ^F ^X^F
:inoremap ^D ^X^D
:inoremap ^L ^X^L
一个特例是,执行寄存器插入的 CTRL-R (见 |i_CTRL-R|) 不会退出 CTRL-X 模式。这主
要是为了允许通过使用 '=' 寄存器来调用若干函数来决定下一个操作。如果该寄存器的
内容 (或者 '=' 寄存器计算的结果) 不是合法的 CTRL-X 模式键,那么就会退出 CTRL-X
模式,如同键盘输入这些内容一样。
例如,下面的程序会如此映射 <Tab>: 如果当前行只有空白,就插入 <Tab>,不然就开始
或继续 CTRL-N 补全操作: >
function! CleverTab()
if strpart( getline('.'), 0, col('.')-1 ) =~ '^\s*$'
return "\<Tab>"
else
return "\<C-N>"
endif
endfunction
inoremap <Tab> <C-R>=CleverTab()<CR>
补全整行 *compl-whole-line*
*i_CTRL-X_CTRL-L*
CTRL-X CTRL-L 反向搜索和当前行光标前字符序列完全相同的行。忽略缩进。
找到的行插入在光标的前面。
'complete' 选项用来决定匹配在哪个缓冲区里搜索,已载入
和未载入的缓冲区都被使用。
CTRL-L 或
CTRL-P 反向搜索前一个匹配行。替换上一次匹配的行。
CTRL-N 正向搜索下一个匹配行。替换上一次匹配的行。
CTRL-X CTRL-L 在扩展一行以后,你可以通过接着输入 CTRL-X CTRL-L 得到
紧接着匹配行之后的行,直到见到两个 CTRL-X 为止。只能用
于已载入的缓冲区。
补全当前文件内的关键字 *compl-current*
*i_CTRL-X_CTRL-P*
*i_CTRL-X_CTRL-N*
CTRL-X CTRL-N 正向搜索以光标前面的关键字开始的单词。找到的关键字插入
在光标的前面。
CTRL-X CTRL-P 反向搜索以光标前面的关键字开始的单词。找到的关键字插入
在光标的前面。
CTRL-N 正向搜索下一个匹配的关键字。替换上一次匹配的关键字。
CTRL-P 反向搜索前一个匹配的关键字。替换上一次匹配的关键字。
CTRL-X CTRL-N 或
CTRL-X CTRL-P 继续使用 CTRL-X CTRL-N 或 CTRL-X CTRL-P 会复制上次本类
型补全在其它上下文里扩展的单词之后紧跟的单词,直到见到
两个 CTRL-X 为止。
如果在光标的前面有一个关键字 (由字母字符和 'iskeyword' 指定的字符组成的名字),
它的前面再加上 "\<" (含义: 单词开始) 就被用作搜索模式。否则 "\<\k\k" 被用作搜
索模式 (任何包含至少两个字符的关键字的开始)。
在替换模式里,替换的字符数目决定于匹配字符串的长度。这和直接在替换模式下键盘输
入经过替换的字符串类似。
如果光标前面不是一个合法的关键字字符,则匹配任何至少有两个字符的关键字。
例如,要得到:
printf("(%g, %g, %g)", vector[0], vector[1], vector[2]);
只需输入:
printf("(%g, %g, %g)", vector[0], ^P[1], ^P[2]);
搜索会在文件末尾回绕,这里不使用 'wrapscan' 的值。
相同的补全内容多次重复会被跳过;这样每次 CTRL-N 和 CTRL-P 都会插入不同的匹配
(除非只有一个匹配的关键字)。
永远不会得到单个字符的匹配,因为它们通常不是你真想要的。
例如,要得到:
printf("name = %s\n", name);
或者:
printf("name = %s\n", n^P);
甚至:
printf("name = %s\n", ^P);
'\n' 中的 'n' 被跳过。
在扩展完一个词后,你可以使用 CTRL-X CTRL-P 或 CTRL-X CTRL-N 得到紧跟在扩展词
之后的单词。这些序列搜索刚刚扩展的文本,并且继续扩展之,使之包括另外一个词。这
可以用于你需要重复一系列复杂的单词的场合。尽管 CTRL-P 和 CTRL-N 只找至少两个字
符的字符串,CTRL-X CTRL-P 和 CTRL-X CTRL-N 可以用来扩展只有一个字符的单词。
例如,要得到:
México
你可以输入:
M^N^P^X^P^X^P
CTRL-N 开始一个扩展,而 CTRL-P 回到单个字符 "M",然后后面的两个 CTRL-X CTRL-P
分别得到 "é" 和 ";xico"。
如果上次的扩展因为超过 'textwidth' 被分割,则只会使用当前行的文本。
如果匹配在行尾,那么下一行的第一个单词会被插入,而且显示消息 "word from next
line"。如果该词被接受,那么下个 CTRL-X CTRL-P 或者 CTRL-X CTRL-N 会搜索那些以
这个单词开始的行。
补全 'dictionary' 的关键字 *compl-dictionary*
*i_CTRL-X_CTRL-K*
CTRL-X CTRL-K 根据 'dictionary' 选项给出的文件搜索光标前关键字开始的
单词。这和 CTRL-N 类似,只不过搜索的是字典文件,而不是
当前文件。找到的关键字插入在光标之前。这可能很慢,因为
在第一个匹配用到之前,所有的匹配都会被找到。缺省,
'dictionary' 选项为空。
要得到哪里能找单词列表的建议,见 'dictionary' 选项。
CTRL-K 或
CTRL-N 正向搜索下一个匹配的关键字。替换上一次匹配的关键字。
CTRL-P 反向搜索前一个匹配的关键字。替换上一次匹配的关键字。
*i_CTRL-X_CTRL-T*
CTRL-X CTRL-T 和 CTRL-X CTRL-K 类似,但稍有不同。它使用 'thesaurus'
选项,而不是 'dictionary'。如果匹配在同义词字典里找
到,同一行里其余单词也在匹配里列出,即使它们并不真的匹
配。这样一个单词可以被完全替换。
举一个例子,假想 'thesaurus' 文件有一行形如: >
angry furious mad enraged
< 把光标放在字母 "ang" 之后并输入 CTRL-X CTRL-T 会匹配单
词 "angry";继续按会把单词改为 "furious"、"mad" 等等。
其它的使用包括两种语言之间的翻译,或者用关键字给 API
函数归类。
CTRL-T 或
CTRL-N 正向搜索下一个匹配的关键字。替换上一次匹配的关键字。
CTRL-P 反向搜索前一个匹配的关键字。替换上一次匹配的关键字。
补全当前和头文件内的关键字 *compl-keyword*
'include' 选项指定如何找到含有头文件名字的行。'path' 选项用来搜索头文件。
*i_CTRL-X_CTRL-I*
CTRL-X CTRL-I 搜索当前和头文件里第一个以光标前面的字母序列开始的关键
字。找到的关键字插入在光标的前面。
CTRL-N 正向搜索下一个匹配的关键字。替换上一次匹配的关键字。
注意: CTRL-I 和 <Tab> 相同,而这可能会在成功的补全之后
输入,因此不使用 CTRL-I 来搜索下一个匹配。
CTRL-P 反向搜索前一个匹配的关键字。替换上一次匹配的关键字。
CTRL-X CTRL-I 继续使用 CTRL-X CTRL-I 会复制上次本类型补全在其它上下
文里扩展的单词之后紧跟的单词,直到见到两个 CTRL-X 为
止。
补全标签 *compl-tag*
*i_CTRL-X_CTRL-]*
CTRL-X CTRL-] 搜索第一个以光标前面的字母序列开始的标签。匹配的标签插
在光标前面。标签名可以包含字母字符和由 'iskeyword' 决
定的字符 (和关键字相同)。另见 |CTRL-]|。
'showfulltag' 选项可以用来增加标签定义前后的上下文。
CTRL-] 或
CTRL-N 正向搜索下一个匹配的标签。替换上一次匹配的标签。
CTRL-P 反向搜索前一个匹配的标签。替换上一次匹配的标签。
补全文件名 *compl-filename*
*i_CTRL-X_CTRL-F*
CTRL-X CTRL-F 搜索第一个以光标前面的字母序列开始的文件。匹配的文件插
在光标前面。标签名可以包含字母字符和由 'isfname' 决
定的字符 (和关键字相同)。注意,(目前) 这里不使用
'path' 选项。
CTRL-F 或
CTRL-N 正向搜索下一个匹配的文件名。替换上一次匹配的文件名。
CTRL-P 反向搜索前一个匹配的文件名。替换上一次匹配的文件名。
补全定义或宏 *compl-define*
'define' 选项用来指定包含定义的行。'include' 选项用来指定包含头文件名的行。
'path' 选项用来搜索头文件。
*i_CTRL-X_CTRL-D*
CTRL-X CTRL-D 搜索当前和头文件里第一个以光标前面的字母序列开始的
定义 (或宏)。找到的定义名插入在光标的前面。
CTRL-D 或
CTRL-N 正向搜索下一个匹配的定义。替换上一次匹配的定义。
CTRL-P 反向搜索前一个匹配的定义。替换上一次匹配的定义。
CTRL-X CTRL-D 继续使用 CTRL-X CTRL-D 会复制上次本类型补全在其它上下
文里扩展的单词之后紧跟的单词,直到见到两个 CTRL-X 为
止。
补全 Vim 命令 *compl-vim*
这里,补全是上下文敏感的,和命令行上的情况相似。它既能补全 Ex 命令,又能补全它
的参数。可用于编写 Vim 脚本。
*i_CTRL-X_CTRL-V*
CTRL-X CTRL-V 猜测光标前的项目的条目,并找到第一个匹配。
注意: 如果 CTRL-V 被映射,你通常可以用 CTRL-Q 来代替
|i_CTRL-Q|。
CTRL-V 或
CTRL-N 正向搜索下一个匹配。替换上一次匹配。
CTRL-P 反向搜索前一个匹配。替换上一次匹配。
CTRL-X CTRL-V 继续使用 CTRL-X CTRL-V 和 CTRL-V 一样。这允许映射键来
执行 Vim 命令补全,例如: >
:imap <Tab> <C-X><C-V>
用户定义补全 *compl-function*
命令补全可以由用户通过 'completefunc' 选项自定义一个函数来完成。下面说明如何调
用此函数,并提供示例 |complete-functions|。
*i_CTRL-X_CTRL-U*
CTRL-X CTRL-U 猜测光标前面项目的类型,并寻找它的第一个匹配。
CTRL-U 或
CTRL-N 正向搜索下一个匹配。替换上一次匹配。
CTRL-P 反向搜索前一个匹配。替换上一次匹配。
全能 (omni) 补全 *compl-omni*
命令补全可以由用户通过 'omnifunc' 选项自定义一个函数来完成。这通常用于特定文件
类型的补全。
下面说明如何调用此函数,并提供示例 |complete-functions|。
关于特定文件类型的说明,见 |compl-omni-filetypes|。
将来会有更多补全脚本,欢迎查阅 www.vim.org。目前已经有了 C++ 的首个版本。
*i_CTRL-X_CTRL-O*
CTRL-X CTRL-O 猜测光标前面项目的类型,并寻找它的第一个匹配。
CTRL-O 或
CTRL-N 正向搜索下一个匹配。替换上一次匹配。
CTRL-P 反向搜索前一个匹配。替换上一次匹配。
拼写建议 *compl-spelling*
定位光标所在或之前的单词,然后提出正确拼写的单词作为建议进行替代。如果该行里有
一个错误拼写的单词在光标之前或之下,移动光标到它后面。否则,使用刚刚在光标之前
的那个单词来提出建议,即使该单词没有拼写错误。
NOTE: 很多 Unix 终端上,CTRL-S 暂停显示。这时用 's' 可以代替。如果显示暂停,输
入 CTRL-Q 会继续显示。
*i_CTRL-X_CTRL-S* *i_CTRL-X_s*
CTRL-X CTRL-S 或
CTRL-X s 定位光标之前的单词,并寻找它的第一个拼写建议。
CTRL-S 或
CTRL-N 正向搜索下一个建议。替换上一次的建议。 注意 这里不能用
's'。
CTRL-P 反向搜索前一个建议。替换上一次的建议。
从不同的来源补全关键字 *compl-generic*
*i_CTRL-N*
CTRL-N 在 'complete' 选项给出的地方搜索下一个以光标前面的关键
字开始的单词。找到的关键字名插入在光标的前面。
*i_CTRL-P*
CTRL-P 在 'complete' 选项给出的地方搜索上一个以光标前面的关键
字开始的单词。找到的关键字名插入在光标的前面。
CTRL-N 正向搜索下一个匹配的关键字。替换上一次匹配的关键字。
CTRL-P 反向搜索前一个匹配的关键字。替换上一次匹配的关键字。
CTRL-X CTRL-N 或
CTRL-X CTRL-P 继续使用 CTRL-X CTRL-N 或 CTRL-X CTRL-P 会复制上次本类
型补全在其它上下文里扩展的单词之后紧跟的单词,直到见到
两个 CTRL-X 为止。
寻 找 补 全 的 函 数 *complete-functions*
这里指 'completefunc' 和 'omnifunc'。
函数被调用两次,使用不同的方式:
- 首先,调用函数以寻找补全文本的开始位置。
- 然后,调用函数以寻找实际的匹配。
第一次调用时,参数是:
a:findstart 1
a:base 空
函数必须返回补全开始位置的列数,这个数字必须在零到光标所在列 "col('.')" 之间。
过程应该检查光标之前的字符,并包含那些可能成为补全项一部分的字符。该列到光标列
之间的文本将来会被匹配结果替换。如果补全无法进行,返回 -1。
第二次调用时,参数是:
a:findstart 0
a:base 补全必须匹配的文本;即第一次调用定位的文本 (可以为空)
函数必须返回匹配单词的列表。这些匹配通常包含 "a:base" 文本。如果没有匹配,返回
空列表。
*complete-items*
每个列表项可以是字符串或者字典类型。如果是字符串,直接用作补全文本。如果是字
典,可以包含以下各项:
word 需要插入的文本,必需
abbr "word" 的缩写;如果非空,菜单里使用它而不是 "word"
menu 用于弹出菜单的补充文本,在 "word" 或 "abbr" 之后显示
info 关于补全项的更多信息,能够在预览窗口显示
kind 代表补全类型的单个字母
icase 如果非零,比较项目是否等同时忽略大小写;如果省略就假定
为零,这时可以同时加入只有大小写有差异的匹配项
dup 如果非零,那么即使和此匹配包含相同单词的匹配项已经存在
也无妨。
除了 'icase' (译者注: 还有 'dup') 以外,其它各项必须是字符串。如果有一项不合要
求,报错,而列表的其余项目也不再使用。你可以在返回列表中混用字符串和字典项目。
"menu" 项目用于弹出菜单且可能被截短,所以它应该尽量简短。"info" 项目可以稍长。
如果在 'completeopt' 中包含 "preview",预览窗口会显示该项信息。关闭弹出菜单后,
"info" 项目将保留显示,这对录入函数参数很有用。用单个空格设置 "info" 可以清除
预览窗口现存的文本。
"kind" 项目用单一字母表示补全类型。用它可以指定补全的不同显示方式 (不同颜色或
者图标)。目前,可用如下类型:
v 变量
f 函数或方法
m 结构或类成员
t typedef
d #define 或宏
如果搜索匹配耗时较长,可以调用|complete_add()|向总列表中增加每个匹配。不要在返
回的列表里包含这些匹配!搜索匹配的同时,时不时地调用 |complete_check()| 来使得
用户仍然可以按键。如果该函数返回非零,搜索停止。
该函数可以移动光标,结束后光标会恢复。为了安全原因,不能在 |modeline| 或
|sandbox| 中设置此选项。
补全月份名的示例: >
fun! CompleteMonths(findstart, base)
if a:findstart
" 定位单词的开始处
let line = getline('.')
let start = col('.') - 1
while start > 0 && line[start - 1] =~ '\a'
let start -= 1
endwhile
return start
else
" 寻找匹配 "a:base" 的月份
let res = []
for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
if m =~ '^' . a:base
call add(res, m)
endif
endfor
return res
endif
endfun
set completefunc=CompleteMonths
<
功能同上,但是现在假设搜索比较慢: >
fun! CompleteMonths(findstart, base)
if a:findstart
" 定位单词的开始处
let line = getline('.')
let start = col('.') - 1
while start > 0 && line[start - 1] =~ '\a'
let start -= 1
endwhile
return start
else
" 寻找匹配 "a:base" 的月份
for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
if m =~ '^' . a:base
call complete_add(m)
endif
sleep 300m " simulate searching for next match
if complete_check()
break
endif
endfor
return []
endif
endfun
set completefunc=CompleteMonths
<
插 入 补 全 弹 出 菜 单 *ins-completion-menu*
*popupmenu-completion*
Vim 可以用更简单的弹出菜单来显示匹配。
当下面条件符合时使用弹出菜单:
- 'completeopt' 选项包含 "menu" 或 "menuone"。
- 显示终端至少支持 8 色。
- 至少有两条匹配项。如果使用 "menuone",一条匹配也可以。
选项 'pumheight' 用于设置最大高度。默认值是使用全部有效空间。
有三个状态:
1. 插入了完整的匹配,例如在 CTRL-N 或 CTRL-P 之后。
2. 用光标键选择其它匹配项。此时不插入该匹配项,只在弹出菜单中高亮选中的条目。
3. 只插入了部分匹配文本,并且已经输入字符或者使用了退格键,这时匹配项列表根据
光标前的内容进行调整。
开始时你通常处于状态一并插入第一个匹配。如果 'completeopt' 包含了 "longest" 而
且有多个匹配项,那么开始于状态三。
如果选择其它匹配项,例如键入 CTRL-N 或 CTRL-P,就进入了状态一。这不会改变匹配
项列表。
如果退回到原文,就会处于状态三。要立即进入该状态,可以使用快捷键映射方法,该映
射在补全开始后立即使用 CTRL-P: >
:imap <F7> <C-N><C-P>
<
*popupmenu-keys*
状态一下,这些键有特别的含义:
<BS> 和 CTRL-H 删除一个字符,查找光标前单词的匹配项。这会减少列表中匹配项的
数目,常常到只有一个项目,然后切换到状态二。
其它非特殊字符:
停止补全,不改变匹配,然后插入输入的字符。
状态二和状态三下,这些键有特别的含义:
<BS> 和 CTRL-H 删除一个字符,并查找光标前变短的单词的匹配项。这可能会发现更
多的匹配项。
CTRL-L 从当前匹配项中增加一个字符,可能会减少匹配项的数量。
任何可显示的非空白字符:
加入该字符,减少匹配项的数量。
全部三个状态中,可以使用这些键:
CTRL-Y 是 (Yes): 接受当前选择的匹配项并停止补全。
CTRL-E 结束 (End) 补全,回退到选择匹配前原有的内容 (原先输入的或者
最长的公共字符串)。
<PageUp> 反向若干项选择一个匹配项,但不插入。
<PageDown> 正向若干项选择一个匹配项,但不插入。
<Up> 选择前一个匹配,同 CTRL-P,但不插入。
<Down> 选择下一个匹配,同 CTRL-N,但不插入。
<Space> 或 <Tab> 停止补全,不改变匹配,插入键入的该字符
<Enter> 键的行为取决于你现在所处的状态:
状态一: 使用现有的文本,然后插入换行符。
状态二: 插入当前选择项。
状态三: 使用现有的文本,然后插入换行符。
换句话说: 如果你只使用光标键在匹配项列表中选择其它条目,按 <Enter> 键将插入该
匹配。如果键入其它字符,按 <Enter> 键将插入换行符。
下面的高亮组能够改变菜单颜色:
Pmenu 普通项 |hl-Pmenu|
PmenuSel 选中项 |hl-PmenuSel|
PmenuSbar 滚动条 |hl-PmenuSbar|
PmenuThumb 滚动条拇指 (thumb) |hl-PmenuThumb|
显示弹出窗口时,没有专门的映射。但你可以使用插入模式映射并检查 |pumvisible()|
函数的返回值以进行不同的处理。例如: >
:inoremap <Down> <C-R>=pumvisible() ? "\<lt>C-N>" : "\<lt>Down>"<CR>
映射中用 <expr> 可以在键入某字符或者满足某些条件时弹出菜单。例如,键入 '.': >
inoremap <expr> . MayComplete()
func MayComplete()
if (can complete)
return ".\<C-X>\<C-O>"
endif
return '.'
endfunc
详见 |:map-<expr>|。
特 定 文 件 类 型 全 能 补 全 的 补 充 说 明 *compl-omni-filetypes*
文件类型 {filetype} 使用的是 'runtimepath' 的 autoload/{filetype}complete.vim