[r209]: trunk / doc / change.txt Maximize Restore History

Download this file

change.txt    1439 lines (1138 with data), 67.4 kB

   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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
*change.txt* For Vim version 7.4. 最近更新: 2013年8月
VIM 参考手册 by Bram Moolenaar
译者: Willis
http://vimcdoc.sf.net
本文档描述删除和修改文本的命令。在本文中,修改文本意味着用单个命令删除部分文本
并将其替换成其他文本。所有本文描述的命令都可以被撤销。其中非命令行 (Ex) 的命令
可以用 "." 命令重复。
1. 删除文本 |deleting|
2. 删除并插入 |delete-insert|
3. 简单修改 |simple-change| *changing*
4. 复杂修改 |complex-change|
4.1 过滤命令 |filter|
4.2 替代 |:substitute|
4.3 搜索与替代 |search-replace|
4.4 调整制表 |change-tabs|
5. 复制并移动文本 |copy-move|
6. 文本排版 |formatting|
7. 文本排序 |sorting|
关于插入文本部分,参阅 |insert.txt|。
==============================================================================
1. 删除文本 *deleting* *E470*
["x]<Del> 或 *<Del>* *x* *dl*
["x]x 删除 [count] 个光标之下和之后的字符 [到寄存器 x 里]
(非 |linewise| 行动作)。和 "dl" 相同。
<Del> 键不使用 [count] 计数。相反,如果有计数,它删
除该计数的最后一位。
如果 <Del> 键的操作与你预期的不符,参见 |:fixdel|。关
于如何删除换行符 (连接行),参见 |'whichwrap'|。
{Vi 不支持 <Del>}
*X* *dh*
["x]X 删除 [count] 个光标之前的字符 [到寄存器 x 里] (非
|linewise| 行动作)。和 "dh" 相同。另见 |'whichwrap'|。
*d*
["x]d{motion} 删除 {motion} 动作跨越的文本 [到寄存器 x 里]。例外见
下。
*dd*
["x]dd 删除 [count] 行 [到寄存器 x 里],|linewise| 行动作。
*D*
["x]D 删除光标所在的字符到行尾及其后的 [count]-1 行 [到寄
存器 x 里] (非 |linewise| 行动作)。和 "d$" 同义。
如果 'cpoptions' 里有 '#' 标志位,忽略计数。
{Visual}["x]x 或 *v_x* *v_d* *v_<Del>*
{Visual}["x]d 或
{Visual}["x]<Del> 删除高亮文本 [到寄存器 x 里] (关于 {Visual} 见
|Visual-mode|)。{Vi 无此功能}
{Visual}["x]CTRL-H 或 *v_CTRL-H* *v_<BS>*
{Visual}["x]<BS> 在选择模式时,删除高亮文本 [到寄存器 x 里]。
{Visual}["x]X 或 *v_X* *v_D* *v_b_D*
{Visual}["x]D 删除高亮行 [到寄存器 x 里] (关于 {Visual} 见
|Visual-mode|)。在可视列块模式里,"D" 删除高亮的文本直
到行尾。{Vi 无此功能}
*:d* *:de* *:del* *:delete* *:dl* *:dp*
:[range]d[elete] [x] 删除 [range] 范围的行 (缺省: 当前行) [到寄存器 x 里]。
注意 这些奇异的缩写:
:dl 删除并列出 (list)
:dell 同上
:delel 同上
:deletl 同上
:deletel 同上
:dp 删除并显示 (print)
:dep 同上
:delp 同上
:delep 同上
:deletp 同上
:deletep 同上
:[range]d[elete] [x] {count}
从 [range] 指定的范围开始,删除 {count} 行 (缺省: 当前
行 |cmdline-ranges|) [到寄存器 x 里]。
这些命令删除文本。你可以用 `.` 命令重复它们 (除了 `:d`),也可以撤销它们。用可
视模式可以删除文本列块。关于寄存器的解释,参见 |registers|。
d{motion} 命令的一个特例: 如果动作不面向行,动作的开始和结束处不在同一行,并且
开始位置之前和结束位置之后只有空白的话,该删除会转为行动作。这意味着删除命令可
能删除你还想保留的空白行。|o_v| 操作符强制该动作面向字符。
如果 'cpoptions' 包括 'E' 标志位,删除文本里的空区域 (例如,在首列上 "d0") 会
报错。
*J*
J 连接 [count] 行,但至少包含两行。删除缩进,插入不多于
两个的空格 (见下)。
*v_J*
{Visual}J 连接高亮行,但至少包含两行。删除缩进,插入不多于两个的
空格 (见下)。{Vi 无此功能}。
*gJ*
gJ 连接 [count] 行,但至少包含两行。不插入或删除任何空
格。{Vi 无此功能}。
*v_gJ*
{Visual}gJ 连接高亮行,但至少包含两行。不插入或删除任何空格。
{Vi 无此功能}。
*:j* *:join*
[range]j[oin][!] [flags]
连接 [range] 范围的行。和 "J" 相同,但如有 [!] 时,连
接不插入或删除任何空格。如果 [range] 包括相同的开始和
结束行,该命令不做任何事。缺省行为是连接当前行与下一
行。{Vi: 没有 !}
[flags] 部分可参见 |ex-flags|。
:[range]j[oin][!] {count} [flags]
连接 [range] 开始的 {count} 行 (缺省: 当前行
|cmdline-ranges|)。和 "J" 相同,但如有 [!] 时,连接不
插入或删除任何空格。{Vi: 没有 !}
[flags] 部分可参见 |ex-flags|。
这些命令删除行间的 <EOL>,即换行符,从而实际上使多行连接成一行。除了 `:j` 之
外,你可以重复这些命令或者撤销之。
这些命令,除了 "gJ" 以外,插入一个空格以代替 <EOL>,除非当前行的结尾已经有空白
或者下一行以 ')' 开始。这些命令,除了 "gJ" 之外,也删除下一行所有开头的空白。
如果 'joinspaces' 选项打开,这些命令在 '.'、'!' 或者 '?' 之后插入两个空格 (但
如果 'cpoptions' 包括 'j' 标志位,只有在 '.' 之后插入两个空格)。
'formatoptions' 里的 'B' 和 'M' 标志位改变在多字节字符之前或者之后插入空格的行
为 |fo-table|。
==============================================================================
2. 删除并插入 *delete-insert* *replacing*
*R*
R 进入替换模式: 每个输入的字符替代一个现有的字符,从光标
所在的位置开始。重复输入的文本 [count] - 1 次。参见
|Replace-mode| 以了解相关详情。
*gR*
gR 进入虚拟替换模式: 每个输入的字符替代屏幕位置一个现有的
字符。因而,一个 <Tab> 可以一次替换若干个字符。重复输
入的文本 [count]-1 次。参见 |Virtual-Replace-mode| 以
了解相关详情。{仅当编译时加入 |+vreplace| 特性有效}
*c*
["x]c{motion} 将 {motion} 跨过的文本删除 [到寄存器 x 里] 并开始插
入。如果 'cpoptions' 包括 'E' 标志位并且没有任何文本实
际需要删除时 (例如,"cTx" 而光标刚在 'x' 之后的时候),
报错并拒绝开始插入模式 (这与 Vi 兼容)。如果
'cpoptions' 没有 'E',"c" 命令总是启动插入模式,即使没
有文本要删除也是如此。
*cc*
["x]cc 删除 [count] 行 [到寄存器 x 里] 并开始插入。
|linewise| 行动作。如果置位 'autoindent',保留首行的缩
进。
*C*
["x]C 从当前光标位置删除到行尾,再删除 [count]-1 行 [到寄存
器 x 里],并开始插入。和 c$ 等价 (非 |linewise| 行动
作)。
*s*
["x]s 删除 [count] 个字符 [到寄存器 x 里],并开始插入。(s 代
表替代 (Substitute))。和 "cl" 等价 (非 |linewise| 行动
作)。
*S*
["x]S 删除 [count] 行 [到寄存器 x 里] 并开始插入。和 "cc" 等
价 |linewise| 行动作。
{Visual}["x]c or *v_c* *v_s*
{Visual}["x]s 删除高亮文本 [到寄存器 x 里],并开始插入 (关于
{Visual} 参见 |Visual-mode|)。{Vi 无此功能}。
*v_r*
{Visual}["x]r{char} 把所有高亮的字符替换成 {char}。
*v_C*
{Visual}["x]C 删除高亮行 [到寄存器 x 里] 并开始插入。在可视列块模式
下有所不同 |v_b_C|。{Vi 无此功能}。
*v_S*
{Visual}["x]S 删除高亮行 [到寄存器 x 里] 并开始插入 (关于 {Visual}
参见 |Visual-mode|)。{Vi 无此功能}。
*v_R*
{Visual}["x]R 现在和 {Visual}["x]S 相同。以后的版本可能会有所改变
{Vi 无此功能}。
注意:
- 你可以用 <Esc> 退出插入和替换模式。
- 参见 "插入和替换模式" 一节 |mode-ins-repl| 以了解其他这些模式下的特殊字符。
- [count] 的效果只有在 Vim 退出插入或替换模式时才会体现。
- 当 'cpoptions' 选项包含 '$' 并且所做的修改在一行之内,Vim 继续显示被删除的文
本,并在最后一个被删除的字符之后加上一个 '$'。
关于寄存器的解释,参见 |registers|。
替换模式和插入模式类似,除了每输入一个字符同时删除一个字符以外。如果到达行尾,
Vim 把其后的字符插入在行尾 (和插入模式相同)。在替换模式下,退格键恢复原来的文
本 (如果有的话)。(参见 "插入和替换模式" 一节 |mode-ins-repl|)。
*cw* *cW*
特殊情况: 如果光标在单词内部,"cw" 和 "cW" 不包含单词后的空白而只修改到词尾。
这是因为 Vim 把 "cw" 解释为 修改-单词,而单词并不包括其后的空白。{Vi: 在其后还
有空白的空白字符上 "cw" 只修改第一个空白;这也许是一个漏洞,因为 "dw" 删除所有
空白;用 'cpoptions' 里的 'w' 标志位来设置类似于 Vi 的工作方式}
如果你希望 "cw" 包括单词之后的空格,使用如下的映射: >
:map cw dwi
或者,用 "caw" (见 |aw|)。
*:c* *:ch* *:change*
:{range}c[hange][!] 用另外的文本替换若干文本行。输入只包含 "." 的行结束替
换。如果没有 {range},该命令只置换当前行。
加上 [!] 后,在本命令的执行期间切换 'autoindent'。
==============================================================================
3. 简单修改 *simple-change*
*r*
r{char} 把光标下的字符换成 {char}。如果 {char} 是 <CR> 或者
<NL>,则把该字符变成换行符。要换成一个真正的 <CR>,使
用 CTRL-V <CR>。CTRL-V <NL> 则换成 <Nul>。
{Vi: CTRL-V <CR> 还是换成换行符。没有办法换成 <CR>}。
若 {char} 为 CTRL-E 或 CTRL-Y,使用下一行或上一行的
字符来代替,就象 |i_CTRL-E| 和 |i_CTRL-Y| 一样。这里
计数也适用,所以 `10r<C-E>` 从下一行复制 10 个字符。
如果你给出 [count],Vim 替换 [count] 个字符为 [count]
个 {char}。不过如果 {char} 为 <CR> 或者 <NL>,Vim 只插
入一个换行符: "5r<CR>" 替换五个字符为一个换行符。
当 {char} 为 <CR> 或者 <NL>,Vim 会自动缩进。这和先执
行删除要替换的字符在执行 "i<CR><Esc>" 类似。
{char} 可以输入二合字母 |digraph-arg|。
|:lmap| 映射会应用在 {char} 上。插入模式下的 CTRL-^ 命
令可以切换这一功能 |i_CTRL-^|。
参见 |utf-8-char-arg| 以了解在 'encoding' 为 Unicode
编码时如果使用合成用字符。
*gr*
gr{char} 替换光标下的虚拟字符。替换发生在屏幕位置而不是文件位置
上。参见 |gR| 和 |Virtual-Replace-mode| 以了解相关详
情。和 |r| 一样,可以使用计数。{char} 输入的方式也相同
{仅当编译时加入 |+vreplace| 特性有效}。
*digraph-arg*
普通模式下的命令,像 |r| 和 |t|,需要一个单字符的参数。如果 'cpo' 不包含 'D'
标志位,该字符可以用 |digraphs| 那样的方式输入: 先键入 CTRL-K 然后输入二合字母
的两个字符 {仅当编译时加入 |+digraphs| 特性有效}。
*case*
下面的命令根据当前的 |locale| 改变字母的大小写。参见 |:language|。这里会用到
LC_CTYPE 的值。
*~*
~ 'notildeop' 选项: 切换光标下字符的大小写,并把光标向右
移。如果给出 [count],应用在那么多数目的字符上。
{Vi: 没有 count}
~{motion} 'tildeop' 选项: 切换 {motion} 跨越的文本的大小写。{Vi:
~ 不能用作操作符}
*g~*
g~{motion} 切换 {motion} 跨越的文本的大小写。{Vi 无此功能}
g~g~ *g~g~* *g~~*
g~~ 切换当前行的大小写。{Vi 无此功能}
*v_~*
{Visual}~ 切换高亮文本的大小写 (关于 {Visual} 见
|Visual-mode|)。{Vi 无此功能}
*v_U*
{Visual}U 使高亮文本成为大写 (关于 {Visual} 见 |Visual-mode|)。
{Vi 无此功能}
*gU* *uppercase*
gU{motion} 使 {motion} 跨越的文本成为大写。{Vi 无此功能}
例如: >
:map! <C-F> <Esc>gUiw`]a
< 可以用在插入模式下: 按 CTRL-F 使光标之前的单词成为大
写。这使得输入大写单词很方便,只要输入小写单词再一次转
换就行了。
gUgU *gUgU* *gUU*
gUU 使得当前行成为大写。{Vi 无此功能}
*v_u*
{Visual}u 使高亮文本成为小写 (关于 {Visual} 见 |Visual-mode|)。
{Vi 无此功能}
*gu* *lowercase*
gu{motion} 使 {motion} 跨越的文本成为小写。{Vi 无此功能}
gugu *gugu* *guu*
guu 使得当前行成为小写。{Vi 无此功能}
*g?* *rot13*
g?{motion} 用 Rot13 对 {motion} 跨越的文本进行编码。{Vi 无此功能}
*v_g?*
{Visual}g? 用 Rot13 对高亮文本进行编码 (关于 {Visual} 见
|Visual-mode|)。{Vi 无此功能}
g?g? *g?g?* *g??*
g?? 用 Rot13 对当前行进行编码。{Vi 无此功能}
要以标题大写 (title cap) 方式改写一行,亦即使每个单词的首字母大写: >
:s/\v<(.)(\w*)/\u\1\L\2/g
递 增 与 递 减 ~
*CTRL-A*
CTRL-A 把当前光标之上或之后的数值或者字母加上 [count]。
{Vi 无此功能}
*CTRL-X*
CTRL-X 把当前光标之上或之后的数值或者字母减去 [count]。
{Vi 无此功能}
CTRL-A 和 CTRL-X 命令可用于 (带符号) 十进制数,无符号八进制和十六进制数以及字
母。这取决于 'nrformats' 选项。
- 当 'nrformats' 包括 "octal" 时,Vim 假设 '0' 开始的数值为八进制,除非该数值
里包含 '8' 或 '9'。其他的数值为十进制,并可以在开始带一个可选的负号。
如果光标已经在数值上,命令应用于该数值;否则,应用于光标右侧的数值。
- 当 'nrformats' 包括 "alpha" 时,Vim 会改变光标之上或之后的字母。这可用于构造
字母编号的列表。
- 当 'nrformats' 包括 "hex" 时,Vim 假设 '0x' 或者 '0X' 开始的数值为十六进制。
这个数值最右端的字母决定所产生十六进制数值的大小写。如果当前数值没有字母,
Vim 使用上一次检测到的大小写。
对零开头的数值 (包括八进制和十六进制的),Vim 尽可能保留相同数量的字符。CTRL-A
在 "0077" 上产生 "0100",CTRL-X 在 "0x100" 上产生 "0x0ff"。
有一个例外: 在发现某数值以零开始但不是八进制 (包含 '8' 或 '9'),而 'noformats'
却包含 "octal" 的时候,引导的零会被删除,以免结果被误认为八进制。
注意 如果 'nrformats' 包括 "octal",开头有零的十进制数会产生错误,因为会和八进
制数产生混淆。
CTRL-A 命令在宏命令里很有用。例如: 使用以下的步骤构造一个数字编号的列表。
1. 建立第一个列表项。确保它以数字开始。
2. qa - 用寄存器 'a' 开始记录
3. Y - 抽出这个列表项
4. p - 把该项的一个副本放置在下一行上
5. CTRL-A - 增加计数
6. q - 停止记录
7. <count>@a - 重复抽出、放置和增加计数操作 <count> 次
将 文 本 左 移 或 右 移 *shift-left-right*
*<*
<{motion} 将 {motion} 跨越的行左移 'shiftwidth' 列。
*<<*
<< 将 [count] 行左移 'shiftwidth' 列。
*v_<*
{Visual}[count]< 将高亮行左移 [count] 个 'shiftwidth' 列 (关于 {Visual}
见 |Visual-mode|)。{Vi 无此功能}
*>*
>{motion} 将 {motion} 跨越的行右移 'shiftwidth' 列。
*>>*
>> 将 [count] 行右移 'shiftwidth' 列。
*v_>*
{Visual}[count]> 将高亮行右移 [count] 个 'shiftwidth' 列 (关于 {Visual}
见 |Visual-mode|)。{Vi 无此功能}
*:<*
:[range]< 将 [range] 指定的行左移 'shiftwidth' 列。多个 '<' 左移
多个 'shiftwidth' 列。
:[range]< {count} 左移 [range] 开始的 {count} 行 'shiftwidth' 列 (缺省从
当前行 |cmdline-ranges|)。多个 '<' 左移多个
'shiftwidth' 列。
:[range]le[ft] [indent] 左对齐 [range] 指定的行。设置缩进距离为 [indent] (缺省
为 0)。{Vi 无此功能}
*:>*
:[range]> [flags] 将 [range] 指定的行右移 'shiftwidth' 列。多个 '>' 右移
多个 'shiftwidth' 列。
[flags] 部分可参见 |ex-flags|。
:[range]> {count} [flags]
右移 [range] 开始的 {count} 行 'shiftwidth' 列 (缺省从
当前行 |cmdline-ranges| 开始)。多个 '>' 右移多个
'shiftwidth' 列。
[flags] 部分可参见 |ex-flags|。
">" 和 "<" 命令可以用来方便地调整程序的缩进。使用 'shiftwidth' 选项设置这些命
令增加或者减少的空白的数量。通常,'shiftwidth' 选项是 8,但你也可以设置为,比
如说,3,使得缩进更小些。如果已经没有缩进,左移命令会停止。另一方面,右移命令
则不会影响空白行。
如果 'shiftround' 选项打开,缩进距离被取整到 'shiftwidth' 的倍数。
如果 'smartindent' 选项打开,或者 'cindent' 打开并且 'cinkeys' 包含 '#',右移
不影响 '#' 开始的行 (这些应该是 C 预处理行,它们应该保持在第一列)。
如果 'expandtab' 选项关闭 (这是缺省值), Vim 尽可能使用 <Tab> 来构成缩进。你可
以用 ">><<" 来把缩进尽可能从空格替换成同样缩进距离的 <Tab> (如有需要,还有少量
的空格)。如果 'expandtab' 选项打开,Vim 只使用空格。这样你可以使用 ">><<" 把
<Tab> 替换成空格 (或者可以用 `:retab!`)。
要移动一行多个 'shiftwidth' 列,使用可视模式或者 `:` 命令。例如: >
Vjj4> 右移三行四个缩进位
:<<< 左移当前行三个缩进位
:>> 5 右移五行两个缩进位
:5>> 右移第五行两个缩进位
==============================================================================
4. 复杂修改 *complex-change*
4.1 过滤命令 *filter*
过滤程序是一个接受文本作为标准输入,作某些修改,并把结果放到标准输出的程序。你
可以用下面的命令把若干文本发送给过滤程序,然后用过滤的输出结果替换。一个过滤程
序的例子是 "sort",按字母顺序给行排序;还有 "indent",排版 C 程序文件 (你需要
一个能以过滤程序方式工作的版本,并非所有的版本都可以)。'shell' 选项指定 Vim 使
用的外壳程序,用以执行过滤程序 (另见 'shelltype' 选项)。你可以用 "." 重复过滤
命令。Vim 不会识别 `:!` 命令之后的注释 (用 '"' 开始)。
*!*
!{motion}{filter} 将 {motion} 跨越的行用外部程序 {filter} 过滤。
*!!*
!!{filter} 将 [count] 行用外部程序 {filter} 过滤。
*v_!*
{Visual}!{filter} 将高亮行用外部程序 {filter} 过滤。(关于 {Visual}
见 |Visual-mode|)。{Vi 无此功能}
:{range}![!]{filter} [!][arg] *:range!*
将 {range} 指定的行用外部程序 {filter} 过滤。Vim 把可
选的感叹号替换成最后一次使用的命令,并附加上可选的参数
[arg]。Vim 把过滤命令的输出保存到临时文件,并把文
件内容读到一个缓冲区里 |tempfile|。Vim 使用
'shellredir' 选项把过滤程序的结果重定向到临时文件。
不过,如果关闭了 'shelltemp' 选项且可以的话,使用管道
机制 (Unix 上)。
如果 'cpoptions' 包含 'R' 标志位,过滤行里的位置标记被
删除,除非使用了 |:keepmarks| 命令。例如: >
:keepmarks '<,'>!sort
< 如果过滤后的行数变少,删去的行里的位置标记无论如何不会
保存。
*=*
={motion} 把 {motion} 跨越的行用 'equalprg' 选项指定的外部程序过
滤。如果 'equalprg' 选项为空 (缺省),使用内部的排版机
制 |C-indenting| 和 |'lisp'|,除非 'indentexpr' 非空,
此时使用 |indent-expression| 机制来代替。反之,如果
Vim 编译时没有包含内部排版机制,最后手段是使用外部的
"indent" 程序。
*==*
== 和 ={motion} 类似,过滤 [count] 行。
*v_=*
{Visual}= 和 ={motion} 类似,过滤高亮行。{Vi 无此功能}
*tempfile* *setuid*
Vim 使用临时文件来处理过滤、执行比较和用于 tempname()。Unix 上,该文件会放在一
个私人的目录里 (只能被当前用户访问),以防堵安全上的漏洞 (例如,符号链接攻击或
文件被其他用户读取等)。Vim 退出时,自动删除该目录及之下的所有文件。如果 Vim 本
身设置了 setuid 位,这样或许会有问题。临时文件由 setuid 用户拥有,但过滤程序以
原来用户的权限执行。
MS-DOS 和 OS/2 上,使用以下目录中首个可用者: $TMP、$TEMP、c:\TMP、c:\TEMP。
Unix 上,使用的目录依次为: $TMPDIR、/tmp、当前目录、$HOME。
MS-Windows 上,使用 GetTempFileName() 系统函数。
其它系统上使用 tmpnam() 库函数。
4.2 替代 *:substitute*
*:s* *:su*
:[range]s[ubstitute]/{pattern}/{string}/[flags] [count]
对 [range] 指定的行把 {pattern} 的匹配替代成
{string}。
关于 {pattern},参见 |pattern|。
{string} 可以是按字面意义的,也可以包含特殊字符。
参见 |sub-replace-special|。
如果不指定 [range] 和 [count],仅在当前行进行替代。
如果指定 [count],在 [range] 最后一行开始的 [count]
行进行替代。如果不指定 [range] ,则从当前行开始。
另见 |cmdline-ranges|。
关于 [flags],参见 |:s_flags|。
:[range]s[ubstitute] [flags] [count]
:[range]&[&][flags] [count] *:&*
使用最后一次 :substitute 相同的模式和替代字符串,但不
包括相同的标志位。你可以另加 [flags] (见 |:s_flags|)。
注意 在 `:substitute` 之后,不能使用 '&' 标志位。它被
认为是一个模式分隔符。
`:substitute` 和 'c'、'g' 和 'r' 标志位之间的空格不是
必需的,但在脚本里为了避免混淆起见,最好保留它。
:[range]~[&][flags] [count] *:~*
使用最后一次 :substitute 相同的替代字符串,但使用最近
使用的搜索模式作为匹配模式。这类似于 `:&r`。
关于 [flags],参见 |:s_flags|。
*&*
& 等价于 `:s` (重复上次的 substitute)。注意 这里不记住标
志位,所以实际工作方式可能不尽相同。你可以用 `:&&` 来
保持相同的标志位。
*g&*
g& 等价于 `:%s//~/&` (在所有行上使用上次的匹配模式,重复
上次的 substitute,并使用相同的标志位)。
例如,如果先用了替代 `:s/pattern/repl/flags` 然后
`/search` 搜索了其他模式,`g&` 会执行
`:%s/search/repl/flags`。
助记: 全局 (global) 替代 (substitute)。{Vi 无此功能}
*:snomagic* *:sno*
:[range]sno[magic] ... 和 `:substitute` 相同,但总使用 'nomagic'。
{Vi 无此功能}
*:smagic* *:sm*
:[range]sm[agic] ... 和 `:substitute` 相同,但总使用 'magic'。
{Vi 无此功能}
*:s_flags*
你可以在 substitute 命令里使用以下标志位:
[&] 必须是首个使用的标志位: 保留和上次 substitute 相同的标志位。例如: >
:&&
:s/this/that/&
< 注意 `:s` 和 `:&` 不保留标志位。
{Vi 无此功能}
[c] 确认每个替代。Vim 高亮匹配的字符串 (如果使用了 |hl-IncSearch|)。你可以
输入: *:s_c*
'y' 来替代这次匹配
'l' 来替代这次匹配并退出 (助记: "last",最后)
'n' 来跳过这次匹配
<Esc> 来退出替代过程
'a' 来替代这次和以后所有的匹配
'q' 来退出替代过程 {Vi 无此功能}
CTRL-E 来上卷屏幕 {Vi 无此功能,仅当编译时加入 |+insert_expand| 特
性才有此功能}
CTRL-Y 来下卷屏幕 {Vi 无此功能,仅当编译时加入 |+insert_expand| 特
性才有此功能}
如果 'edcompatible' 选项打开,Vim 记住 [c] 标志位并在每次使用它时切换
是否确认,但在给出一个新的匹配模式时复位。
{Vi 没有高亮匹配部分和除了 'y' 和 'n' 之外的选择}
[e] 如果模式搜索不成功,不给出错误信息。因为没产生错误,映射的过程得以继
续。这主要用来防止在映射执行过程的无匹配 ("No match") 错误中断映射。
不过,Vim 不会抑制以下的错误信息:
Regular expressions can't be delimited by letters (正规表达式
不能以字母分隔)
\ should be followed by /, ? or & (\ 必须后面跟 /、? 或者 &)
No previous substitute regular expression (没有上次的替代正规
表达式)
Trailing characters (结尾有多余的字符)
Interrupted (中断)
{Vi 无此功能}
[g] 对行内所有的匹配进行替代。如果没有这个参数,替代只对每行的第一个匹配进
行。如果 'edcompatible' 选项打开,Vim 记住这个标志并在你每次使用该标志
时切换,但在给出一个新的匹配模式时复位。如果 'gdefault' 选项打开,这个
标志缺省打开,而 [g] 参数关闭之。
[i] 忽略模式的大小写。不使用 'ignorecase' 和 'smartcase' 选项。
{Vi 无此功能}
[I] 不忽略模式的大小写。不使用 'ignorecase' 和 'smartcase' 选项。
{Vi 无此功能}
[n] 报告匹配的次数,并不实际进行替代。忽略 [c] 标志位。匹配报告的发生就像
'report' 总是为零那样。可用于 |count-items|。
如果使用 \= |sub-replace-expression|,在 |sandbox| 里对每一个匹配执行
该表达式。
[p] 显示包含最后一次替代的行。
[#] 类似 [p],且在前面加上行号。
[l] 类似 [p],但显示的方式类似于 |:list|。
[r] 仅对于不带参数的 `:&` 和 `:s` 有用。`:&r` 和 `:~` 工作的方式相同: 如果
匹配模式为空,使用上一次使用的搜索模式,而不是上一次的 substitute 或者
`:global` 所使用的模式。如果最近一次使用搜索的命令就是 substitute 或者
`:global`,那就没有区别了。如果最近的命令的是 "/" 那样的搜索命令,使用
那个命令的搜索模式。
带参数的 `:s`,则不论如何,总是如此: >
:s/blue/red/
/green
:s//red/ 或 :~ 或 :&r
< 最后的命令把 "green" 替代成 "red"。 >
:s/blue/red/
/green
:&
< 最后的命令把 "blue" 替代成 "red"。
{Vi 无此功能}
注意这里没有标志位可以改变模式的 "魔术性" (magicness)。你可以用别的命令或 |/\v|
之类。原因是标志位只能在跳过模式之后才能找到,而要跳过模式,必须先知道模式的
"魔术性"。第二十二条军规!
如果 substitute 命令所用的 {pattern} 为空,该命令使用上次的 substitute 或者
`:global` 命令用过的模式。如果不存在,但有上次搜索模式,使用之。如果有 [r] 标
志位,该命令使用上次 substitute、 `:global` 或者搜索命令使用的模式。
如果 {string} 省略,替代命令假定它为空。这样就把匹配文本删除了。这时,
{pattern} 之后的分隔符也可省略。例如: >
:%s/TESTING
删除所有行上的 "TESTING",但每行只删一个。
为了和 Vi 的兼容性,有两个例外:
"\/{string}/" 和 "\?{string}?" 等同于 "//{string}/r"。
"\&{string}&" 等同于 "//{string}/"。
*E146*
除了用 '/' 来包围模式和替代字符串之外,你可以使用任何其他的单字节字符,除了
字母、数字、'\'、'"' 或 '|' 之外。这可以用于 '/' 是搜索模式或替代字符串一部
分的场合。例如: >
:s+/+//+
关于模式的定义,参见 |pattern|。在可视列块模式下,如果模式中使用了 |/\%V|,那
么替代只在列块内进行,否则它作用于整行。
*sub-replace-special* *:s\=*
{string} 以 "\=" 开始时,它被作为表达式来执行,参见 |sub-replace-expression|。
你可以用此功能实现复杂替换,也可用来使用特殊字符。
否则,{string} 字符串里的字符有如下的特殊含义:
*:s%*
如果 {string} 等于 "%",且 'cpoptions' 选项包含 '/',重复使用上次替代命令的
{string},见 |cpo-/|
magic nomagic 动作 ~
& \& 替代为完整的匹配 *s/\&*
\& & 替代为 &
\0 替代为完整的匹配 *\0* *s/\0*
\1 替代为匹配的第一个 () 里面的内容 *s/\1*
\2 替代为匹配的第二个 () 里面的内容 *s/\2*
.. .. *s/\3*
\9 替代为匹配的第九个 () 里面的内容 *s/\9*
~ \~ 替代为前一个 substitute 的替代字符串 *s~*
\~ ~ 替代为 ~ *s/\~*
\u 下一个字符成为大写 *s/\u*
\U 其后字符成为大写,直到 \E 出现 *s/\U*
\l 下一个字符成为小写 *s/\l*
\L 其后字符成为小写,直到 \E 出现 *s/\L*
\e 结束 \u、\U、\l 和 \L (注意: 不是 <Esc>!) *s/\e*
\E 结束 \u、\U、\l 和 \L *s/\E*
<CR> 把该行在此位置一分为二
(<CR> 以 CTRL-V <Enter> 方式输入) *s<CR>*
\r 同上 *s/\r*
\<CR> 插入一个回车 (CTRL-M)
(<CR> 以 CTRL-V <Enter> 方式输入) *s/\<CR>*
\n 插入一个 <NL> (文件里的 <NUL>)
(此处并不是换行) *s/\n*
\b 插入一个 <BS> *s/\b*
\t 插入一个 <Tab> *s/\t*
\\ 插入单个反斜杠 *s/\\*
\x 其中 x 是上面没提到的任何一个字符:
保留作将来的扩展
这里的特殊含义也用于 |substitute()| 函数的第三个参数 {sub},除了若干例外:
- % 总是插入百分号,与 'cpoptions' 无关。
- 总是假定有魔术性,与 'magic' 无关。
- ~ 总是插入波浪符。
- <CR> 和 \r 插入回车 (CTRL-M)。
- \<CR> 没有特殊意义,只是 \x 之一。
示例: >
:s/a\|b/xxx\0xxx/g 修改 "a b" 为 "xxxaxxx xxxbxxx"
:s/\([abc]\)\([efg]\)/\2\1/g 修改 "af fa bg" 为 "fa fa gb"
:s/abcde/abc^Mde/ 修改 "abcde" 为 "abc"、"de" (两行)
:s/$/\^M/ 修改 "abcde" 为 "abcde^M"
:s/\w\+/\u\0/g 修改 "bla bla" 为 "Bla Bla"
:s/\w\+/\L\u/g 修改 "BLA bla" 为 "Bla Bla"
注意: "\L\u" 可用于使单词的首个字母变大写。此行为和 Vi 以及旧版 Vim 不兼容,那
里 "\u" 会抵消 ”\L"。"\U\l" 亦然。
注意: 在以前的版本里,CTRL-V 以特殊的方式处理。因为和 Vi 不兼容,该功能已经被
去掉了,现在用反斜杠来替代。
命令 文本 结果 ~
:s/aa/a^Ma/ aa a<line-break>a
:s/aa/a\^Ma/ aa a^Ma
:s/aa/a\\^Ma/ aa a\<line-break>a
(你需要输入 CTRL-V <CR> 来得到这里的 ^M)
"\1","\2" 等里的数字是基于模式里 "\(" 出现的顺序 (从左到右)。如果一个括号组匹
配多次,最后一次的匹配被使用在 "\1","2" 等里。例如: >
:s/\(\(a[a-d] \)*\)/\2/ 修改 "aa ab x" 为 "ab x"
如果括号和 '|' 组合使用,如 \([ab]\)\|\([cd]\),两者有一个会不匹配,所以 \1 或
者 \2 会为空。例如: >
:s/\([ab]\)\|\([cd]\)/\1x/g 修改 "a b c d" 为 "ax bx x x"
<
以表达式方式替代 *sub-replace-expression*
*sub-replace-\=*
当替代字符串以 "\=" 开始时,其余部分被解释为一个表达式。该功能不能递归调用。出
现在该表达式里面的 |substitute()| 函数不能使用 "\=" 作为替代字符串。
除了 "<CR>" 以外,|sub-replace-special| 提到的字符的特殊含义这里不适用。<NL>
字符被用作换行符,双引号字符串 "\n" 也可以。在 <NL> 之前加上反斜杠得到一个真正
的 <NL> 字符 (在文件里成为 NUL)。
"\=" 记法也可用于 |substitute()| 函数的第三个参数 {sub} 之内,这时,
|sub-replace-special| 指出的特殊含义完全不适用。具体说,<CR> 和 <NL> 不用作换
行,而分别是回车和新行。
如果结果是 |List|,连接其中的项目并以换行符分隔。这样,每个项目单独成为一行,
当然本身就包含换行符的除外。
完整的匹配可以用 "submatch(0)" 得到。首个括号里的匹配可以用 "submatch(1)",余
者类似。
小心: 分隔符不能出现在表达式里!可以考虑使用 "@" 或者 ":" 那样的字符。执行结果
里出现分隔符不成问题。
例如: >
:s@\n@\="\r" . expand("$HOME") . "\r"@
把换行符替代为包含 $HOME 值的一个新行。 >
s/E/\="\<Char-0x20ac>"/g
把所有的 'E' 字符替代为欧元符号。详见 |<Char->|。
4.3 搜索与替代 *search-replace*
*:pro* *:promptfind*
:promptf[ind] [string]
弹出搜索对话框。如果给出 [string],它被用作初始的搜索
字符串。
{仅适用于 Win32、Motif 和 GTK GUI 环境}
*:promptr* *:promptrepl*
:promptr[epl] [string]
弹出搜索/替代对话框。如果给出 [string],它被用作初始的
搜索字符串。
{仅适用于 Win32、Motif 和 GTK GUI 环境}
4.4 改变制表 *change-tabs*
*:ret* *:retab* *:retab!*
:[range]ret[ab][!] [new_tabstop]
把所有包含 <Tab> 的空白序列替代成由新的制表位
[new_tabstop] 确定的空白序列。如果你不指定新的制表位,
或者它为 0,Vim 使用原来的制表位 'tabstop'。
已有的 Tab 的宽度总是用 'tabstop' 的当前值来计算。
如果有 !,Vim 也在合适的时候,把只包含正常空格的字符串
换成 Tab。
如果置位了 'expandtab',Vim 把所有的 Tab 换成相当的空
格。
该命令把 'tabstop' 设为新值。如果按照缺省的情况,在全
文件上进行处理,视觉上应该不会有任何改变。
小心: 该命令修改 C 程序中的字符串里的任何 <Tab> 字符。
要避免这一点,用 "\t" (无论如何,应该养成这个好的习
惯)。
`:retab!` 也把空格序列换成 <Tab>,这可能会使 printf()
引起混淆。
{Vi 无此功能,仅在编译时加入 |+ex_extra| 特性才有效}
*retab-example*
下面的例子使用自动命令和 ":retab" 来编辑使用制表位为 8 的文件,但在编辑时制表
位设置为 4。警告: 字符串里的空格会被改变。另见 'softtabstop' 选项。 >
:auto BufReadPost *.xx retab! 4
:auto BufWritePre *.xx retab! 8
:auto BufWritePost *.xx retab! 4
:auto BufNewFile *.xx set ts=4
==============================================================================
5. 复制并移动文本 *copy-move*
*quote*
"{a-zA-Z0-9.%#:-"} 指定下次的删除、抽出和放置命令使用的寄存器
{a-zA-Z0-9.%#:-"} (大写字符使得删除和抽出命令附加到该
寄存器) ({.%#:} 只能用于放置命令)。
*:reg* *:registers*
:reg[isters] 显示所有编号和命名寄存器的内容。但不列出用于 |:redir|
目的地的寄存器。
{Vi 无此功能}
:reg[isters] {arg} 显示 {arg} 里提到的编号和命名寄存器的内容。例如: >
:dis 1a
< 显示寄存器 '1' 和 'a'。{arg} 里可以用空格。
{Vi 无此功能}
*:di* *:display*
:di[splay] [arg] 和 :registers 相同。{Vi 无此功能}
*y* *yank*
["x]y{motion} 抽出 {motion} 跨越的文本 [到寄存器 x]。如果没有字符被
抽出 (例如,在第一列执行 "y0") 并且 'cpoptions' 里包括
'E' 标志位,这是一个错误。
*yy*
["x]yy 抽出 [count] 行 [到寄存器 x] |linewise| 行动作。
*Y*
["x]Y 抽出 [count] 行 [到寄存器 x] (等同于 yy,|linewise| 行
动作)。如果你想要 "Y" 执行从光标到行尾的操作 (更合乎逻
辑,但是与 Vi 不兼容),用 ":map Y y$"。
*v_y*
{Visual}["x]y 抽出高亮文本 [到寄存器 x] (关于 {Visual} 见
|Visual-mode|)。{Vi 无此功能}
*v_Y*
{Visual}["x]Y 抽出高亮行 [到寄存器 x] (关于 {Visual} 见
|Visual-mode|)。{Vi 无此功能}
*:y* *:yank* *E850*
:[range]y[ank] [x] 抽出 [range] 所指定的行 [到寄存器 x]。仅当包含
|+clipboard| 特性时才可以抽出到 "* 或 "+ 寄存器。
:[range]y[ank] [x] {count}
从 [range] 的最后一行开始 (缺省: 当前行
|cmdline-ranges|) 抽出 {count} 行 [到寄存器 x]。
*p* *put* *E353*
["x]p 放置文本 [从寄存器 x] 在光标之后 [count] 次。{Vi: 没有
计数}
*P*
["x]P 放置文本 [从寄存器 x] 在光标之前 [count] 次。{Vi: 没有
计数}
*<MiddleMouse>*
["x]<MiddleMouse> 从一个寄存器放置文本在光标之前 [count] 次。除非另外指
定,否则用 "* 寄存器。
光标停留在新文本的尾部。
只有在 'mouse' 包含 'n' 或者 'a' 时鼠标才会工作。
{Vi 无此功能}
如果你有滚轮鼠标而且经常不小心粘贴了文本,你可以使用以
下映射来关闭鼠标中键粘贴的功能: >
:map <MiddleMouse> <Nop>
:imap <MiddleMouse> <Nop>
< 你也许还想要关闭多键击的功能。参见 |double-click|。
*gp*
["x]gp 如同 "p",但光标停留在新文本之后。{Vi 无此功能}
*gP*
["x]gP 如同 "P",但光标停留在新文本之后。{Vi 无此功能}
*:pu* *:put*
:[line]pu[t] [x] 放置文本 [从寄存器 x] 在行号 [line] (缺省为当前行) 之
后。它总是 |linewise| 行动作,因而这个命令可以用来把抽
出的块放置在新行上。
如果未指定寄存器,则取决于 'cb' 选项: 如果 'cb' 包含
"unnamedplus",则从 + 寄存器 |quoteplus| 取出,否则如
果 'cb' 包含 "unnamed",则从 * 寄存器 |quotestar| 取
出,否则,从无名寄存器 |quote_quote| 取出。
寄存器也可以是 '=',跟随一个可选的表达式。表达式继续到
该命令结束为止。你需要在 '|' 和 '"' 字符前加上反斜杠不
让它们终止你的命令行。例如: >
:put ='path' . \",/test\"
< 如果 '=' 之后没有表达式,Vim 使用前一个表达式。用
":dis =" 你可以看到它。
:[line]pu[t]! [x] 放置文本 [从寄存器 x] 在行号 [line] (缺省为当前行) 之
前。
["x]]p 或 *]p* *]<MiddleMouse>*
["x]]<MiddleMouse> 类似 "p",但调整当前行的缩进。只有在 'mouse' 包含 'n'
或者 'a' 时鼠标才会工作。{Vi 无此功能}
["x][P 或 *[P*
["x]]P 或 *]P*
["x][p 或 *[p* *[<MiddleMouse>*
["x][<MiddleMouse> 类似 "P",但调整当前行的缩进。只有在 'mouse' 包含 'n'
或者 'a' 时鼠标才会工作。{Vi 无此功能}
你可以用这些命令把文本从一个地方复制到另一个地方。首先,把文本用抽出、删除或者
修改命令取到一个寄存器里,然后用放置命令把寄存器的内容插入。你可以用这些命令把
文本从一个文件移动到另一个文件,因为 Vim 在切换缓冲区时保留所有的寄存器
(CTRL-^ 命令可用来快捷地切换文件)。
*linewise-register* *characterwise-register*
除了 :put 以外,你可以用 "." 重复放置命令,你也可以撤销它们。如果保存到寄存器
文本的命令是 |linewise| 行动作,Vim 把文本插入在光标所在的行之下 ("p") 或之上
("P")。不然,Vim 把文本插入在光标的之后 ("p") 或之前 ("P")。":put" 命令使得
Vim 总是把文本放在下一行。你可以用命令序列 "xp" 来交换两个字母。你可以用 "ddp"
命令序列来交换两行。你还可以用 "deep" 命令交换两个单词 (光标在第一个单词之前的
空白上)。你更可以在放置命令之后用 "']" 或者 "`]" 命令把光标移动到插入文本之
后,或者用 "'[" 或 "`[" 把光标移动到文本的开始处。
*put-Visual-mode* *v_p* *v_P*
在可视模式下使用如 |p| 或者 |P| 之类的放置命令时,Vim 试图把选择的文本替换成寄
存器的内容。是否工作如你所愿决定于选择的类型和寄存器里文本的类型。对于列块选择
而言,它也决定于列块的大小,和头尾是否在已存在的字符上。(实现细节: 实际上,它
先把寄存器的内容放到选择区之后,再删除选择区的内容。)
前次选择的文本被放在无名寄存器中。如果希望把相同的文本重复放入可视选择区多次,
请选用其它寄存器。例如,先抽出要复制的文本,再可视化选择要替换的文本,然后使用
"0p。重复任意多次均可,而每次无名寄存器都会被改变。
*blockwise-register*
如果你使用面向列块的可视模式命令把文本存到寄存器里,文本列块会被插入在当前和其
后的行的当前列之前 ("P") 或之后 ("p")。Vim 使得整个文本列块从同一列开始。这样,
插入的文本看上去和抽出或删除时看起来一样。为了使之可能,Vim 可能需要把一些
<Tab> 字符替换成空格。不过,如果列块的宽度不是 <Tab> 宽度的整数倍并且插入列块
之后文本里包含 <Tab> 的时候,那些文本可能就不会那么整齐。
注意 在一个面向字符的抽出命令之后,Vim 把光标停留在最接近缓冲区开头的第一个被
抽出的字符之上。这意味着 "yl" 不会移动光标,但是 "yh" 把光标向左移一格。
逻辑: 在 Vi 里 "y" 命令跟一个反向的动作有时不会把光标移动到第一个被
抽出的字符之上,因为屏幕没有刷新。Vim 符合 Posix 的规范,总是
把光标移动到第一个字符之上。
在一个面向行的抽出命令之后,光标放在第一行上,但是列保持不变,所以不必然在第一
个抽出的字符上。
共有九种类型的寄存器: *registers* *E354*
1. 无名寄存器 ""
2. 10 个编号寄存器 "0 到 "9
3. 行内删除寄存器 "-
4. 26 个命名的寄存器 "a 到 "z 或者 "A 到 "Z
5. 四个只读寄存器 ":、".、"% 和 "#
6. 表达式寄存器 "=
7. 选择和拖放寄存器 "*、"+ 和 "~
8. 黑洞寄存器寄存器 "_
9. 最近搜索模式寄存器 "/
1. 无名寄存器 "" *quote_quote* *quotequote*
用 "d"、"c"、"s"、"x" 等命令删除或者用 "y" 等抽出命令复制的文本都被 Vim 用来填
充该寄存器,不管是否用到别的专门寄存器 (例如 "xdd)。这就好像无名寄存器是指向最
近使用的那个寄存器的指针一样。使用大写寄存器进行添加时,无名寄存器包含和命名寄
存器相同的文本。'_' 寄存器是一个特例。"_dd 不把删除的文本存在任何寄存器里。
不指定寄存器的放置命令 (p 或 P) 使用无名寄存器的内容。你也可以用 '"' 作为名字
来访问该寄存器。这意味着要输入两个连续的双引号。写入 "" 寄存器将实际写到寄存器
"0 上。{Vi: 寄存器内容在更换文件时丢失,没有 '"'}
2. 编号寄存器 "0 到 "9 *quote_number* *quote0* *quote1*
*quote2* *quote3* *quote4* *quote9*
Vim 把抽出和删除命令的文本保存在这些寄存器里。
编号寄存器 0 包含最近抽出的文本,除非该命令用 ["x] 指定了别的寄存器。
编号寄存器 1 包含了最近删除或者修改的文本,除非该命令用 ["x] 指定了别的寄存
器或者该文本小于一行 (该情况下使用行内删除寄存器)。以下移动命令在应用删除操作
符时例外: |%|、|(|、 |)|、|`|、|/|、|?|、|n|、|N|、|{| 和 |}|。这时,总是使用
寄存器 "1 (为了和 Vi 兼容)。如果文本小于一行,同时使用 "- 寄存器。
每来一次新的删除和修改,Vim 把前一次的寄存器 1 的内容复制到寄存器 2,2 到
3,依此类推。而寄存器 9 的内容就丢失了。
{Vi: 编号寄存器的内容在更换文件时丢失;寄存器 0 不存在}
3. 行内删除寄存器 "- *quote_-* *quote-*
该寄存器保存删除不到一行内容的命令的文本,除非该命令用 ["x] 指定了寄存器。
{Vi 无此功能}
4. 命名寄存器 "a 到 "z 或者 "A 到 "Z *quote_alpha* *quotea*
Vim 只有在你指定的时候才使用这些寄存器。指定为小写字母时替换原来的内容,指定为
大写字母时附加到原来的内容。如果 'cpoptions' 里有 '>' 标志位,在附加文本前插入
一个换行符。
5. 只读寄存器 ":、".、"% 和 "#
它们是 '%'、'#'、':' 和 '.'。你只能在 "p"、"P"、":put" 命令和 CTRL-R 的时候使
用它们。{Vi 无此功能}
*quote_.* *quote.* *E29*
". 包含最近插入的文本 (和插入模式命令 CTRL-A 和 CTRL-@ 插入的一
样)。注意: 它不适用于 CTRL-R 在命令行上的操作。它的工作方式稍
有不同,例如,文本是被插入而不是放置的 ('textwidth' 和其它选项
影响插入的内容)。
*quote_%* *quote%*
"% 包含当前文件名。
*quote_#* *quote#*
"# 包含轮换文件名。
*quote_:* *quote:* *E30*
": 包含最近执行过的命令行。例如: 用 "@:" 重复上次执行过的命令行命
令。只有当一个命令行中至少一个字符是键入的,该寄存器才会保存命
令行的内容。所以,如果命令行完全来自映射,该寄存器保持不变。
{仅当编译时加入 |+cmdline_hist| 特性才有效}
6. 表达式寄存器 "= *quote_=* *quote=* *@=*
其实并没有这么一个寄存器可以储存文本,但是这是用来在使用寄存器的命令中使用表达
式的一个方式。表达式寄存器是只读的,你不能把文本放置其中。在 '=' 之后,光标移
到命令行上,这时你可以输入任何的表达式 (见 |expression|)。所有普通的命令行编辑
命令都可以使用,还有一个表达式专门的历史表。当你按回车结束命令行时,Vim 计算表
达式的结果。如果你用 <Esc> 结束,Vim 终止表达式。如果你不输入表达式,Vim 使用
最近的表达式 (和 "/" 命令的处理相似)。
表达式的计算结果必须是一个字符串。数值结果会自动转化为字符串。对 "p" 和 ":put"
命令而言,浮点数结果也会被转化为字符串。如果结果为列表,每个成员被转成字符串,
然后被单独放在一行上。字典、函数引用类型的结果则产生错误信息 (通过 string() 转
化)。
如果 "= 寄存器被 "p" 命令使用,该字符串会在 <NL> 字符处断开。如果该字符串以
<NL> 结尾,则它被视为一个面向行的寄存器。{Vi 无此功能}
7. 选择和拖放寄存器 "*、"+ 和 "~
用这些寄存器来保存和取得 GUI 界面选择的文本。参见 |quotestar| 和 |quoteplus|。
如果剪贴板不存在或者不工作,使用无名寄存器。Unix 上,仅当 |+xterm_clipboard|
特性存在时剪贴板才可用。{Vi 无此功能}
注意 "* 和 "+ 在 X11 系统上有分别。关于该差别的解释,参见 |x11-selection|。在
MS-Windows 上,"* 和 "+ 的使用实际上是等价的,可见 |gui-clipboard|。
*quote_~* *quote~* *<Drop>*
只读的 "~ 寄存器保存最近一次拖放操作放下的文本。如果有什么东西被放到 Vim 上,
"~ 寄存器被填充,<Drop> 虚拟键被激活。如果你需要,你可以重定义该键的映射;缺省
的动作 (适用于所有模式) 是把 "~ 寄存器的内容插入到当前光标位置。{Vi 无此功能}
{仅当编译时加入 |+dnd| 特性才有效,当前只适用于 GTK GUI 版本}
注意: "~ 寄存器仅用于在 Vim 上拖放普通文本。拖放 URI 列表在内部处理。
8. 黑洞寄存器 "_ *quote_*
当写到这个寄存器时,什么都不会发生。这可以用来删除文本,而不影响任何正常的寄存
器。从该寄存器读时,什么都不会返回。{Vi 无此功能}
9. 最近搜索模式寄存器 "/ *quote_/* *quote/*
含有最近搜索的模式。它被 "n" 和 'hlsearch' 使用。可以用 `:let` 来修改。你可以
改变它使得 'hlsearch' 不经过实际的搜索直接高亮某些匹配。你不能把抽出或者删除命
令的内容放到该寄存器上。搜索方向则可从 |v:searchforward| 得到。
注意 从函数返回时该值被复原 |function-search-undo|。
{Vi 无此功能}
*@/*
你可以用 `:let` 命令写到一个寄存器 |:let-@|。例如: >
:let @/ = "the"
如果你用放置命令而不指定寄存器,Vim 使用上次填充的寄存器 (这也是无名寄存器的内
容)。如果你弄糊涂了,用 `:dis` 命令看看 Vim 会放置什么内容 (该命令显示所有的有
名和无名的寄存器;无名寄存器被标为 '"')。
下面三个命令总是针对整行工作。
:[range]co[py] {address} *:co* *:copy*
把 [range] 指定的行复制到 {address} 给出的行之下。
*:t*
:t 和 :copy 等价。
:[range]m[ove] {address} *:m* *:mo* *:move* *E134*
把 [range] 指定的行移动到 {address} 给出的行之下。
==============================================================================
6. 文本排版 *formatting*
:[range]ce[nter] [width] *:ce* *:center*
在 [range] 指定范围的行和 [width] 限定的列 (缺省为
'textwidth',如其为 0,则取 80) 范围内的文本居中对齐。
{Vi 无此功能}
只有在编译时加入 |+ex_extra| 特性时才有此功能。
:[range]ri[ght] [width] *:ri* *:right*
在 [range] 指定范围的行和 [width] 限定的列 (缺省为
'textwidth',如其为 0,则取 80) 范围内的文本靠右对齐。
{Vi 无此功能}
只有在编译时加入 |+ex_extra| 特性时才有此功能。
*:le* *:left*
:[range]le[ft] [indent]
在 [range] 指定范围的行的文本靠左对齐。其缩进的距离可
由 [indent] 设置 (缺省为 0)。
{Vi 无此功能}
*gq*
gq{motion} 对 {motion} 动作跨越的行进行排版。
排版使用如下三种方式之一:
1. 如果 'formatexpr' 不为空,计算该表达式。每个缓冲区
的值可以不同。
2. 如果 'formatprg' 不为空,使用外部程序。
3. 否则,使用内部排版机制。
第三种方式使用 'textwidth' 选项控制所有待排版行的行宽
(见下)。
如果 'textwidth' 选项为 0,则排版行宽设为屏幕的宽度
(但最大宽度不超过 79)。
'formatoptions' 选项控制排版的方式 |fo-table|。
光标停留在排版行末行的第一个非空白处。
注意: "Q" 命令以前执行此项功能。如果你还想继续用 "Q"
来排版,执行如下映射命令: >
:nnoremap Q gq
gqgq *gqgq* *gqq*
gqq 排版当前行。如带计数排版相应多行。{Vi 无此功能}
*v_gq*
{Visual}gq 排版高亮文本 ({Visual} 的部分参见 |Visual-mode|)。
{Vi 无此功能}
*gw*
gw{motion} 对 {motion} 动作跨越的行进行排版。和 |gq| 类似,但排版
后光标恢复原位。而且不使用 'formatprg' 和 'formatexpr'
选项。
{Vi 无此功能}
gwgw *gwgw* *gww*
gww 对当前行排版,其它和 "gw" 类同。{Vi 无此功能}
*v_gw*
{Visual}gw 排版高亮文本,其它和 "gw" 类同。({Visual} 可见
|Visual-mode|)。{Vi 无此功能}
例如: 要排版当前段落,可用: *gqap* >
gqap
"gq" 命令后,光标随着指定的移动命令移动。这使得用 "." 进行连续排版成为可能。例
如,"gqj" (对当前行和下一行排版) 和 "gq}" (排版到段落尾) 便可如此。注意: 如果
设置了 'formatprg',"gq" 把光标留在排版后的首行 (如同过滤命令那般)。
如果你想对当前段落排版后留在原来的位置,可用: >
gwap
如果你想使段落自动排版,可以在 'formatoptions' 里加入 'a' 标志位。参见
|auto-format|。
如果 'autoindent' 选项打开,Vim 用首行的缩进距离排版其后的所有行。
排版不会改变空行 (但会改变只有空白字符的行!)。
如果有连接行的操作,应用 'joinspaces' 选项。
你可以设置 'formatexpr' 选项为某表达式或设置 'formatprg' 选项为外部程序名,Vim
会用之进行文本排版。'textwidth' 等选项对外部程序的排版不起作用。
*right-justify*
Vim 没有靠右控制对齐 (right justify) 文本的命令。你可以用 "par" 这样的外部命令
来实现 (例如, "!}par" 对到段落尾的文本排版),或者设置 'formatprg' 为 "par"。
*format-comments*
用户手册的 |30.6| 一节给出注释排版的总览。
Vim 可以自动对注释的插入和排版进行特殊处理。Vim 把以特定字符串开头 (忽略空白)
的行识别为注释。以下是三种不同类型的注释:
- 在每行的开头都出现的注释字符串。例如,外壳脚本使用的注释行都以 "#" 开头。
- 只在首行出现的注释字符串。使用连字符 "-" 的本列表就是这样的一个例子,
- 由三部分组成的注释,包括起始字符串,结尾字符串,和两者之间可选的行的起始字符
串。三种字符串可分别指定。如下 C 风格的注释就是如此:
/*
* this is a C comment
*/
'comments' 选项是一个由逗号分隔的列表。每个部分定义一种类型的注释字符串。每个
部分的组成方式是:
{flags}:{string}
{string} 是必须出现的字符串 (不作转义)。
{flags}:
n 可嵌套的注释: 允许多个部分间的嵌套。例如,'comments' 为 "n:),n:>"。则
以 "> ) >" 开始的行视为注释。
b 在 {string} 之后必须有空白字符 (<Space>、<Tab> 或 <EOL>)。
f 该注释字符串只在首行出现。下一行不重复注释,但保留相同的缩进 (例如,带
符号的列表 (bullet-list))。
s 三段式注释的起始字符串
m 三段式注释的中间字符串
e 三段式注释的结尾字符串
l 左对齐。和 's' 或 'e' 一起使用。起始或结尾字符串的最左字符和中间字符串
的最左字符对齐。
这是缺省值,可以省略。详情见下。
r 右对齐。同上,不过不是最左字符而是最右字符。详情见下。
O "O" 命令不把它当作注释。
x 允许三段式注释用以下方式结束: 在中间字符串自动提供的情况下,在新行第一
个动作是输入结尾字符串的最后一个字符。详情见下。
{digits}
在和 's' 或 'e' 一起使用时: 对自动插入的中间或结尾字符串增加 {digit}
单位的位移。该位移以左对齐的位置为基准。详情见下。
-{digits}
和 {digits} 类似,但减少缩进。这只对开始或结尾部分至少有相当数量的缩进
时才有效。
如果一个字符串没有 'f'、's'、'm' 或 'e' 任何一个标志位,Vim 假设注释字符串在每
行都重复出现。标志位部分可以为空。
在 {string} 之前或之后的任何空白都是 {string} 的一部分,所以不要随便留出开头或
结尾的空白,除非空白的确是注释字符串的一部分。
如果某个注释字符串是另一个字符串的一部分,先指定完整的,再指定部分的。例如,要
包含 "-" 和 "->",用 >
:set comments=f:->,f:-
三段式注释必须以开始、中间和结尾三部分给出,而且不能间杂其它的部分。一个三段式
C 注释的例子是 >
sr:/*,mb:*,ex:*/
为了避免形如 "*ptr" 的内容被识别为注释,这里的中间字符串包含了 'b' 标志位。对
三段式注释而言,Vim 从开始和中间字符串之后查找结尾字符串。如果找到,注释就不会
再从下一行继续。三段式注释必须要有一个中间字符串,不然 Vim 无法识别中间的那些
行。
注意 上述三段式注释定义里的 "x" 标志位。当你在一个 C-注释里按回车时,Vim 会自
动在新行后插入中间字符串: " * "。要结束注释,你只需要在新行里首先键入 "/"。这
样就把中间字符串替换成结尾字符串并应用指定的对齐方式,成为了 " */"。从而省却了
先按退格键的麻烦。
如果同时匹配中间部分和结尾部分但结尾部分更长,使用结尾部分。这样 C 风格注释就
不需要中间部分后加空格了。
这里是一个关于用于对齐的标志位的例子,使得注释看起来很突出 (也很像一个 1 字)。
考虑注释字符串: >
:set comments=sr:/***,m:**,ex-2:******/
<
/*** ~
**<--右对齐,来自 "r" 标志位 ~
** ~
2 个单位的位移,来自 "2" 标志位--->** ~
******/ ~
该例中,第一行注释是键入的,然后按回车四次,最后按 "/" 以结束注释。
这里是三部分注释的一些细节。有三个时间点应用对齐和位移标志位: 输入起始字符串后
开启新行、在结尾字符串前开启新行、三部分注释的自动结束。而结尾部分的对齐标志位
要反过来看;这样,相同的对齐标志位在分别用于 "s" 和 "e" 时才会使起始和结尾部分
有相同的缩进。每个注释部分只应用一种对齐方式,但位移优先于 "r" 和 "l" 标志位。
打开 'cindent' 在很多情况下会覆盖对齐标志位。使用其它方法,如 |gq| 或 |=| 来重
新缩进也不会参考对齐标志位。这些其它的排版选择可以定义类似的行为。一个担心是
'cindent' 虽然有众多附加的选项来对注释进行基于上下文的缩进,但不能再现三部分注
释的缩进对齐。但 'indentexpr' 应该有能力很好地处理三部分注释。
其它示例: >
"b:*" 包含 "*" 开头的行,但 "*" 后面不是空白的除外。这样避免指针取值
操作 "*str" 被识别为注释。
"n:>" 包含形如 ">"、">>"、">>>" 等开头的行。
"fb:-" 包含 "- " 开头的列表,可用来自动排版。
该选项的缺省值是 "b:#"。这意味着 "#include" 开头的行不会被认为是注释,但
"# define" 是。这是个不得不然的妥协。
{仅当编译时加入 |+comments| 特性才有效}
*fo-table*
你可以使用 'formatoptions' 选项来控制 Vim 如何对文本进行排版。'formatoptions'
是一个字符串,它可以包含下列字符。缺省设置是 "tcq"。为了提高可读性,你可以用逗
号分隔选项字符。
字符 在 'formatoptions' 里代表的含义 ~
t 使用 'textwidth' 自动回绕文本
c 使用 'textwidth' 自动回绕注释,自动插入当前注释前导符。
r 在插入模式按回车时,自动插入当前注释前导符。
o 在普通模式按 'o' 或者 'O' 时,自动插入当前注释前导符。
q 允许 "gq" 排版时排版注释。
注意 排版不会影响空行或者只有注释前导符的行。这样的行开启一个新段落,
注释前导符的改变也是如此。
w 拖尾的空格指示下一行继续同一个段落。而以非空白字符结束的行结束一个段
落。
a 自动排版段落。每当文本被插入或者删除时,段落都会自动进行排版。参见
|auto-format|。
如果 'c' 标志位存在,该设置只对识别的注释有效。
n 在对文本排版时,识别编号的列表。实际上,这里使用了 'formatlistpat' 选
项,所以可以使用任何类型的列表。出现在数字之后的文本缩进距离被应用到后
面的行。数字之后可以有可选的 '.'、 ':'、')'、']' 或者 '}'。
注意 'autoindent' 也必须置位。不要和 "2" 一起使用,效果不好。
示例: >
1. 第一项
回绕文字
2. 第二项
2 在对文本排版时,将段落第二行而非第一行的缩进距离应用到其后的行上。这适
用于第一行有特殊缩进需要的段落。注意 'autoindent' 也必须置位。
示例: >
first line of a paragraph
second line of the same paragraph
third line.
< 也适用于注释内部,并忽略注释前导符。
v Vi-兼容的插入模式自动回绕: 只有在当前输入命令键入的空白上才会分行。
(注意: 这并不能 100% Vi 兼容。Vi 在这方面有些 "意想不到的特性",换而言
之,漏洞。它使用屏幕列而非实际的列。)
b 和 'v' 类似,但只有在键入空白时还没抵达或者刚到回绕边界的时候才会自动
回绕。如果一行在开始插入之前已经超过 'textwidth' 指定的长度,或者在到
达 'textwidth' 之时没有输入过空白,Vim 不会自动回绕。
l 插入模式不分行: 当一行已经超过 'textwidth' 时,插入命令不会自动排版。
m 可以在任何值高于 255 的多字节字符上分行。这对亚洲文本尤其有用,因为每
个字符都是单独的单位。
M 在连接行时,不要在多字节字符之前或之后插入空格。优先于 'B' 标志位。
B 在连接行时,不要在两个多字节字符之间插入空格。有 'M' 标志位时无效。
1 不要在单字母单词后分行。如有可能,在它之前分行。
j 在合适的场合,连接行时删除注释前导符。例如,连接:
int i; // the index ~
// in the list ~
结果是:
int i; // the index in the list ~
't' 和 'c' 不同组合方式决定 Vim 何时进行自动回绕:
值 行为 ~
"" 没有自动排版 (你可以用 "gq" 进行手工排版)
"t" 自动排版文本,不包括注释
"c" 自动排版注释,不包括文本 (对 C 程序适用)
"tc" 自动排版文本和注释
注意 如果 'textwidth' 为 0,Vim 不会做任何自动排版 (但是会根据 'comments' 选项
自动插入注释前导符)。但 'a' 标志位存在时有例外。|auto-format|
注意 如果 'paste' 打开,Vim 也不会做任何排版。
注意 即使 Vim 不做自动回绕,仍然可以把 'textwidth' 设为非零。'textwidth' 对
"gq" 的排版依然有用。
如果 'comments' 选项包含 "/*"、"*" 和/或 "*/",Vim 有一套处理这些注释更加聪明
的内嵌方法。在 "/*" 或 "*/" 之前或之后开始一个新行 (在 'formatoptions' 里有
'r' 或者 'o' 的情况下),会自动给出正确的开始部分。排版或者自动回绕也会有相同的
处理。在以 "/*" 或者 "*" 开始并包含 "*/" 的行之后开启新行,就不会插入注释前导
符,而且新行的缩进由注释起始行决定。
例如: >
/* ~
* 你的任何注释。
*/ ~
该行的缩进和以上注释的起始行相同。
上述这些应该已经十分够用了,尤其在与新的 :autocmd 命令协同使用时,可以为不同文
件类型提供不同的设置。
一些例子:
适用于 C 代码 (只对注释排版): >
:set fo=croq
< 适用于邮件/新闻 (排版所有文本,"o" 命令不开始注释): >
:set fo=tcrq
<
自动排版 *auto-format* *autoformat*
如果 'formatoptions' 里包含 'a' 标志位,在插入或者删除文本时会自动进行排版。这
对编辑文本段落很好用。以下对如何使用这一功能提供一些提示:
- 你需要正确定义何谓段落。最简单的方式是以空行分隔的为段落。如果没有分隔的空
行,考虑用 'w' 标志位并在段落中除了最后一行以外,每行结尾加上一个空格。
- 你可以根据文件类型 |filetype|, 或者用 |modeline| 指定特定文件的方式,设置不
同的 'formatoptions'。
- 将 'formatoptions' 设为 "aw2tq" 使得文本以如下方式缩进:
bla bla foobar bla
bla foobar bla foobar bla
bla bla foobar bla
bla foobar bla bla foobar
- 如果只想自动排版注释,加上 'c' 标志位。可用于源代码。
- 设置 'textwidth' 为你希望的宽度。如果为零,使用 79 或屏幕宽度中较小的那个。
还有一些警告:
- 如果段落没有正确分隔,任何改变都会使得所有相连的文本自动排版。考虑 >
:set fo-=a
- 如果用 'w' 标志位 (行尾的空格意味着段落的继续) 并且用 |dd| 删除了段落的末
行,这段落自动和下一个段落合并为一个段落。
- 改变的文本被保存以备可能的撤销之用。排版也是改变的一种。所以每次排版都会为撤
销保存文本。这会有相当的内存开销。
- 排版一个很长的段落和/或复杂的缩进也许会相当慢。
==============================================================================
7. 文本排序 *sorting*
Vim 有排序函数和排序命令。排序函数可见: |sort()|。
*:sor* *:sort*
:[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]
给 [range] 里的行排序。如果没有给出行范围,给所有行排
序。
带 [!] 则反向排序。
带 [i] 则忽略大小写。
带 [n] 则排序基于每行的第一个十进制数 (在 {pattern} 匹
配之后或之内)。
数值包含前导的 '-'。
带 [x] 则排序基于每行的第一个十六进制数 (在 {pattern}
匹配之后或之内)。忽略引导的 "0x" 或 "0X"。
数值包含前导的 '-'。
带 [o] 则排序基于每行的第一个八进制数 (在 {pattern} 匹
配之后或之内)。
带 [u] 则只保留完全相同的行的第一行 (如果带 [i],忽略
大小写的区别)。
没有这个标志位,完全相同的行的序列会按照它们原来的顺序
被保留下来。
注意 引导和拖尾的空白差异会导致不相同的行。
如果指定 /{pattern}/ 并且没有 [r] 标志位,跳过匹配
{pattern} 的文本,使得排序在匹配之后的内容上进行。
除了斜杠以外,任何非字母的字符都可以。
例如,要按第二个逗号分隔的字段排序: >
:sort /[^,]*,/
< 按虚拟第 10 列的文本排序 (从而忽略制表和空格的区别): >
:sort /.*\%10v/
< 按每行的第一个数值排序,不管它前面有什么: >
:sort /.\{-}\ze\d/
< (说明: ".\{-}" 匹配任何文本,"\ze" 设置匹配结束位置,
\d 匹配单个数位。)
带 [r] 则排序在匹配 {pattern} 的文本上进行,而不是如上
所述的用它之后的文本。
例如,要按每行的前三个字母排序且只看这三个字母: >
:sort /\a\a\a/ r
< 如果使用 {pattern},不匹配 {pattern} 的行按照它们原来
的顺序被保留,但和匹配 {pattern} 的行分开。如果反向排
序,它们会以反向顺序出现,并在排序好的行之后。否则它们
会以原有顺序出现,在排序好的行之前。
如果 {pattern} 为空 (例如指定 //),则使用最近使用的搜
索模式。这样你可以先试好模式,然后在执行。
注意 `:sort` 和 `:global` 一起使用并不能对匹配的行进行排序,这样做没有意义。
排序的细节取决于使用的库函数。不能保证它是 "稳定" 排序,也不能保证排序依赖于当
前的 locale。你要自己试试才知道。
排序可以被中断,但在整个过程里如果中断得太晚,最后可能会出现重复的行。这取决于
使用的系统库函数。
vim:tw=78:ts=8:ft=help:norl: