File: usr_41.dex

package info (click to toggle)
vimhelp-de 7.3.101122-2
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 660 kB
  • sloc: makefile: 34
file content (2650 lines) | stat: -rw-r--r-- 94,748 bytes parent folder | download
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
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
*usr_41.txt*	Für Vim version 7.3.  Letzte Änderung: 2010-Jul-20

		     VIM BENUTZERHANDBUCH - von Bram Moolenaar

			      Ein Vim-Skript schreiben


Vims Skriptsprache wird für die Startup-Datei vimrc, Syntax-Dateien und
viele andere Dinge verwendet.  Dieses Kapitel erklärt die Elemente, die in
einem Vim-Skript benutzt werden können.  Davon gibt es eine Menge, daher
ist dies ein langes Kapitel.

|41.1|	Einführung
|41.2|	Variablen
|41.3|	Ausdrücke
|41.4|	Bedingungen
|41.5|	Einen Ausdruck ausführen
|41.6|	Funktionen benutzen
|41.7|	Eine Funktion definieren
|41.8|	Listen und Wörterbücher
|41.9|	Ausnahmen
|41.10|	Verschiedene Anmerkungen
|41.11|	Ein Plugin schreiben
|41.12|	Ein Dateityp-Plugin schreiben
|41.13|	Ein Kompiler-Plugin schreiben
|41.14|	Ein Plugin so schreiben, dass es schnell lädt
|41.15|	Bibliotheksskripte schreiben
|41.16|	Vim-Skripte verteilen

Nächstes Kapitel: |usr_42.txt|  Neue Menüs hinzufügen
 Voriges Kapitel: |usr_40.txt|  Neue Befehle machen
Inhaltsübersicht: |usr_toc.txt|

==============================================================================
*41.1*	Einführung				*vim-script-intro* *script*

Ihre erste Erfahrung mit Vim-Skripten ist die Datei vimrc.  Vim liest sie beim
Start und führt die Befehle aus.  Sie können Optionen auf Werte setzen, die
Sie bevorzugen.  Und Sie können jeden Doppelpunkt-Befehl in ihr benutzen
(Befehle, die mit »:« starten, diese werden manchmal Ex-Befehle oder
Befehlszeilen-Befehle genannt.
   Syntax-Dateien sind ebenfalls Vim-Skripte. So wie Dateien, die für einen
bestimmten Dateityp Optionen setzen.  Ein kompliziertes Makro kann in einer
eigenen Vim-Skript-Datei definiert werden.  Sie können sich nun weitere
Möglichkeiten ausmalen.

Lassen Sie uns mit einem einfachen Beispiel beginnen: >

	:let i = 1
	:while i < 5
	:  echo "Zähler ist" i
	:  let i += 1
	:endwhile
<
	Anmerkung:
	Die »:« werden hier nicht wirklich gebraucht.  Sie brauchen sie nur,
	wenn Sie einen Befehl in Vim tippen.  In einer Vim-Skript-Datei können
	sie ausgelassen werden.  Wir benutzen Sie hier dennoch, um klar zu
	machen, dass dies Doppelpunkt-Befehle sind, und um sie sich von den
	Befehlen des Normalmodus abheben zu lassen.
	Anmerkung:
	Sie können die Beispiele ausprobieren, indem Sie die Zeilen von hier
	in ein Register kopieren und sie mit :@" ausführen.

Die Ausgabe des Beispielcodes ist:

	Zähler ist 1 ~
	Zähler ist 2 ~
	Zähler ist 3 ~
	Zähler ist 4 ~

In der ersten Zeile verknüpft der Befehl »:let« einen Wert mit einer
Variablen.  Die generische Form ist: >

	:let {variable} = {ausdruck}

In diesem Falle ist der Variablenname »i« und der Ausdruck ist ein einfacher
Wert, die Zahl eins.
    Der Befehl »:while« beginnt eine Schleife.  Die generische Form ist: >

	:while {bedingung}
	:  {anweisungen}
	:endwhile

Die Anweisungen bis zum entsprechenden »:endwhile« werden so lange ausgeführt,
wie die Bedingung wahr ist.  Die hier benutzte Bedingung ist der Ausdruck
»i < 5«.  Dies ist wahr, wenn die Variable i kleiner als fünf ist.
	Anmerkung:
	Falls Sie versehentlich eine While-Schleife schreiben, die nicht
	abbricht, können Sie sie durch Drücken von CTRL-C (CTRL-Pause unter
	MS-Windows) unterbrechen.

Der Befehl »:echo« gibt seine Argumente aus.  In diesem Falle die
Zeichenkette »Zähler ist« und den Wert der Variablen i. Weil i eins ist,
wird folgendes ausgegeben:

	Zähler ist 1 ~

Dann kommt der Befehl »:let i += 1«.  Dies macht dasselbe wie »:let i = i
+1«.  Dies addiert eins zu der Variablen i und verknüpft den neuen Wert
mit derselben Variablen.

Das Beispiel wurde aufgeführt, um die Befehle zu erläutern, aber wenn Sie
wirklich solch eine Schleife bauen wollen, kann dies viel kompakter
geschrieben werden: >

	:for i in range(1, 4)
	:  echo "Zähler ist" i
	:endfor

Wir erklären |:for| und |range()| zunächst nicht.  Folgen Sie den
Verweisen, wenn Sie ungeduldig sind.


DREI ARTEN VON ZAHLEN

Zahlen können dezimal, hexadezimal oder oktal sein.  Eine hexadezimale Zahl
beginnt mir »0x« oder »0X«.  »0x1f« ist zum Beispiel dezimal 31.  Eine oktale
Zahl beginnt mit einer Null.  »017« ist dezimal 15.  Achtung: setzen Sie keine
Null vor eine dezimale Zahl, sie wird dann als oktale Zahl interprätiert!
   Der Befehl »:echo« gibt immer dezimale Zahlen aus.  Beispiel: >

	:echo 0x7f 036
<	127 30 ~

Eine Zahl wird mit einem Minus-Zeichen negativ gemacht.  Dies funktioniert
auch für hexadezimale und oktale Zahlen.  Das Minus-Zeichen wird auch für die
Substraktion verwandt.  Vergleichen Sie dies mit dem vorigen Beispiel: >

	:echo 0x7f -036
<	97 ~

Whitespace in einem Ausdruck wird ignoriert.  Dennoch empfiehlt es sich, ihn
zu benutzen, um Elemente zu trennen, um den Ausdruck leichter lesbar zu
machen.  Um zum Beispiel oben die Verwechslung mit einer negativen Zahl zu
vermeiden, setzen Sie ein Leerzeichen zwischen das Minus-Zeichen und die
darauf folgende Zahl: >

	:echo 0x7f - 036

==============================================================================
*41.2*	Variablen

Ein Variablenname besteht aus ASCII-Buchstaben, Ziffern und dem
Unterstrich.  Er kann nicht mit einer Ziffer beginnen.  Gültige
Variablennamen sind:

	counter
	_aap3
	very_long_variable_name_with_underscores
	FuncLength
	LENGTH

Ungültige Namen sind »foo+bar« und »6var«.
   Diese Variablen sind global.  Um eine Liste aktuell definierter Variablen
zu sehen, benutzen Sie diesen Befehl: >

	:let

Sie können überall globale Variablen verwenden.  Dies bedeutet auch, dass,
wenn eine Variable »zaehler« in einer Skript-Datei benutzt wird, sie auch
in einer andereren Datei benutzt werden könnte.  Dies führt bestenfalls zu
Verwirrung, schlimmstenfalls zu wirklichen Problemen.  Um dies zu vermeiden,
können Sie eine Variable lokal zu einem Skript verwenden, indem Sie »s:«
voranstellen.  Ein Skript enthält zum Beispiel diesen Code: >

	:let s:count = 1
	:while s:count < 5
	:  source other.vim
	:  let s:count += 1
	:endwhile

Weil »s:count« lokal zu diesem Skript ist, können Sie sicher sein, dass
das Einlesen von »other.vim« diese Variable nicht verändert.  Falls
»other.vim« ebenfalls eine Variable »s:count« enthält, ist dies eine
andere Einheit, lokal zu diesem Skript.  Mehr über Variablen, die lokal zu
einem Skript sind, unter: |script-variable|

Es gibt noch mehr Arten von Variablen, siehe |internal-variables|.  Die am
häufigsten gebrauchten sind:

	b:name		Variable lokal zu einem Puffer
	w:name		Variable lokal zu einem Fenster
	g:name		globale Variable (auch in einer Funktion)
	v:name		von Vim vordefinierte Variable


VARIABLEN LöSCHEN

Variablen belegen Speicher und erscheinen in der Ausgabe des Befehls
»:let«. Um eine Variable zu löschen, benutzen Sie den Befehl »:unlet«.
Beispiel: >

	:unlet s:count

Dies löscht die skript-lokale Variable »s:count« um den Speicher
freizugeben, den sie belegt.  Wenn Sie nicht sicher sind, ob die Variable
existiert und Sie keine Fehlermeldung wollen, wenn sie es nicht tut, hängen
Sie »!« an: >

	:unlet! s:count

Wenn ein Skript terminiert, werden die in ihm benutzten lokalen Variablen
nicht automatisch freigegeben.  Das nächste Mal, wenn das Skript
ausgeführt wird, kann es immernoch den alten Wert benutzen.  Beispiel: >

	:if !exists("s:aufruf_zaehler")
	:  let s:aufruf_zaehler = 0
	:endif
	:let s:aufruf_zaehler = s:aufruf_zaehler + 1
	:echo s:aufruf_zaehler "Male aufgerufen"

Die Funktion »exists()« prüft, ob eine Variable bereits definiert wurde.
Ihr Argument ist der Name der Variablen, die man überprüfen will.  Nicht
die Variable selbst!  Falls Sie dies tun würden: >

	:if !exists(s:aufruf_zaehler)

Dann wird der Wert von s:aufruf_zaehler als der Name der Variablen, die
exists() überprüft, genommen.  Das ist nicht, was Sie wollen.
   Das Ausrufezeichen ! negiert einen Wert.  Wenn der Wert wahr war, wird er
falsch.  Wenn er falsch war, wird er wahr.  Sie können es als »nicht« lesen.
Also kann »if !exists()« als »if not exists()« gelesen werden.
   Was Vim als wahr betrachtet, ist alles, was nicht Null ist.  Null ist
falsch.
	Anmerkung:
	Vim konvertiert eine Zeichenkette automatisch zu einer Zahl, wenn er
	nach einer Zahl sucht.  Bei einer Zeichenkette, die nicht mit einer
	Ziffer beginnt, ist die resultierende Zahl Null.  Also geben Sie
	hierauf acht: >
		:if "true"
>	Das »true« wird als Null interprätiert, also als falsch!


ZEICHENKETTENVARIABLEN UND -KONSTANTEN

So weit wurden nur Zahlen für den Variablenwert benutzt.  Zeichenketten können
auch benutzt werden.  Zahlen und Zeichenketten sind die Grundtypen von
Variablen, die Vim unterstützt.  Der Typ ist dynamisch, er wird jedes Mal
gesetzt, wenn der Variablen mit »:let« ein Wert zugewiesen wird.  Mehr zu
Typen in |41.8|.
   Um einer Variablen einen Zeichenkettenwert zuzuweisen, müssen Sie eine
Zeichenkettenkonstante benutzen.  Davon gibt es zwei Typen.  Zuerst die
Zeichenkette in doppelten Zitatzeichen: >

	:let name = "peter"
	:echo name
<	peter ~

Falls Sie ein doppeltes Zitatzeichen in die Zeichenkette einbeziehen wollen,
stellen Sie ihm einen Rückwärtsschrägstrich voran: >

	:let name = "\"peter\""
	:echo name
<	"peter" ~

Um den Rückwärtsschrägstrich zu vermeiden, können Sie eine Zeichenkette
in einfachen Zitatzeichen verwenden: >

	:let name = '"peter"'
	:echo name
<	"peter" ~

In einer Zeichenkette mit einfachen Zitatzeichen sind alle Zeichen wie sie
sind.  Nur das einzelne Zitatzeichen selbst ist besonders: Sie müssen zwei
verwenden, um eins zu bekommen.  Ein Rückwärtsschrägstrich wird wörtlich
genommen, also können Sie ihn nicht benutzen, um die Bedeutung des Zeichens
danach zu verändern.
   In Zeichenketten mit doppelten Zitatzeichen ist es möglich, besondere
Zeichen zu verwenden.  Hier sind ein Paar nützliche:

	\t		<Tab>
	\n		<NL>, Zeilenumbruch
	\r		<CR>, <Enter>
	\e		<Esc>		\b		<BS>, Backspace
	\"		"
	\\		\. Rückwärtsschrägstrich
	\<Esc>		<Esc>
	\<C-W>		CTRL-W

Die letzten zwei sind nur Beispiele.  Die Form »\<name>« kann benutzt werden,
um die Sondertaste »name« einzubeziehen.
   Siehe |expr-quote| für die volle Liste besonderer Elemente in einer
Zeichenkette.

==============================================================================
*41.3*	Ausdrücke

Vim hat eine reichhaltige, aber dennoch einfache Weise, um Ausdrücke zu
behandeln.  Sie können die Definition hier lesen: |expression-syntax|. Hier
werden wir die gebräuchlichsten zeigen.
   Die oben erwähnten Zahlen, Zeichenketten und Variablen sind selbst
Ausdrücke.  Also können Sie überall, wo ein Ausdruck erwartet wird, eine Zahl,
Zeichenkette oder Variable verwenden.  Andere Grundelemente in einem Ausdruck
sind:

	$NAME		Umgebungsvariable
	&name		Option
	@r		Register

Beispiele: >

	:echo "Der Wert von 'tabstop' ist" &ts
	:echo "Ihr Heimverzeichnis ist" $HOME
	:if @a > 5

Die Form &name kann benutzt werden, um den Wert einer Option zwischen zu
speichern, sie auf einen neuen Wert zu setzen, etwas zu tun und den alten
Wert zu restaurieren.  Beispiel: >

	:let save_ic = &ic
	:set noic
	:/Der Beginn/,$delete
	:let &ic = save_ic

Dies stellt sicher, dass das Muster »Der Beginn« mit deaktivierter Option
'ignorecase' benutzt wird.  Jedoch behält es den Wert, den der Benutzer
gesetzt hat.  (Eine andere Möglichkeit, dies zu tun, wäre dem Suchmuster
»\C« hinzuzufügen, siehe |/\C|.)


MATHEMATIK

Es wird interessanter, wenn wir diese Grundelemente kombinieren.  Lassen Sie
uns mit Mathematik auf Zahlen beginnen

	a + b		Addition
	a - b		Subtraktion
	a * b		Multiplikation
	a / b		Division
	a % b		Modulo

Die gewöhnliche Präzedenz wird benutzt.  Beispiel: >

	:echo 10 + 5 * 2
<	20 ~

Gruppierung mit Klammern.  Keine Überraschungen hier.  Beispiel: >

	:echo (10 + 5) * 2
<	30 ~

Zeichenketten können mit ».« verkettet werden.  Beispiel: >

	:echo "foo" . "bar"
<	foobar ~

Wenn der Befehl »:echo« mehrere Argumente erhält, trennt er sie mit einem
Leerzeichen.  In diesem Beispiel ist das Argument ein einzelner Ausdruck,
also wird kein Leerzeichen eingefügt.

Aus der Sprache C entliehen ist der konditionale Ausdruck:

	a ? b : c

Falls »a« wahr ergibt, wird »b« verwandt, ansonsten wird »c« benutzt.
Beispiel: >

	:let i = 4
	:echo i > 5 ? "i is big" : "i is small"
<	i is small ~

Die drei Teile des Konstrukts werden immer zuerst berechnet, also könnten
Sie als als das Folgende funktionieren sehen:

	(a) ? (b) : (c)

==============================================================================
*41.4*	Bedingungen

Der Befehl »:if« führt die folgenden Anweisungen aus, bis zum
übereinstimmenden »:endif«, nur wenn eine Bedingung erfüllt ist.  Die
generische Form ist:

	:if {bedingung}
	   {anweisungen}
	:endif

Nur wenn der Ausdruck {bedingung} wahr (nicht-null) ergibt, werden die
{anweisungen} ausgeführt.  Dies müssen immer noch gültige Befehle sein.  Falls
sie Müll enthalten, ist es Vim nicht möglich, das »:endif« zu finden.
   Sie können auch »:else« verwenden.  Die generische Form hierfür ist:

	:if {bedingung}
	   {anweisungen}
	:else
	   {anweisungen}
	:endif

Der zweite Block {anweisungen} wird nur ausgeführt, wenn der erste nicht wird.
   Schließlich gibt es »:elseif«:

	:if {bedingung}
	   {anweisungen}
	:elseif {bedingung}
	   {anweisungen}
	:endif

Dies funktioniert genauso, wie »:else« und dann »if« zu verwenden, aber ohne
ein extra »:endif« zu benutzen.
   Ein nützliches Beispiel für Ihre vimrc ist, die Option 'term' zu prüfen,
und abhängig von ihrem Wert etwas zu tun: >

	:if &term == "xterm"
	:  " Mache etwas für xterm
	:elseif &term == "vt100"
	:  " Mache etwas für ein VT100-Terminal
	:else
	:  " Mache etwas für andere Terminals
	:endif


LOGISCHE OPERATIONEN

Wir haben bereits einige in den Beispielen benutzt.  Dies sind die am
häufigsten verwandten:

	a == b		gleich
	a != b		ungleich
	a >  b		größer als
	a >= b		größer als oder gleich
	a <  b		kleiner als
	a <= b		kleiner als oder gleich

Das Ergebnis ist eins, falls die Bedingung erfüllt ist, sonst null.  Ein
Beispiel: >

	:if v:version >= 700
	:  echo "Gratulation"
	:else
	:  echo "Sie benutzen eine alte Version.  Aktualisieren Sie!"
	:endif

Hier ist »v:version« eine von Vim definierte Variable, die den Wert der
Vim-Version hat.  600 ist für Version 6.0.  Version 6.1 hat den Wert 601.
Dies ist sehr nützlich beim Schreiben eines Skript, das mit verschiedenen
Versionen von Vim funktionieren soll.  |v:version|

Die logischen Operatoren funktionieren sowohl für Zahlen wie auch für
Zeichenketten.  Beim Vergleich zweier Zeichenketten wird der mathematische
Unterschied benutzt.  Dies vergleicht Byte-Werte, was für manche Sprachen
eventuell nicht richtig ist.
   Beim Vergleich einer Zeichenkette mit einer Zahl wird die Zeichenkette
zuerst in eine Zahl verwandelt.  Dies ist ein wenig verzwickt, wenn eine
Zeichenkette nicht wie eine Zahl aussieht, wird die Zahl Null verwandt.
Beispiel: >

	;if 0 == "eins"
	:  echo "ja"
	:endif

Dies gibt »ja« aus, weil »eins« nicht wie eine Zahl aussieht, es also
zur Zahl Null konvertiert wird.

Für Zeichenketten gibt es zwei weitere Elemente:

	a =~ b		stimmt mit überein
	a !~ b		stimmt nicht mit überein

Das linke Element »a« wird als Zeichenkette verwandt.  Das rechte Element
»b« wird als Muster benutzt, wie beim Suchen.  Beispiel: >

	:if str =~ " "
	:  echo "str enthält ein Leerzeichen"
	:endif
	:if str !~ '\.$'
	:  echo "str endet nicht mit einem Punkt"
	:endif

Beachten Sie den Gebrauch der einfach zitierten Zeichenkette.  Dies ist
nützlich, weil Rückwärtsschrägstriche in doppelt zitierten Zeichenketten
verdoppelt werden müssten, und Muster dazu neigen, viele
Rückwärtsschrägstriche zu enthalten.

Die Option 'ignorecase' wird beim Vergleich von Zeichenketten benutzt.  Wenn
Sie dies nicht wollen, hängen Sie »#« an, für Übereinstimmung von
Groß-/Kleinschreibung, und »?«, um dies zu ignorieren.  Also vergleicht
»==?« zwei Zeichenketten auf Gleichheit, während Groß-/Kleinschreibung
ignoriert wird.  Und »!~#« prüft, ob ein Muster nicht passt, auch
Groß-/Kleinschreibung überprüfend.  Für die volle Tabelle siehe
|expr-==|.


MEHR ÜBER SCHLEIFEN

Der Befehl »:while« wurde bereits erwähnt.  Zwei weitere Anweisungen
können zwischen dem »:while« und dem »:endwhile« benutzt werden:

	:continue		Springe zurück zum Beginn der While-Schleife;
				die Schleife wird fortgesetzt.
	:break			Springe vorwärts zum »:endwhile«; die Schleife
				wird abgebrochen.

Beispiel: >

	:while zaehler < 40
	:  call tue_etwas()
	:  if flag_ueberspringen
	:    continue
	:  endif
	:  if flag_beendet
	:    break
	:  endif
	:  sleep 50m
	:endwhile

Der Befehl »:sleep« lässt Vim ein Nickerchen machen.  »50m« gibt
fünzig Millisekunden an.  Ein weiteres Beispiel ist »:sleep 4«, was für
vier Sekunden schläft.

Sogar noch mehr Schleifen können mit dem Befehl »:for« gemacht werden,
siehe unten in |41.8|.

==============================================================================
*41.5*	Einen Ausdruck ausführen

So weit wurden die Befehle in dem Skript von Vim direkt ausgeführt.  Der
Befehl »:execute« erlaubt das Ausführen des Ergebnisses eines Ausdrucks.  Dies
ist eine sehr mächtige Möglichkeit, Befehle aufzubauen und sie ausführen zu
lassen.
   Ein Beispiel ist ein Tag anzuspringen, das in einer Variablen enthalten
ist: >

	:execute "tag " . tag_name

Der ».« wird verwandt, um die Zeichenkette »tag « mit dem Wert der
Variablen »tag_name« zu verketten.  Angenommen, »tag_name« hat den Wert
»get_cmd«, dann ist der ausgeführte Befehl: >

	:tag get_cmd

Der Befehl »:execute« kann nur Doppelpunkt-Befehle ausführen.  Der Befehl
»:normal« führt Befehl des Normalmodus aus.  Jedoch ist sein Argument
kein Ausdruck, sondern die wörtlichen Befehlszeichen.  Beispiel: >

	:normal gg=G

Dies springt in die erste Zeile und formatiert alle Zeilen mit dem Operator
»=«.
   Damit »:normal« mit einem Ausdruck funktioniert, kombinieren Sie
»:execute« mit ihm.  Beispiel: >

	:execute "normal " . normal_befehle

Die Variable »normal_befehle« muss die Normal-Modus-Befehle enthalten.
   Stellen Sie sicher, dass das Argument für »:normal« ein vollständiger
Befehl ist.  Ansonsten läuft Vim in das Ende des Arguments und führt den
Befehl nicht aus.  Falls Sie zum Beispiel den Einfüge-Modus starten, müssen
Sie auch den Einfüge-Modus verlassen.  Dies funktioniert: >

	:execute "normal INeuer Text \<Esc>"

Dies fügt »Neuer Text « in der aktuellen Zeile ein.  Beachten Sie den
Gebrauch der Sondersequenz »\<Esc>«.  Dies vermeidet, dass sie ein
wirkliches <Esc>-Zeichen in Ihr Skript einfügen müssen.

Falls Sie eine Zeichenkette nicht ausführen, sondern auswerten möchten, um
ihren Ausdruckswert zu bekommen, können Sie die Funktion eval() benutzen: >

	:let optname = "path"
	:let optval = eval('&' . optname)

Ein »&«-Zeichen wird »path« vorangestellt, also ist das Argument für eval()
»&path«.  Das Ergebnis ist dann der Wert der Option 'path'.
   Dasselbe kann mit dem folgenden gemacht werden: >
	:exe 'let optval = &' . optname

==============================================================================
*41.6*	Funktionen benutzen

Vim definiert viele Funktionen und bietet so einen großen Betrag an
Funktionalität.  Einige wenige Beispiele werden in diesem Abschnitt
gegeben.  Sie können die ganze Liste hier finden: |functions|.

Eine Funktion wird mit dem Befehl »:call« aufgerufen.  Die Parameter
werden in Klammern übergeben, getrennt durch Kommata.  Beispiel: >

	:call search("Date: ", "W")

Dies ruft die Funktion search() auf, mit den Argumenten »Date: « und
»W«.  Die Funktion search() benutzt ihr erstes Argument als Suchmuster und
das zweite als Flags.  Das Kennzeichen »W« bedeutet, dass die Suche am
Ende der Datei nicht an ihrem Beginn fortgesetzt werden soll (wrap around).

Eine Funktion kann in einem Ausdruck aufgerufen werden.  Beispiel: >

	:let zeile = getline(".")
	:let ersetzt = substitute(zeile, '\a', "*", "g")
	:call setline(".", ersetzt)

Die Funktion getline() holt eine Zeile aus dem aktuellen Puffer.  Ihr Argument
ist eine Spezifikation der Zeilennummer.  In diesem Falle wird ».« benutzt,
was die Zeile meint, wo sich der Cursor befindet.
   Die Funktion substitute() tut etwas ähnliches wie der Befehl »:substitute«.
Das erste Argument ist die Zeichenkette, auf der die Ersetzung stattfinden
soll.  Das zweite Argument ist das Muster, das dritte die
Ersetzungszeichenkette.  Schließlich sind die letzten Argumente die Flags.
   Die Funktion setline() setzt die Zeile, die durch das erste Argument
spezifiziert wird, auf eine neue Zeichenkette, das zweite Argument.  In diesem
Beispiel wird die Zeile unter dem Cursor ersetzt durch das Ergebnis von
substitute().  Also ist der Effekt der drei Anweisungen gleich: >

	:substitute/\a/*/g

Die Funktionen benutzen wird interessanter, wenn Sie mehr Arbeit vor und
nach dem Aufruf von substitute() erledigen.


FUNKTIONEN						*function-list*

Es gibt viele Funktionen.  Wir werden Sie hier erwähnen, gruppiert nach
ihrem Verwendungszweck.  Sie können hier eine alphabetische Liste finden:
|functions|.  Benutzen Sie CTRL-] auf dem Funktionsnamen, um zu einer
detailierten Hilfe zu ihr zu springen.

Zeichenketten-Manipulation:					*string-functions*
	nr2char()		gibt ein Zeichen nach seinem ASCII-Wert
	char2nr()		gibt den ASCII-Wert eines Zeichens
	str2nr()		konvertiert eine Zeichenkette in eine Zahl
	str2float()		konvertiert eine Zeichenkette in eine
				Gleitpunktzahl
	printf()		formatiert eine Zeichenkette nach %-Elementen
	escape()		schützt Zeichen in einer Zeichenkette mit
				einem »\«
	shellescape()		schützt eine Zeichenkette zum Gebrauch mit
				einem Shell-Befehl
	fnameescape()		schützt einen Dateinamen zum Gebrauch mit
				einem Vim-Befehl
	tr()			übersetzt Zeichen von einer Menge in eine
				andere
	strtrans()		übersetzt eine Zeichenkette, um sie druckbar
				zu machen
	tolower()		konvertiert eine Zeichenkette in
				Kleinbuchstaben
	toupper()		konvertiert eine Zeichenkette in
				Großbuchstaben
	match()			Position, wo ein Muster in einer Zeichenkette
				übereinstimmt
	matchend()		Postion, wo eine Musterübereinstimmung in
				einer Zeichenkette endet
	matchstr()		Übereinstimmung eines Musters in einer
				Zeichenkette
	matchlist()		wie matchstr(), gibt auch
				Unterübereinstimmungen zurück
	stridx()		erster Index einer kurzen in einer langen
				Zeichenkette
	strridx()		letzter Index einer kurzen in einer langen
				Zeichenkette
	strlen()		Länge einer Zeichenkette
	substitute()		ersetze eine Musterübereinstimmung durch eine
				Zeichenkette
	submatch		liefert eine bestimmte Übereinstimmung in
				einem »:substitute«
	strpart()		liefert Teil einer Zeichenkette
	expand()		expandiert besondere Schlüsselwörter
	iconv()			konvertiert Text von einer Kodierung
				in eine andere
	byteidx()		Byte-Index eines Zeichens in einer Zeichenkette
	repeat()		wiederholt eine Zeichenkette mehrere Male
	eval()			wertet einen Zeichenkettenausdruck aus

Listen-Manipulation:					*list-functions*
	get()			liefert ein Element ohne Fehler für falschen
				Index
	len()			Anzahl Elemente in einer Liste
	empty()			prüft, ob eine Liste leer ist
	insert()		fügt ein Element irgendwo in einer Liste ein
	add()			hängt ein Element an eine Liste an
	extend()		hängt eine Liste an eine Liste an
	remove()		entfernt ein oder mehrere Elemente
				aus einer Liste
	copy()			macht eine oberflächliche Kopie einer Liste
	deepcopy()		macht eine volle Kopie einer Liste
	filter()		entfernt ausgewählte Elemente einer Liste
	map()			ändert jedes Listenelement
	sort()			sortiert eine Liste
	reverse()		kehrt die Reihenfolge einer Liste um
	split()			spaltet eine Zeichenkette in eine Liste
	join()			fügt Listenelemente zu einer Zeichenkette
				zusammen
	range()			gibt eine Liste mit einer Folge von Zahlen
				zurück
	string()		Zeichenkettenrepräsentation einer Liste
	call()			ruft eine Funktion auf mit Liste als Argumente
	index()			Index eines Werts in einer Liste
	max()			maximaler Wert in einer Liste
	min()			minimaler Wert in einer Liste
	count()			zählt Anzahl, wie oft ein Wert in einer Liste
				erscheint
	repeat()		wiederholt eine Liste mehrere Male

Wörterbuch-Manipulation:				*dict-functions*
	get()			liefert einen Eintrag ohne einen Fehler
				für einen falschen Schlüssel
	len()			Anzahl von Einträgen in einem Wörterbuch
	has_key()		prüft, ob ein Schlüssel in einem Wörterbuch
				erscheint
	empty()			prüft, ob ein Wörterbuch leer ist
	remove()		entfernt einen Eintrag aus einem Wörterbuch
	extend()		kopiert Einträge von einem Wörterbuch
				in ein anderes
	filter()		entfernt ausgewählte Einträge
				aus einem Wörterbuch
	map()			ändert jeden Wörterbuch-Eintrag
	keys()			liefert Liste von Wörterbuch-Schlüsseln
	values()		liefert Liste von Wörterbuch-Werten
	items()			liefert Liste von
				Wörterbuch-Schlüssel-Wert-Paaren
	copy()			macht eine oberflächliche Kopie
				eines Wörterbuchs
	deepcopy		macht eine volle Kopie eines Wörterbuchs
	string()		Zeichenkettenrepräsentation eines Wörterbuchs
	max()			maximaler Wert in einem Wörterbuch
	min()			minimaler Wert in einem Wörterbuch
	count()			Anzahl, wie oft ein Wert erscheint

Gleitpunkt-Berechnung:				*float-functions*
	float2nr()		konvertiert Gleitpunktzahl zu Zahl
	abs()			Absolut-Wert (funktioniert auch für Zahl)
	round()			rundet
	ceil()			rundet auf
	floor()			rundet ab
	trunc()			entfernt Wert nach Dezimalpunkt
	log10()			Logarithmus zur Basis 10
	pow()			Wert von x hoch y
	sqrt()			Quadratwurzel
	sin()			Sinus
	cos()			Cosinus
	atan()			Arcustangens

Variablen:
	type()			Typ einer Variablen
	islocked()		prüft, ob eine Variable gelockt ist
	function()		liefert eine Funktionsreferenz für einen
				Funktionsnamen
	getbufvar()		liefert einen Variablenwert aus einem
				bestimmten Puffer
	setbufvar()		setzt eine Variable in einem bestimmten Puffer
	getwinvar()		liefert eine Variable aus einem bestimmten
				Fenster
	gettabvar()		liefert eine Variable für eine bestimmte Reiterseite
	gettabwinvar()		liefert eine Variable für bestimmtes Fenster
				und Reiterseite
	setwinvar()		setzt eine Variable in einem bestimmten
				Fenster
	settabvar()		setzt eine Variable für eine bestimmte Reiterseite
	settabwinvar()		setzt eine Variable für bestimmtes Fenster und
				Reiterseite
	garbagecollect()	gibt möglicherweise Speicher frei

Cursor- und Markierungs-Position:		*cursor-functions* *mark-functions*
	col()			Spaltennummer von Cursor oder einer Markierung
	virtcol()		Bildschirmspalte von Cursor oder einer
				Markierung
	line()			Zeilennummer von Cursor oder einer Markierung
	wincol()		Fensterspaltennummer des Cursors
	winline()		Fensterzeilennummer des Cursors
	cursor()		positioniert den Cursor auf einer Zeile/Spalte
	getpos()		liefert Position von Cursor, Markierung usw.
	setpos()		setzt Position von Cursor, Markierung usw.
	byte2line()		liefert Zeilennummer bei einer bestimmten
				Byte-Anzahl
	line2byte()		Byte-Anzahl bei einer bestimmten Zeile
	diff_filler()		liefert die Anzahl von Füllzeilen über einer
				Zeile

Arbeiten mit dem Text im aktuellen Puffer:		*text-functions*
	getline()		liefert eine Zeile oder Liste von Zeilen aus
				dem aktuellen Puffer
	setline()		ersetzt eine Zeile im Puffer
	append()		fügt eine Zeile oder Liste von Zeilen im
				Puffer an
	indent()		Einrückung einer bestimmten Zeile
	cindent()		rückt eine Zeile nach Einrückung für C ein
	lispindent()		rückt eine Zeile nach Einrückung für Lisp ein
	nextnonblank()		findet nächste nicht-leere Zeile
	prevnonblank()		findet vorige nicht-leere Zeile
	search()		findet eine Übereinstimmung für ein Muster
	searchpos()		findet eine Übereinstimmung für ein Muster
	searchpair()		findet das andere Ende eines Start/Skip/End
	searchpairpos()		findet das andere Ende eines Start/Skip/End
	searchdecl()		sucht nach der Deklaration eines Namens

					*system-functions* *file-functions*
Systemfunktionen und Manipulation von Dateien:
	glob()			expandiere Wildcards
	globpath()		expandiere Wildcards in einer Reihe von
				Verzeichnissen
	findfile()		findet eine Datei in einer Liste von
				Verzeichnissen
	finddir()		findet ein Verzeichnis in einer Liste von
				Verzeichnissen
	resolve()		findet heraus, wohin ein Shortcut zeigt
	fnamemodify()		modifiziert einen Dateinamen
	pathshorten()		verkürzt Verzeichnisnamen in einem Pfad
	simplify()		vereinfacht einen Pfad, ohne seine Bedeutung
				zu verändern
	executable()		prüft, ob ein ausführbares Programm existiert
	filereadable()		prüft, ob eine Datei gelesen werden kann
	filewritable()		prüft, ob in eine Datei geschrieben werden kann
	getfperm()		liefert die Zugriffsrechte einer Datei
	getftype()		liefert die Art einer Datei
	isdirectory()		prüft, ob ein Verzeichnis existiert
	getfsize()		liefert die Größe einer Datei
	getcwd()		liefert das aktuelle Arbeitsverzeichnis
	haslocaldir()		prüft, ob das aktuelle Fenster |:lcd| benutzt
				hat
	tempname()		liefert den Namen einer temporären Datei
	mkdir()			erzeugt ein neues Verzeichnis
	delete()		löscht eine Datei
	rename()		benennt eine Datei um
	system()		liefert das Ergebnis eines Shell-Befehls
	hostname()		Rechnername
	readfile()		lese eine Datei in eine Liste von Zeilen
	writefile()		schreibe eine Liste von Zeilen in eine Datei

Datum und Zeit:				*date-functions* *time-functions*
	getftime()		liefert Zeit der letzten Modifikation
				einer Datei
	localtime()		liefert aktuelle Zeit in Sekunden
	strftime()		konvertiert Zeit in eine Zeichenkette
	reltime()		liefert die aktuelle oder vergangene Zeit
				akkurat
	reltimestr()		konvertiert Ergebnis von reltime() in eine
				Zeichenkette

			*buffer-functions* *window-functions* *arg-functions*
Puffer, Fenster und die Argumentenliste:
	argc()			Anzahl von Einträgen in der Argumentenliste
	argidx()		aktuelle Position in der Argumentenliste
	argv()			liefert einen Eintrag aus der Argumentenliste
	bufexists()		prüft, ob ein Puffer existiert
	buflisted()		prüft, ob ein Puffer existiert und gelistet ist
	bufloaded()		prüft, ob ein Puffer existiert und geladen ist
	bufname()		liefert den Namen eines bestimmten Puffers
	bufnr()			liefert die Puffernummer eines bestimmten
				Puffers
	tabpagebuflist()	gibt eine Liste der Puffer in einer
				Reiterseite zurück
	tabpagenr()		liefert die Nummer einer Reiterseite
	tabpagewinnr()		wie winnr() für eine bestimmte Reiterseite
	winnr()			liefert die Fensternummer für das aktuelle
				Fenster
	bufwinnr()		liefert die Fensternummer eines bestimmten
				Puffers
	winbufnr()		liefert die Puffernummer eines bestimmten
				Fensters
	getbufline()		liefert eine Liste von Zeilen aus dem
				bestimmten Puffer

Befehlszeile:					*command-line-functions*
	getcmdline()		liefert die aktuelle Befehlszeile
	getcmdpos()		liefert Position des Cursors in der Befehlszeile
	setcmdpos()		setzt Position des Cursors in der Befehlszeile
	getcmdtype()		gibt den Typ der aktuellen Befehlszeile zurück

Quickfix und Lokationslisten:			*quickfix-functions*
	getqflist()		Liste von Quickfix-Fehlern
	setqflist()		modifiziere eine Quickfix-Liste
	getloclist()		Liste von Lokationslisten-Elementen
	setloclist()		modifiziere eine Lokationsliste

Vervollständigung im Einfügemodus:				*completion-functions*
	complete()		setzt gefundene Übereinstimmungen
	complete_add()		fügt zu gefundenen Übereinstimmungen hinzu
	complete_check()	prüft, ob Vervollständigung abgebrochen werden
				sollte
	pumvisible()		prüft, ob das Aufklapp-Menü angezeigt wird

Falten:					*folding-functions*
	foldclosed()		prüft auf eine geschlossene Faltung in einer
				bestimmten Zeile
	foldclosedend()		wie foldclosed(), aber gibt die letzte Zeile
				zurück
	foldlevel()		prüft auf die Faltungsebene in einer
				bestimmten Zeile
	foldtext()		erzeugt die für eine geschlossene Faltung
				angezeigte Zeile
	foldtextresult()	liefert den für eine geschlossene Faltung
				angezeigten Text

Syntax und Hervorhebung:	  *syntax-functions* *highlighting-functions*
	clearmatches()		löscht alle von |matchadd()| und den |:match|-
				Befehlen definierte Übereinstimmungen
	getmatches()		holt alle von |matchadd()| und den |:match|-
				Befehlen definierten Übereinstimmungen
	hlexists()		prüft, ob eine Hervorhebungsgruppe existiert
	hlID()			liefert ID einer Hervorhebungsgruppe
	synID()			liefert Syntax-ID an einer bestimmten Position
	synIDattr()		liefert ein bestimmtes Attribut einer Syntax-ID
	synIDtrans()		liefert übersetzte Syntax-ID
	diff_hlID()		liefert Hervorhebungs-ID für den Diff-Modus
				an einer Position
	matcharg()		liefert Informationen über Argumente
				von |:match|
	matchdelete()		löscht eine von |matchadd()| oder den |:match|-
				Befehlen definierte Übereinstimmungen
	setmatches()		stellt eine von |getmatches()| gespeicherte
				Liste von Übereinstimmungen wieder her

Rechtschreibkontrolle:				*spell-functions*
	spellbadword()		lokalisiert falsch geschriebenes Wort am
				oder nach dem Cursor
	spellsuggest()		liefert vorgeschlagene Schreibungskorrekturen
				zurück
	soundfold()		liefert die ähnlich klingende Entsprechung
				eines Wortes zurück

Verläufe:					*history-functions*
	histadd()		fügt ein Element einem Verlauf hinzu
	histdel()		löscht ein Element aus einem Verlauf
	histget()		liefert ein Element aus einem Verlauf
	histnr()		liefert den höchsten Index einer Verlaufsliste

Interaktiv:					*interactive-functions*
	browse()		stellt eine Datei-Anfrage zur Verfügung
	browsedir()		stellt eine Verzeichnis-Anfrage zur Verfügung
	confirm()		lässt den Benutzer eine Auswahl machen
	getchar()		holt ein Zeichen vom Benutzer
	getcharmod()		liefert die Modifikatoren für das letzte
				eingegebene Zeichen
	feedkeys()		stellt Zeichen in die Vorauseingabe-Schleife
	input()			holt eine Zeile vom Benutzer
	inputlist()		lässt den Benutzer einen Eintrag aus einer
				Liste auswählen
	inputsecret()		holt eine Zeile vom Benutzer ohne sie
				anzuzeigen
	inputdialog()		holt eine Zeile vom Benutzer in einem Dialog
	inputsave()		speichert und löscht Vorauseingabe
	inputrestore()		stellt die Vorauseingabe wieder her

GUI:						*gui-functions*
	getfontname()		liefert den Namen des aktuell benutzten
				Schriftstils
	getwinposx()		X-Position des GUI-Vim-Fensters
	getwinposy()		Y-Position des GUI-Vim-Fensters

Vim-Server:					*server-functions*
	serverlist()		gibt eine Liste von Server-Namen zurück
	remote_send()		sendet Befehlszeichen an einen Vim-Server
	remote_expr()		wertet einen Ausdruck in einem Vim-Server aus
	server2client()		sendet eine Antwort an einen Client eines
				Vim-Servers
	remote_peek()		prüft, ob es eine Antwort von einem Vim-Server
				gibt
	remote_read()		liest eine Antwort von einem Vim-Server
	foreground()		bewegt das Vim-Fenster in den Vordergrund
	remote_foreground()	bewegt das Fenster des Vim-Servers in den
				Vordergrund

Fenster-Größe und -Position:			*window-size-functions*
	winheight()		liefert die Höhe eines bestimmten Fensters
	winwidth()		liefert die Breite eines bestimmten Fensters
	winrestcmd()		gibt Befehl zurück, um Fenstergrößen
				wiederherzustellen
	winsaveview()		liefert Ansicht des aktuellen Fensters
	winrestview()		stellt gespeicherte Ansicht des aktuellen
				Fensters wieder her

Verschiedenes:					*various-functions*
	mode()			liefert aktuelle Editiermodus
	visualmode()		der letzte benutzte visuelle Modus
	hasmapto()		prüft, ob eine Belegung existiert
	mapcheck()		prüft, ob eine passende Belegung existiert
	maparg()		liefert die rechte Seite einer Belegung
	exists()		prüft, ob eine Variable, Funktion usw.
				existiert
	has()			prüft, ob ein Feature von Vim unterstützt wird
	changenr()		gibt die Nummer der letzten Änderung zurück
	cscope_connection()	prüft, ob eine CScope-Anbindung existiert
	did_filetype()		prüft, ob ein automatischer Befehl eines
				Dateityps benutzt wurde
	eventhandler()		prüft, ob von einem Ereignis-Behandler
				aufgerufen wurde
	getpid()		liefert Prozess-ID von Vim

	libcall()		ruft eine Funktion in einer externen
				Bibliothek auf
	libcallnr()		ebenso, gibt eine Zahl zurück

	getreg()		liefert Inhalt eines Registers
	getregtype()		liefert Typ eines Registers
	setreg()		setzt Inhalt und Typ eines Registers

	taglist()		liefert Liste passender Tags
	tagfiles()		liefert Liste von Tag-Dateien

	mzeval()		wertet |MzScheme|-Ausdruck aus

==============================================================================
*41.7*	Eine Funktion definieren

Vim ermöglicht es Ihnen, eigene Funktionen zu definieren.  Die grundlegende
Funktions-Deklaration beginnt wie folgt: >

	:function {name}({var1}, {var2}, ...)
	:  {body}
	:endfunction
<
	Anmerkung:
	Funktions-Namen müssen mit einem Großbuchstaben beginnen.

Lassen Sie uns eine kurze Funktion definieren, die die kleinere von zwei
Zahlen zurückgibt.  Sie beginnt mit dieser Zeile: >

	:function Min(num1, num2)

Dies sagt Vim, dass die Funktion »Min« heißt und zwei Argumente nimmt, »num1«
und »num2«.
   Als erstes müssen wir überprüfen, welche Zahl kleiner ist:
   >
	:  if a:num1 < a:num2

Das besondere Präfix »a:« sagt Vim, dass die Variable ein
Funktions-Argument ist.  Weisen wir nun der Variablen »smaller« den Wert
der kleineren Zahl zu: >

	:  if a:num1 < a:num2
	:    let smaller = a:num1
	:  else
	:    let smaller = a:num2
	:  endif

Die Variable »smaller« ist eine lokale Variable.  In einer Funktion
benutzte Variablen sind lokal, solange ihnen nicht etwas wie »g:«, »a:«
oder »s:« vorangestellt wird.

	Anmerkung:
	Um innerhalb einer Funktion auf eine globale Variable zuzugreifen,
	müssen Sie ihr »g:« voranstellen.  Also wird innerhalb einer Funktion
	»g:today« für die globale Funktion »today« verwandt, und ein einfaches
	»today« ist eine andere Variable, die zur Funktion lokal ist.

Nun benutzen wir die Anweisung »:return« um die kleinere Zahl an den
Aufrufer zurückzugeben.  Die Funktion endet schließlich: >

	:  return smaller
	:endfunction

Die vollständige Funktions-Definition ist wie folgt: >

	:function Min(num1, num2)
	:  if a:num1 < a:num2
	:    let smaller = a:num1
	:  else
	:    let smaller = a:num2
	:  endif
	:  return smaller
	:endfunction

Für Leute, die kurze Funktionen mögen, leistet dies dasselbe: >

	:function Min(num1, num2)
	:  if a:num1 < a:num2
	:    return a:num1
	:  endif
	:  return a:num2
	:endfunction

Eine benutzerdefinierte Funktion wird genauso aufgerufen, wie eine
eingebaute.  Nur der Name ist verschieden.  Die Funktion Min kann so benutzt
werden: >

	:echo Min(5, 8)

Erst jetzt wird die Funktion ausgeführt, und die Zeilen werden von Vim
interpretiert.  Falls es Fehler gibt, wie das Nutzen einer undefinierten
Variablen oder Funktion, erhalten Sie nun eine Fehlermeldung.  Beim
Definieren der Funktion werden diese Fehler nicht erkannt.

Wenn eine Funktion »:endfunction« erreicht, oder »:return« wird ohne
Argument benutzt, gibt die Funktion Null zurück.

Um eine bereits existierende Funktion erneut zu definieren, benutzen Sie
»:function« mit dem !-Modifikator: >

	:function!  Min(num1, num2, num3)


EINEN BEREICH BENUTZEN

Dem Befehl »:call« kann ein Zeilenbereich gegeben werden.  Dies kann eine von
zwei Bedeutungen haben.  Wenn eine Funktion mit dem Schlüsselwort »range«
definiert wurde, kümmert sie sich selbst um den Zeilenbereich.
  Der Funktion werden die Variablen »a:firstline« und »a:lastline« übergeben.
Diese haben die Zeilennummern des Bereiches, mit dem die Funktion aufgerufen
wurde.  Beispiel: >

	:function Count_words() range
	:  let lnum = a:firstline
	:  let n = 0
	:  while lnum <= a:lastline
	:    let n = n + Wordcount(getline(lnum))
	:    let lnum = lnum + 1
	:  endwhile
	:  echo "found " . n . " words"
	:endfunction

Sie können diese Funktion aufrufen mit: >

	:10,30call Count_words()

Sie wird einmal ausgeführt und gibt die Anzahl an Worten aus.
   Die andere Möglichkeit einen Zeilenbereich zu benutzen ist, eine Funktion
ohne das Schlüsselwort »range« zu definieren.  Die Funktion wird einmal für
jede Zeile in dem Bereich aufgerufen, mit dem Cursor in dieser Zeile.
Beispiel: >

	:function  Number()
	:  echo "line " . line(".") . " contains: " . getline(".")
	:endfunction

Falls Sie diese Funktion aufrufen mit: >

	:10,15call Number()

wird die Funktion sechs Mal aufgerufen.


VARIABLE ANZAHL VON ARGUMENTEN

Vim ermöglicht Ihnen, Funktionen zu definieren, die eine variable Anzahl
von Argumenten haben.  Der folgende Befehl zum Beispiel definiert eine
Funktion, die ein Argument haben muss (start), und die bis zu 20
zusätzliche Argumente haben kann: >

	:function Show(start, ...)

Die Variable »a:1« enthält das erste optionale Argument, »a:2« das zweite und
so weiter.  Die Variable »a:0« enthält die Anzahl von zusätzlichen Argumenten
   Zum Beispiel: >

	:function Show(start, ...)
	:  echohl Title
	:  echo "Show is " . a:start
	:  echohl None
	:  let index = 1
	:  while index <= a:0
	:    echo "  Arg " . index . " is " . a:{index}
	:    let index = index + 1
	:  endwhile
	:  echo ""
	:endfunction

Dies benutzt den Befehl »:echohl« um die für den nächsten
»:echo«-Befehl benutzte Hervorhebung anzugeben.  »:echohl None«
deaktiviert dies.  Der Befehl »:echon« funktioniert wie »:echo«, gibt
aber keinen Zeilenumbruch aus.

Sie können auch die Variable a:000 benutzen.  Dies ist eine Liste aller
optionalen Argumente.  Siehe |a:000|.


FUNKTIONEN AUFLISTEN

Der Befehl »:function« listet die Namen und Argumente aller
benutzerdefinierten Funktionen auf: >

	:function
<	function Show(start, ...) ~
	function GetVimIndent() ~
	function SetSyn(name) ~

Um zu sehen, was eine Funktion tut, benutzen Sie ihren Namen als Argument
für »:function«: >

	:function SetSyn
<	1     if &syntax == '' ~
	2       let &syntax = a:name ~
	3     endif ~
	   endfunction ~


FEHLERSUCHE

Die Zeilennummer ist nützlich, wenn Sie eine Fehlermeldung erhalten, oder bei
der Fehlersuche.  Siehe |debug-scripts| für den Fehlersuche-Modus.
   Sie können auch die Option 'verbose' auf 12 oder höher setzen, um alle
Funktionsaufrufe zu sehen.  Setzen Sie sie auf 15 oder höher um jede
ausgeführte Zeile zu sehen.


EINE FUNKTION LÖSCHEN

Um die Funktion Show() zu löschen: >

	:delfunction Show

Sie erhalten eine Fehlermeldung, wenn die Funktion nicht existiert.


FUNKTIONSREFERENZEN

Manchmal kann es nützlich sein, eine Variable auf die eine oder andere
Funktion zeigen zu lassen.  Dies können Sie mit der Funktion function()
machen.  Sie verwandelt den Namen einer Funktion in eine Referenz: >

	:let result = 0		" or 1
	:function! Right()
	:  return 'Right!'
	:endfunc
	:function! Wrong()
	:  return 'Wrong!'
	:endfunc
	:
	:if result == 1
	:  let Afunc = function('Right')
	:else
	:  let Afunc = function('Wrong')
	:endif
	:echo call(Afunc, [])
<	Wrong! ~

Beachten Sie, dass der Name einer Variablen, die eine Funktionsreferenz
enthält, mit einem Großbuchstaben beginnen muss.  Andernfalls könnte er mit
dem Namen einer eingebauten Funktion verwechselt werden.
   Der Weg, eine Funktion aufzurufen, die eine Variable referenziert, ist es,
die Funktion call() zu benutzen.  Ihr erstes Argument ist die
Funktionsreferenz, das zweite Argument ist eine Liste von Argumenten.

Funktionsreferenzen sind am nützlichsten in Kombination mit einem
Wörterbuch, was im nächsten Abschnitt erklärt wird.

==============================================================================
*41.8*	Listen und Wörterbücher

Bis jetzt haben wir die Basistypen String (Zeichenkette) und Number (Zahl)
benutzt.  Vim unterstützt auch zwei zusammengesetzte Typen: Liste und
Dictionary (Wörterbuch).

Eine Liste ist eine geordnete Folge von Dinge.  Die Dinge können jeglicher
Art von Wert sein, also können Sie eine Liste von Zahlen machen, eine Liste
von Listen, und sogar eine Liste von gemischten Elementen.  Um eine Liste
mit drei Zeichenketten zu erzeugen: >

	:let alist = ['aap', 'mies', 'noot']

Die Listenelemente sind in eckige Klammern eingeschlossen und durch Kommata
getrennt.  Um eine leere Liste zu erzeugen: >

	:let alist = []

Mit der Funktion add() können Sie einer Liste Elemente hinzufügen: >

	:let alist = []
	:call add(alist, 'foo')
	:call add(alist, 'bar')
	:echo alist
<	['foo', 'bar'] ~

Listen-Konkatenation wird mit + erledigt: >

	:echo alist + ['foo', 'bar']
<	['foo', 'bar', 'foo', 'bar'] ~

Oder falls Sie eine Liste direkt erweitern wollen: >

	:let alist = ['one']
	:call extend(alist, ['two', 'three'])
	:echo alist
<	['one', 'two', 'three'] ~

Beachten Sie, dass das Benutzen von add() einen anderen Effekt hat: >

	:let alist = ['one']
	:call add(alist, ['two', 'three'])
	:echo alist
<	['one', ['two', 'three']] ~

Das zweite Argument von add() wird als einzelnes Element hinzugefügt.


FOR-SCHLEIFE

Eines der netten Dinge, die Sie mit einer Liste machen können, ist über
sie zu iterieren: >

	:let alist = ['one', 'two', 'three']
	:for n in alist
	:  echo n
	:endfor
<	one ~
	two ~
	three ~

Dies läuft über jedes Element in der Liste »alist«, wobei es den Wert
der Variablen »n« zuweist.  Die generische Form einer For-Schleife ist: >

	:for {varname} in {listexpression}
	:  {commands}
	:endfor

Um über eine bestimmte Anzahl von Malen zu laufen, brauchen Sie eine Liste
einer bestimmten Länge.  Die Funktion range() erzeugt einem eine: >

	:for a in range(3)
	:  echo a
	:endfor
<	0 ~
	1 ~
	2 ~

Beachten Sie, dass das erste Element der Liste, die range() produziert, Null
ist, also ist das letzte Element eins weniger als die Länge der Liste.
   Sie können auch den Maximalwert angeben, den Inkrement, und sogar rückwärts
laufen: >

	:for a in range(8, 4, -2)
	:  echo a
	:endfor
<	8 ~
	6 ~
	4 ~

Ein nützlicheres Beispiel, das über Zeilen im Puffer läuft: >

	:for line in getline(1, 20)
	:  if line =~ "Date: "
	:    echo matchstr(line, 'Date: \zs.*')
	:  endif
	:endfor

Dies schaut sich Zeilen 1 bis 20 (einschließlich) an, und gibt jedes dort
gefundene Datum aus.


WÖRTERBÜCHER

Ein Wörterbuch speichert Schlüssel-Wert-Paare.  Man kann schnell einen
Wert nachschlagen, wenn man den Schlüssel kennt.  Ein Wörterbuch wird mit
geschwungenen Klammern erzeugt: >

	:let uk2nl = {'one': 'een', 'two': 'twee', 'three': 'drie'}

Nun kann man Wörter nachschlagen, indem man den Schlüssel in eckige
Klammern setzt: >

	:echo uk2nl['two']
<	twee ~

Die generische Form für das Definieren eines Wörterbuchs ist: >

	{<key> : <value>, ...}

Ein leeres Wörterbuch ist eines ohne Schlüssel: >

	{}

Die Möglichkeiten mit Wörterbüchern sind zahlreich.  Ebenso gibt es für
sie verschiedene Funktionen.  Zum Beispiel kann man eine Liste der
Schlüssel beziehen und sie durchlaufen: >

	:for key in keys(uk2nl)
	:  echo key
	:endfor
<	three ~
	one ~
	two ~

Sie werden bemerken, dass die Schlüssel nicht geordnet sind.  Man kann die
Liste sortieren, um eine bestimmte Ordnung zu erhalten: >

	:for key in sort(keys(uk2nl))
	:  echo key
	:endfor
<	one ~
	three ~
	two ~

Aber man kann nie die Reihenfolge zurückbekommen, in der die Elemente
definiert wurden.  Dafür muss man eine Liste benutzen, sie speichert
Elemente in einer geordneten Reihenfolge.


WÖRTERBUCHFUNKTIONEN

Die Elemente in einem Wörterbuch können normalerweise mit einem Index in
eckigen Klammern bezogen werden: >

	:echo uk2nl['one']
<	een ~

Eine Methode, die dasselbe tut, aber ohne so viele Zeichen: >

	:echo uk2nl.one
<	een ~

Dies funktioniert nur für einen Schlüssel, der aus ASCII-Buchstaben,
Ziffern und dem Unterstrich besteht.  Auf diese Weise kann man auch einen
neuen Wert zuweisen: >

	:let uk2nl.four = 'vier'
	:echo uk2nl
<	{'three': 'drie', 'four': 'vier', 'one': 'een', 'two': 'twee'} ~

Und nun zu etwas Besonderem: man kann direkt eine Funktion definieren und
eine Referenz auf diese in dem Wörterbuch speichern: >

	:function uk2nl.translate(line) dict
	:  return join(map(split(a:line), 'get(self, v:val, "???")'))
	:endfunction

Probieren wir dies zunächst einmal aus: >

	:echo uk2nl.translate('three two five one')
<	drie twee ??? een ~

Das erste Besondere, das Sie bemerken, ist das »dict« am Ende der Zeile
mit
»:function«.  Dies markiert die Funktion als aus einem Wörterbuch zu benutzen.
Die Variable »self« referenziert dann dieses Wörterbuch.
   Schauen wir uns den komplizierten Rückgabebefehl nun Stück für Stück an: >

	split(a:line)

Die Funktion split() nimmt eine Zeichenkette, schneidet sie in
leerzeichen-getrennte Wörter, und gibt eine Liste mit diesen Wörtern
zurück.  Im Beispiel also: >

	:echo split('three two five one')
<	['three', 'two', 'five', 'one'] ~

Diese Liste ist das erste Argument an die Funktion map().  Diese geht durch
die Liste, und wertet dabei ihr zweite Argument mit »v:val« auf den Wert
jedes Elements gesetzt.  Dies ist eine Abkürzung zum Benutzen einer
For-Schleife.  Dieser Befehl: >

	:let alist = map(split(a:line), 'get(self, v:val, "???")')

ist gleichbedeutend mit: >

	:let alist = split(a:line)
	:for idx in range(len(alist))
	:  let alist[idx] = get(self, alist[idx], "???")
	:endfor

Die Funktion get() prüft, ob ein Schlüssel in einem Wörterbuch vorhanden
ist.  Falls er es ist, wird der Wert zurückgegeben.  Falls nicht, wird ein
Standardwert zurückgegeben, im Beispiel '???'.  Dies ist eine bequeme Art
Situationen zu behandeln, in denen ein Schlüssel möglicherweise nicht
vorhanden ist und man keine Fehlermeldung möchte.

Die Funktion join() tut das Gegenteil von split(): sie fügt eine Liste von
Wörtern zusammen, wobei sie ein Leerzeichen zwischen sie setzt.
  Diese Kombination von split(), map() und join() ist eine schöne Möglichkeit,
eine Zeile von Wörtern auf eine sehr kompakte Weise zu filtern.


OBJEKT-ORIENTIERTE PROGRAMMIERUNG

Jetzt, da Sie sowohl Werte wie Funktionen in ein Wörterbuch stecken können,
können Sie ein Wörterbuch tatsächlich wie ein Objekt benutzen.
   Oben haben wir ein Wörterbuch benutzt, um Holländisch in Englisch zu
übersetzen.  Wir könnten dasselbe für andere Sprachen tun wollen.  Machen wir
zunächst ein Objekt (aka Wörterbuch), das die Übersetzungsfunktion hat, aber
keine Wörter zum Übersetzen: >

	:let transdict = {}
	:function transdict.translate(line) dict
	:  return join(map(split(a:line), 'get(self.words, v:val, "???")'))
	:endfunction

Es ist ein wenig verschieden von der Funktion oben, indem wir 'self.words'
benutzen, um Wort-Übersetzungen nachzuschlagen.  Aber wir haben keine
self.words.  Also könnte man dies eine abstrakte Klasse nennen.

Nun können wir ein Übersetzungsobjekt für Holländisch instanziieren: >

	:let uk2nl = copy(transdict)
	:let uk2nl.words = {'one': 'een', 'two': 'twee', 'three': 'drie'}
	:echo uk2nl.translate('three one')
<	drie een ~

Und einen Übersetzer für Deutsch: >

	:let uk2de = copy(transdict)
	:let uk2de.words = {'one': 'ein', 'two': 'zwei', 'three': 'drei'}
	:echo uk2de.translate('three one')
<	drei ein ~

Sie sehen, dass die Funktion copy() benutzt wird, um eine Kopie des
Wörterbuchs »transdict« zu machen, und dann diese Kopie verändert wird,
um die Worte aufzunehmen.  Das Original bleibt natürlich dasselbe.

Nun kann man einen Schritt weiter gehen, und den bevorzugten Übersetzer
verwenden: >

	:if $LANG =~ "de"
	:  let trans = uk2de
	:else
	:  let trans = uk2nl
	:endif
	:echo trans.translate('one two three')
<	een twee drie ~

Hier referenziert »trans« eines der beiden Objekte (Wörterbücher).  Es
wird keine Kopie gemacht.  Mehr über Listen- und Wörterbuch-Identität
kann unter |list-identity| und |dict-identity| gefunden werden.

Nun könnte man eine Sprache benutzen, die nicht unterstützt wird.  Man
kann die Funktion translate() überstimmen, nichts zu machen: >

	:let uk2uk = copy(transdict)
	:function! uk2uk.translate(line)
	:  return a:line
	:endfunction
	:echo uk2uk.translate('three one wladiwostok')
<	three one wladiwostok ~

Beachten Sie, dass ein ! benutzt wurde, um die bestehende Funktionsreferenz
zu überschreiben.  Nun benutze »uk2uk«, falls keine erkannte Sprache
gefunden wird: >

	:if $LANG =~ "de"
	:  let trans = uk2de
	:elseif $LANG =~ "nl"
	:  let trans = uk2nl
	:else
	:  let trans = uk2uk
	:endif
	:echo trans.translate('one two three')
<	one two three ~

Zum Weiterlesen siehe |Lists| und |Dictionaries|.

==============================================================================
*41.9*	Ausnahmen

Beginnen wir mit einem Beispiel: >

	:try
	:   read ~/templates/pascal.tmpl
	:catch /E484:/
	:   echo "Sorry, the Pascal template file cannot be found."
	:endtry

Der Befehl »:read« scheitert, falls die Datei nicht existiert.  Statt eine
Fehlermeldung zu generieren, fängt dieser Code den Fehler auf und gibt dem
Benutzer stattdessen eine nette Meldung.

Für die Befehle zwischen »:try« und »:endtry« werden Fehler in
Ausnahmen verwandelt.  Eine Ausnahme ist eine Zeichenkette.  Im Falle eines
Fehlers enthält die Zeichenkette die Fehlernummer.  Und jede Fehlermeldung
hat eine Nummer.  In diesem Fall enthält der Fehler, den wir auffangen,
»E484:«.  Diese Nummer bleibt garantiert dieselbe (der Text kann sich
ändern, z.B. übersetzt werden).

Wenn der Befehl »:read« einen anderen Fehler verursacht, passt das Muster
»E484:« nicht.  Also wird diese Ausnahme nicht aufgefangen und resultiert
in der üblichen Fehlermeldung.

Sie sind vielleicht versucht, dies zu tun: >

	:try
	:   read ~/templates/pascal.tmpl
	:catch
	:   echo "Sorry, the Pascal template file cannot be found."
	:endtry

Dies bedeutet, dass alle Fehler aufgefangen werden.  Dann aber sehen Sie
keine nützlichen Fehler, so wie »E21: Kann keine Änderungen machen,
'modifiable' ist aus«.

Ein weiterer nützlicher Mechanismus ist der Befehl »:finally«: >

	:let tmp = tempname()
	:try
	:   exe ".,$write " . tmp
	:   exe "!filter " . tmp
	:   .,$delete
	:   exe "$read " . tmp
	:finally
	:   call delete(tmp)
	:endtry

Dies filtert die Zeilen vom Cursor bis zum Dateiende durch das Programm
»filter«, das einen Dateinamen als Argument nimmt.  Egal, ob das Filtern
funktioniert, etwas geht zwischen »:try« und »:finally« schief, oder der
Benutzer bricht das Filtern ab, indem er CTRL-C drückt, »call
delete(tmp)« wird jederzeit ausgeführt.  Dies stellt sicher, dass man
nicht die temporäre Datei zurücklässt.

Weiter Informationen über Ausnahme-Behandlung können im Referenzhandbuch
gefunden werden: |exception-handling|.

==============================================================================
*41.10*	Verschiedene Anmerkungen

Hier ist eine Sammlung von Elementen, die auf Vim-Skripte zutreffen.  Sie
werden auch anderswo erwähnt, aber formen eine nette Prüfliste.

Das Zeichen für das Zeilenende hängt vom System ab.  Unix benutzt ein
einzelnes <NL>-Zeichen.  Unter MS-DOS, Windows, OS/2 und so wird <CR><LF>
benutzt.  Dies ist wichtig, wenn Belegungen verwandt werden, die in einem
<CR> enden.  Siehe |:source_crnl|.


WHITE SPACE

Leere Zeilen sind erlaubt und werden ignoriert.

Führende Leerzeichen und Tabulatoren werden immer ignoriert.  Der
Whitespace zwischen Parametern (z.B zwischen dem 'set' und dem 'cpoptions'
im Beispiel unten) wird reduziert auf ein Leerzeichen und spielt die Rolle
eines Trenners, der Whitespace nach dem letzten (sichtbaren) Zeichen kann
situationsabhängig ignoriert werden oder auch nicht, siehe unten.

Für einen »:set«-Befehl, der das Zeichen »=« (gleich) enthält, so wie
in: >

	:set cpoptions    =aABceFst

wird der Whitespace unmittelbar vor dem Zeichen »=« ignoriert.  Aber es
darf kein Whitespace nach dem »=«-Zeichen sein!

Um ein Whitespace-Zeichen im Wert einer Option zu verwenden, muss es durch
einen »\« (Backslash) geschützt werden, wie in dem folgenden Beispiel: >

	:set tags=my\ nice\ file

Dasselbe Bespiel geschrieben als >

	:set tags=my nice file

resultiert in einem Fehler, weil es interpretiert wird als: >

	:set tags=my
	:set nice
	:set file


KOMMENTARE

Das Zeichen " (das doppelte Anführungszeichen) leitet einen Kommentar ein.
Alles nach und einschließlich dieses Zeichens bis zum Zeilenende wird als
Kommentar betrachtet und ignoriert, außer bei Befehlen, die keine
Kommentare beachten, wie in den Beispielen unten gezeigt.  Ein Kommentar
kann an jeder Zeichen-Position auf der Zeile beginnen.

Bei einigen Befehlen gibt es »Fallen« mit Kommentaren.  Beispiele: >

	:abbrev dev development		" shorthand
	:map <F3> o#include		" insert include
	:execute cmd			" do it
	:!ls *.c			" list C files

Die Abkürzung 'dev' wird expandiert zu 'development     " shorthand'.  Die
Belegung von <F3> ist tatsächlich die ganze Zeile nach dem 'o# ....',
einschließlich dem '" insert include'.  Der »execute«-Befehl ergibt einen
Fehler.  Der »!«-Befehl schickt alles nach ihm an die Shell, was einen Fehler
wegen eines unbalancierten '"'-Zeichens verursacht.
   Nach den Befehlen »:map«, »:abbreviate«, »:execute« und »!« kann kein
Kommentar stehen (es gibt ein paar Befehle mehr mit dieser Einschränkung).
Für die Befehle »:map«, »:abbreviate« und »:execute« gibt es einen Trick: >

	:abbrev dev development|" shorthand
	:map <F3> o#include|" insert include
	:execute cmd			|" do it

Mit dem Zeichen '|' wird ein Befehl vom nächsten getrennt.  Und dieses nächste
Zeichen ist nur ein Kommentar.  Für den letzten Befehl müssen Sie zwei Dinge
machen: |:execute| und '|' benutzen: >

	:exe '!ls *.c'			|" list C files

Man beachte, das hier kein Leerzeichen vor dem '|' in der Abkürzung und der
Belegung ist.  Bei diesen Befehlen wird jedes Zeichen bis zum Zeilenende
oder dem '|' einbezogen.  Als Konsequenz dieses Verhaltens sieht man nicht
immer, das nachstehende Leerzeichen einbezogen werden: >

	:map <F4> o#include  

Um diese Probleme zu erkennen, können Sie die Option 'list' setzen, wenn
Sie vimrc-Dateien editieren.

Für Unix gibt es eine besondere Möglichkeit, eine Zeile zu kommentieren, die
es erlaubt, ein Vim-Skript ausführbar zu machen: >

	#!/usr/bin/env vim -S
	echo "this is a Vim script"
	quit

Der Befehl »#« selbst listet eine Zeile mit der Zeilennummer.  Das
Hinzufügen eines Ausrufezeichen lässt ihn nichts machen, so dass Sie den
Shell-Befehl hinzufügen können, um den Rest der Datei auszuführen. |:#!|
|-S|


FALLEN

Ein noch größeres Problem ensteht im folgenden Beispiel: >

	:map ,ab o#include
	:unmap ,ab 

Hier funktioniert der unmap-Befehl nich, weil er versucht »,ab «
freizugeben.  Dies existiert nicht als Belegungsfolge.  Ein Fehler wird
ausgegeben, der sehr schwer zu identifizieren ist, weil das nachstehende
Leerzeichen in »:unmap ,ab « nicht sichtbar ist.

Und es ist dasselbe wie wenn man einen Kommentar nach einem »unmap«-Befehl
benutzt: >

	:unmap ,ab     " comment

Hier wird der Teil, der Kommentar, ist ignoriert.  Vim versucht dennoch
»,ab     «, freizugeben, was nicht existiert.  Wir schreiben es um als: >

	:unmap ,ab|    " comment


DIE ANSICHT WIEDERHERSTELLEN

Manchmal will man eine Änderung machen und dahin zurück gehen, wo der Cursor
war.  Die relative Position wiederherstellen wäre auch nett, so dass dieselbe
Zeile die oberste im Fenster ist.
   Dieses Beispiel kopiert die aktuelle Zeile, setzt sie über die erste Zeile
der Datei, und stellt dann die Ansicht wieder her: >

	map ,p ma"aYHmbgg"aP`bzt`a

Was dies tut: >
	ma"aYHmbgg"aP`bzt`a
<	ma			setze Markierung a bei Cursor-Position
	  "aY			kopiere aktuelle Zeile in Register a
	     Hmb		gehe zur obersten Zeile im Fenster und setze
				dort Markierung b
		gg		gehe zur ersten Zeile der Datei
		  "aP		setze kopierte Zeile über sie
		     `b		gehe zurück zur obersten Zeile der Anzeige
		       zt	positioniere den Text im Fenster wie vorher
			 `a	gehe zurück zur gespeicherten Cursor-Position


PAKETIERUNG

Um zu vermeiden, dass Ihre Funktionsnamen Funktionen beeinflussen, die Sie von
anderen erhalten, benutzen Sie dieses Schema:

- Stellen Sie jedem Funktionsnamen eine einzigartige Zeichenkette voran.  Ich
  benutze oft eine Abkürzung.  Zum Beispiel wird »OW_« für Funktionen des
Optionsfensters verwandt.

- Packen Sie die Definitionen Ihrer Funktionen in eine Datei.  Setzen Sie eine
  globale Variable, die anzeigt, dass die Funktionen geladen wurden.  Wenn die
  Datei erneut eingelesen wird, geben Sie erst die Funktionen frei.

Beispiel: >

	" Dies ist das Paket XXX

	if exists("XXX_loaded")
	  delfun XXX_one
	  delfun XXX_two
	endif

	function XXX_one(a)
		... body of function ...
	endfun

	function XXX_two(b)
		... body of function ...
	endfun

	let XXX_loaded = 1

==============================================================================
*41.11*	Ein Plugin schreiben				*write-plugin*

Sie können ein Vim-Skript so schreiben, dass viele Leute es benutzen
können.  Dies nennt sich Plugin.  Vim-Benutzer können Ihr Skript in ihr
Plugin-Verzeichnis legen und seine Features auf der Stelle nutzen
|add-plugin|.

Tatsächlich gibt es zwei Typen von Plugins:

 globale Plugins: Für alle Typen von Dateien.
Dateityp-Plugins: Nur für Dateien eines bestimmten Typs.

In diesem Abschnitt wird der erste Typ erklärt.  Die meisten Elemente sind
auch relevant für das Schreiben von Dateityp-Plugins.  Die Spezifika für
Dateityp-Plugins folgen im nächsten Abschnitt |write-filetype-plugin|.


NAME

Zuallererst müssen Sie einen Namen für Ihr Plugin wählen.  Die Features,
die von dem Plugin bereitgestellt werden werden, sollten anhand seines
Namens klar sein.  Und es sollte unwahrscheinlich sein, dass jemand anderes
ein Plugin mit demselben Namen schreibt, das etwas anderes tut.  Und bitte
begrenzen Sie den Namen auf acht Zeichen, um Probleme auf alten
Windows-Systemen zu vermeiden.

Ein Skript, welches Tipp-Fehler korrigiert, könnte »typecorr.vim« genannt
werden.  Wir benutzen es hier als Beispiel.

Damit das Plugin für jeden funktioniert, sollte es einigen wenigen
Richtlinien folgen.  Diese werden Schritt-für-Schritt erklärt.  Das
komplette Beispiel-Plugin steht am Ende.


KÖRPER

Lassen Sie uns mit dem Körper des Plugins beginnen, den Zeilen, die
tatsächlich die Arbeit erledigen: >

 14	iabbrev teh the
 15	iabbrev otehr other
 16	iabbrev wnat want
 17	iabbrev synchronisation
 18		\ synchronization
 19	let s:count = 4

Die tatsächliche Liste sollte selbstverständlich viel länger sein.

Die Zeilennummern wurden nur hinzugefügt, um ein Paar Dinge zu erläutern,
übernehmen Sie sie nicht in Ihre Plugin-Datei!


KOPF

Sie werden dem Plugin vermutlich neue Korrekturen hinzufügen, und bald
haben Sie mehrere Versionen herumliegen.  Und wenn Sie die Datei verteilen,
werden die Leute wissen wollen, wer dieses wundervolle Plugin schrieb und
wohin sie Anmerkungen schicken können.  Deshalb stellen Sie Kopfzeilen an
den Beginn Ihres Plugins: >

  1	" Vim global plugin for correcting typing mistakes
  2	" Last Change:	2000 Oct 15
  3	" Maintainer:	Bram Moolenaar <Bram@vim.org>

Über Copyright und Lizensierung: Da Plugins sehr nützlich sind, und es
kaum wert ist, ihre Verteilung zu begrenzen, erwägen Sie bitte, Ihr Plugin
entweder in die Public-Domain oder unter die Vim-Lizenz |license| zu
stellen.  Eine kurze Zeile hierüber nahe des Beginn des Plugins sollte
ausreichend sein.  Beispiel: >

  4	" License:	This file is placed in the public domain.


ZEILENFORTSETZUNG, SEITENEFFEKTE VERMEIDEN		*use-cpo-save*

Oben in Zeile 18 wird der Mechanismus der Zeilen-Fortsetzung benutzt
|line-continuation|.  Benutzer, bei denen 'compatible' gesetzt ist, werden
hier Probleme, eine Fehlermeldung bekommen.  Wir können nicht einfach
'compatible' neu setzen, weil dies viele Seiteneffekte hat.  Um dies zu
vermeiden, setzen wir die Option 'cpoptions' auf ihren Vim-Standardwert und
stellen sie später wieder her.  Das erlaubt die Benutzung von
Zeilen-Fortsetzung und lässt das Skript für die meisten Leute
funktionieren.  Es wird so gemacht: >

 11	let s:save_cpo = &cpo
 12	set cpo&vim
 ..
 42	let &cpo = s:save_cpo

Wir speichern zunächst den alten Wert von 'cpoptions' in der Variablen
s:save_cpo.  Am Ende des Plugins wird dieser Wert wiederhergestellt.

Beachten Sie, dass eine skript-lokale Variable benutzt wird |s:var|.  Eine
globale Variable könnte bereits für etwas anderes in Gebrauch sein.
Benutzen Sie immer skript-lokale Variablen für Dinge, die nur in dem Skript
benutzt werden.


NICHT LADEN

Es ist möglich, dass ein Nutzer nicht immer dieses Plugin laden möchte.
Oder der System-Administrator hat es in das system-weite Plugin-Verzeichnis
gelegt, aber ein Nutzer hat sein eigenes Plugin, das er nutzen möchte.
Dann muss der Nutzer eine Möglichkeit haben, das Laden dieses bestimmten
Plugins zu deaktivieren.  Dies macht es möglich: >

  6	if exists("g:loaded_typecorr")
  7	  finish
  8	endif
  9	let g:loaded_typecorr = 1

Dies vermeidet es auch, dass wenn das Skript zweimal geladen wird, dass es
Fehlermeldungen für das Neudefinieren von Funktionen und Schwierigkeiten
bei automatischen Befehlen, die zweimal hinzugefügt werden, verursacht.

Es empfiehlt sich, dass der Name mit »loaded_« und dann wortwörtlich mit
dem Namen des Plugins beginnt.  »g:« wird nur vorangestellt, um Fehler zu
vermeiden, wenn die Variable in einer Funktion benutzt wie (ohne »g:«
wäre sie eine Variable lokal zu dieser Funktion).

Das Benutzen von »finish« verhindert, das Vim den Rest der Datei liest, es
ist viel schneller als if-endif um die ganze Datei.


BELEGUNGEN

Nun lassen Sie uns das Plugin interessanter machen: Wir fügen eine Belegung
hinzu, die eine Korrektur für das Wort unter dem Cursor hinzufügt.  Um dem
Nutzer zu erlauben, zu definieren, welche Tasten eine Belegung in einem
Plugin benutzt, kann das Element <Leader> benutzt werden: >

 22	  map <unique> <Leader>a  <Plug>TypecorrAdd

Das »<Plug>TypecorrAdd« macht die Arbeit, mehr darüber weiter unten.

Der Nutzer kann die Variable »mapleader« auf die Tastenfolge setzen, mit
der er diese Belegung starten lassen möchte.  Falls der Nutzer also dies
macht: >

	let mapleader = "_"

definiert die Belegung »_a«.  Falls der Nutzer dies nicht tat, wird der
Standardwert benutzt, was ein Backslash ist.  Dann wird eine Belegung für
»\a« definiert.

Beachten Sie, dass <unique> benutzt wird, dies verursacht eine
Fehlermeldung, falls die Belegung der Tastenfolge bereits
existiert. |:map-<unique>|

Aber was, falls der Nutzer seine eigene Tastenfolge definieren möchte? Wir
können dies mit folgendem Mechanismus erlauben: >

 21	if !hasmapto('<Plug>TypecorrAdd')
 22	  map <unique> <Leader>a  <Plug>TypecorrAdd
 23	endif

Dies prüft, ob eine Belegung von »<Plug>TypecorrAdd« bereits existiert,
und definiert die Belegung von »<Leader>a« nur dann, falls nicht.  Der
Nutzer hat nun die Möglichkeit, dies in seine vimrc zu packen: >

	map ,c  <Plug>TypecorrAdd

Dann ist die belegte Tastenfolge »,c« statt »_a« oder »\a«.


STÜCKE

Wenn ein Skript länger wird, möchte man oft die Arbeit in Portionen
aufteilen.  Man kann hierfür Funktionen oder Belegungen benutzen.  Aber man
will nicht, dass diese Funktionen oder Belegungen andere Skripte
beeinflussen.  Man könnte zum Beispiel eine Funktion Add() definieren, aber
ein anderes Skript könnte versuchen, dieselbe Funktion zu definieren.  Um
dies zu vermeiden, definieren wir die Funktion lokal zum Skript, indem wir
ihr »s:« voranstellen.

Wir definieren eine Funktion, die eine neue Tipp-Korrektur hinzufügt: >

 30	function s:Add(from, correct)
 31	  let to = input("type the correction for " . a:from . ": ")
 32	  exe ":iabbrev " . a:from . " " . to
 ..
 36	endfunction

Jetzt können wir innerhalb des Skripts die Funktion s:Add() aufrufen.
Falls ein anderes Skript ebenfalls s:Add() definiert, ist sie lokal zu jenem
Skript und kann nur von dem Skript aufgerufen werden, in dem sie definiert
wurde.  Es kann auch eine globale Funktion Add() geben (ohne »s:«, die
wieder eine andere Funktion ist.

<SID> kann mit Belegungen verwandt werden.  Es generiert eine Skript-ID, die
das aktuelle Skript identifiziert.  In unserem Tipp-Korrektur-Plugin
verwenden wir es folgendermaßen: >

 24	noremap <unique> <script> <Plug>TypecorrAdd  <SID>Add
 ..
 28	noremap <SID>Add  :call <SID>Add(expand("<cword>"), 1)<CR>

Wenn also ein Nutzer »\a« tippt, wird diese Folge aufgerufen: >

	\a  ->  <Plug>TypecorrAdd  ->  <SID>Add  ->  :call <SID>Add()

Falls ein anderes Skript auch <SID>Add belegen würde, würde es eine andere
Skript-ID erhalten, also eine andere Belegung definieren.

Beachten Sie, dass wir hier <SID>Add() statt s:Add benutzen.  Das kommt
daher, dass die Belegung vom Nutzer getippt wird, also außerhalb des
Skripts.  Das <SID> wird in die Skript-ID übersetzt, so dass Vim weiß, in
welchem Skript er nach der Funktion Add() schauen muss.

Dies ist ein Bisschen kompliziert, aber es ist nötig, damit das Plugin mit
anderen Skripten zusammenarbeitet.  Die Grundregel ist, dass Sie <SID>Add()
in Belegungen verwenden, und s:Add() an anderen Stellen (dem Skript selbst,
automatischen Befehlen, Benutzerbefehlen).

Wir können auch einen Menü-Eintrag hinzufügen, der dasselbe tut wie die
Belegung: >

 26	noremenu <script> Plugin.Add\ Correction      <SID>Add

Das Menü »Plugin« ist das empfohlene, um Menü-Element für Plugins
hinzuzufügen.  In diesem Falle wird nur ein Element benutzt.  Wenn man
mehrere Elemente hinzufügt, empfiehlt sich das Erzeugen eines Untermenüs.
Zum Beispiel könnte »Plugin.CVS« für ein Plugin verwendet werden, das
CVS-Operationen anbietet: »Plugin.CVS.checkin«, »Plugin.CVS.checkout«
usw.

Beachten Sie, dass in Zeile 28 »:noremap« benutzt wird, um zu vermeiden,
dass irgendwelche anderen Belegungen Probleme verursachen.  Jemand könnte
zum Beispiel »:call« neu belegt haben.  In Zeile 24 benutzen wir auch
»:noremap«, aber wir wollen »<SID>Add« neu belegt haben.  Deshalb wird
hier »<script>« benutzt.  Dies erlaubt nur Belegungen, die lokal zum
Skript sind |:map-<script>|.  Dasselbe passiert in Zeile 26 für
»:noremenu« |:menu-<script>|.


<SID> UND <Plug>					*using-<Plug>*

Sowohl <SID> und <Plug> werden benutzt, um zu vermeiden, dass Belegungen von
getippten Tasten Belegungen beeinflussen, die nur von anderen Belegungen zu
verwenden sind.  Beachten Sie den Unterschied zwischen <SID> und <Plug>:

<Plug>	ist außerhalb des Skripts sichtbar.  Es wird für Belegungen verwendet,
	die der Nutzer möglicherweise mit einer Tastenfolge belegen will.
	<Plug> ist ein besonderer Code, den eine getippte Taste nie
	produzieren wird.
	Um es sehr unwahrscheinlich zu machen, dass andere Plugins dieselbe
	Zeichenfolge verwenden, benutze man diese Struktur:
	<Plug> Skriptname Belegungsname.
	In unserem Beispiel ist der Skriptname »Typecorr« und der
	Belegungsname »Add«.  Dies ergibt »<Plug>TypecorrAdd«.  Nur das erste
	Zeichen von Skriptname und Belegungsname ist groß, so dass wir sehen
	können, wo der Belegungsname beginnt.

<SID>	ist die Skript-ID, ein eindeutiger Identifikator für ein Skript.
	Intern übersetzt Vim <SID> in »<SNR>123_«, wobei »123« jede Zahl sein
	kann.  Also hat eine Funktion »<SID>Add()« einen Name »<SNR>11_Add()«
	in einem Skript und »<SNR>22_Add()« in einem anderen.  Sie können dies
	sehen, falls Sie den Befehl »:function« benutzen, um eine Liste von
	Funktionen zu erhalten.  Die Übersetzung von <SID> in Belegungen ist
	exakt dieselbe, deshalb können Sie eine skript-lokale Funktion von
	einer Belegung aufrufen.


BENUTZERBEFEHLE

Nun lassen Sie uns einen Benutzerbefehl hinzufügen, um eine Korrektur
hinzuzufügen: >

 38	if !exists(":Correct")
 39	  command -nargs=1  Correct  :call s:Add(<q-args>, 0)
 40	endif

Der Benutzerbefehl wird nur definiert, falls kein Befehl desselben Namen
bereits existiert.  Andernfalls würden wir hier einen Fehler bekommen.  Den
existierenden Benutzerbefehl mit »:command!« nichtig machen, ist keine
gute Idee, dies könnte den Nutzer sich fragen lassen, warum der Befehl, den
er selbst definiert hat, nicht funktioniert |:command|.


SKRIPT-VARIABLEN

Wenn eine Variable mit »s:« beginnt, ist sie eine Skript-Variable.  Sie
kann nur innerhalb eines Skripts verwendet werden.  Außerhalb des Skripts
ist sie nicht sichtbar.  Dies vermeidet Probleme, wenn derselbe
Variablenname in verschiedenen Skripten verwendet wird.  Die Variablen
werden solange gehalten, wie Vim läuft.  Und dieselben Variablen werden
verwandt, wenn dasselbe Skript wieder eingelesen wird |s:var|.

Der Spaß an der Sache ist, dass diese Variablen auch in Funktionen,
automatischen Befehlen und Benutzerbefehlen, die in dem Skript definiert
werden, verwendet werden können.  In unserem Beispiel können wir ein Paar
Zeilen hinzufügen, um die Anzahl der Korrekturen zu zählen: >

 19	let s:count = 4
 ..
 30	function s:Add(from, correct)
 ..
 34	  let s:count = s:count + 1
 35	  echo s:count . " corrections now"
 36	endfunction

Zunächst wird s:count im Skript selbst auf 4 initialisiert.  Wenn später
die Funktion s:Add() aufgerufen wird, inkremiert sie s:count.  Es ist nicht
entscheidend von wo die Funktion aufgerufen wurde, weil sie im Skript
definiert wurde, benutzt sie die lokalen Variablen dieses Skripts.


DAS ERGEBNIS

Hier ist das komplette sich ergebende Beispiel: >

  1	" Vim global plugin for correcting typing mistakes
  2	" Last Change:	2000 Oct 15
  3	" Maintainer:	Bram Moolenaar <Bram@vim.org>
  4	" License:	This file is placed in the public domain.
  5
  6	if exists("g:loaded_typecorr")
  7	  finish
  8	endif
  9	let g:loaded_typecorr = 1
 10
 11	let s:save_cpo = &cpo
 12	set cpo&vim
 13
 14	iabbrev teh the
 15	iabbrev otehr other
 16	iabbrev wnat want
 17	iabbrev synchronisation
 18		\ synchronization
 19	let s:count = 4
 20
 21	if !hasmapto('<Plug>TypecorrAdd')
 22	  map <unique> <Leader>a  <Plug>TypecorrAdd
 23	endif
 24	noremap <unique> <script> <Plug>TypecorrAdd  <SID>Add
 25
 26	noremenu <script> Plugin.Add\ Correction      <SID>Add
 27
 28	noremap <SID>Add  :call <SID>Add(expand("<cword>"), 1)<CR>
 29
 30	function s:Add(from, correct)
 31	  let to = input("type the correction for " . a:from . ": ")
 32	  exe ":iabbrev " . a:from . " " . to
 33	  if a:correct | exe "normal viws\<C-R>\" \b\e" | endif
 34	  let s:count = s:count + 1
 35	  echo s:count . " corrections now"
 36	endfunction
 37
 38	if !exists(":Correct")
 39	  command -nargs=1  Correct  :call s:Add(<q-args>, 0)
 40	endif
 41
 42	let &cpo = s:save_cpo

Zeile 33 wurde noch nicht erklärt.  Sie verbindet die neue Korrektur mit
dem Wort unter dem Cursor.  Der Befehl |:normal| wird benutzt, um die neue
Abkürzung zu benutzen.  Beachten Sie, das Belegungen und Abkürzungen hier
expandiert werden, selbst wenn die Funktion von einer Belegung aufgerufen
wurde, die mit »:noremap« definiert wurde.

Es empfiehlt sich, für die Option 'fileformat' »unix« zu benutzen.  Die
Vim-Skripte funktionieren dann überall.  Skripte, bei denen 'fileformat'
auf »dos« gesetzt ist, funktionieren nicht unter Unix.  Siehe auch
|:source_crnl|.  Um sicher zu sein, dass sie richtig gesetzt ist, tun Sie
dies vor dem Schreiben der Datei: >

	:set fileformat=unix


DOKUMENTATION						*write-local-help*

Es ist eine gute Idee, auch etwas Dokumentation für das Plugin zu
schreiben.  Besonders, wenn sein Verhalten von dem Nutzer geändert werden
kann.  Für die Installation siehe |add-local-help|.

Hier ist ein einfaches Beispiel für eine Plugin-Hilfe-Datei namens
»typecorr.txt«

  1	*typecorr.txt*	Plugin for correcting typing mistakes
  2
  3	If you make typing mistakes, this plugin will have them corrected
  4	automatically.
  5
  6	There are currently only a few corrections.  Add your own if you like.
  7
  8	Mappings:
  9	<Leader>a   or   <Plug>TypecorrAdd
 10		Add a correction for the word under the cursor.
 11
 12	Commands:
 13	:Correct {word}
 14		Add a correction for {word}.
 15
 16							*typecorr-settings*
 17	This plugin doesn't have any settings.

Die erste Zeile ist tatsächlich die einzige, bei der das Format zählt.
Sie wird aus der Hilfe-Datei extrahiert, um in den Abschnitt »LOKALE
ERGÄNZUNGEN« von help.txt gepackt zu werden |local-additions|.  Der erste
»*« muss in der ersten Spalte der ersten Zeile sein.  Nach dem Hinzufügen
Ihrer Hilfe-Datei machen Sie »:help« und prüfen, ob sich die Einträge
hübsch aufreihen.

Sie können weitere Tags in ** in Ihrer Hilfe-Datei hinzufügen.  Aber seien
Sie vorsichtig, existierende Hilfe-Tags nicht zu verwenden.  In den meisten
werden Sie wahrscheinlich den Namen Ihres Plugins verwenden, wie
»typecorr-settings« im Beispiel.

Referenzen auf andere Teile der Hilfe in || zu verwenden empfiehlt sich.
Dies macht es dem Nutzer leicht, verwandte Hilfe zu finden.


DATEITYP-ERKENNUNG					*plugin-filetype*

Falls Ihr Dateityp noch nicht von Vim erkannt wird, sollten Sie einen
Schnipsel zur Dateityp-Erkennung in einer gesonderten Datei erstellen.  Es
ist für gewöhnlich ein automatischer Befehl der den Dateityp setzt, wenn
der Dateiname auf ein Muster passt.  Beispiel: >

	au BufNewFile,BufRead *.foo			set filetype=foofoo

Schreiben sie diese einzeilige Datei als »ftdetect/foofoo.vim« in das
erste Verzeichnis, das in 'runtimepath' erscheint.  Unter Unix wäre dies
»~/.vim/ftdetect/foofoo.vim«.  Konvention ist, dass der Name des Dateityps
für den Skriptnamen verwandt wird.

Sie können kompliziertere Tests machen, falls Sie mögen, zum Beispiel den
Inhalt der Datei inspizieren, um die Sprache zu erkennen.  Siehe auch
|new-filetyp|


ZUSAMMENFASSUNG						*plugin-special*

Zusammenfassung besonderer Dinge, die man in einem Plugin benutzen kann:

s:name			Variablen lokal zum Skript.

<SID>			Skript-ID, benutzt für Belegungen und Funktionen lokal
			zum Skript.

hasmapto()		Funktion, um zu testen, ob der Nutzer bereits eine
			Belegung für Funktionalität, die das Skript bietet,
			definiert hat.

<Leader>		Wert von »mapleader«, die der Nutzer als die Tasten
			definiert, mit denen Plugin-Belegungen beginnen.

:map <unique>		Gibt eine Warnung, falls eine Belegung bereits
			existiert

:noremap <script>	Benutze nur Belegungen lokal zum Skript, nicht globale.

exists(":Cmd")		Prüft, ob ein Benutzerbefehl bereits existiert.

==============================================================================
*41.12*	Ein Dateityp-Plugin schreiben	*write-filetype-plugin* *ftplugin*

Ein Dateityp-Plugin ist wie ein globales, außer dass es nur für den
aktuellen Puffer Optionen setzt und Belegungen definiert.  Siehe
|add-filetype-plugin| für Informationen, wie dieser Plugin-Typ benutzt
wird.

Zunächst lesen Sie den Abschnitt über globale Plugins oben |41.11|.  Alles
dort gesagte gilt auch für Dateityp-Plugins.  Es gibt ein Paar Extras, die
hier erklärt werden.  Essenziell ist, dass ein Dateityp-Plugin sich nur auf
den aktuellen Puffer auswirken sollte.


DEAKTIVIEREN

Falls Sie ein Dateityp-Plugin schreiben, das von vielen Leuten genutzt
werden soll, brauchen sie eine Möglichkeit, sein Laden zu deaktivieren.
Stellen Sie dies an den Anfang des Plugins: >

	" Only do this when not done yet for this buffer
	if exists("b:did_ftplugin")
	  finish
	endif
	let b:did_ftplugin = 1

Dies muss auch verwandt werden, um zu vermeiden, dass dasselbe Plugin
zweimal für denselben Puffer ausgeführt wird (passiert, wenn man den
Befehl »:edit« ohne Argumente benutzt).

Jetzt können Nutzer das Laden des Standard-Plugins komplett deaktivieren,
indem sie ein Dateityp-Plugin mit nur dieser Zeile machen: >

	let b:did_ftplugin = 1

Dies erfordert, dass das Verzeichnis für das Dateityp-Plugin in
'runtimepath' vor $VIMRUNTIME kommt!

Falls Sie das Standard-Plugin benutzen möchten, aber eine der Einstellungen
aufheben möchten, können sie die unterschiedliche Einstellung in ein
Skript schreiben: >

	setlocal textwidth=70

Nun schreiben Sie dies in das Verzeichnis »after«, so dass es nach dem
verteilten Dateityp-Plugin »vim.vim« eingelesen wird |after-directory|.
Unter Unix wäre dies »~/.vim/after/ftplugin/vim.vim«.  Beachten Sie, dass
das Standard-Plugin »b:did_ftplugin« setzt, dies wird hier aber nicht
beachtet.


OPTIONEN

Um sicherzustellen, dass das Dateityp-Plugin nur den aktuellen Puffer
beeinflusst, benutzen Sie den Befehl >

	:setlocal

um Optionen zu setzen.  Und setzen Sie nur Optionen, die lokal zu einem
Puffer sind (siehe die Hilfe zu der Option, um dies zu prüfen).  Wenn
|:setlocal| für globale Optionen oder Optionen, die lokal zu einem Fenster
sind, benutzt wird, ändert sich der Wert für viele Puffer, und das ist
nicht, was ein Dateityp-Plugin tun sollte.

Wenn eine Option einen Wert hat, der eine Liste von Flags oder Elementen
ist, erwägen Sie »+=« und »-=« zu nutzen, um den existierenden Wert zu
behalten.  Seien Sie sich bewusst, dass der Nutzer einen Optionswert bereits
verändert haben kann.  Zuerst auf den Standardwert setzen und dann ändern
ist oft eine gute Sache.  Beispiel: >

	:setlocal formatoptions& formatoptions+=ro


BELEGUNGEN

Um sicherzustellen, dass Belegungen nur in dem aktuellen Puffer
funktionieren, benutzen Sie den Befehl >

	:map <buffer>

Dies muss mit der zweischrittigen Belegung, wie oben erklärt, kombiniert
werden.  Ein Beispiel wie man Funktionalität in einem Dateityp-Plugin
definiert: >

	if !hasmapto('<Plug>JavaImport')
	  map <buffer> <unique> <LocalLeader>i <Plug>JavaImport
	endif
	noremap <buffer> <unique> <Plug>JavaImport oimport ""<Left><Esc>

|hasmapto()| wird benutzt um zu prüfen, ob der Nutzer bereits eine Belegung
auf <Plug>JavaImport definiert hat.  Falls nicht, definiert das
Dateityp-Plugin die Standard-Belegung.  Diese beginnt mit |<LocalLeader>|,
was dem Nutzer erlaubt, die Taste(n), mit denen Belegungen aus
Dateityp-Plugins beginnen, zu wählen.  Der Standard ist ein Backslash.
»<unique>« wird benutzt, um eine Fehlermeldung auszugeben, falls die
Belegung bereits existiert oder mit anderen Belegungen überlappt.
|:noremap| wird benutzt, um zu vermeiden, dass jegliche anderen Belegungen,
die der Nutzer definiert hat,Einfluss nehmen.  Man will möglicherweise
»:noremap <script>« verwenden, um das Neubelegen von Belegungen, die in
diesem Skript definiert wurden und mit <SID> beginnen, zu erlauben.

Der Nutzer muss die Möglichkeit haben, die Belegungen in einem
Dateityp-Plugin zu deaktivieren, ohne alles zu deaktivieren.  Hier ein
Beispiel, wie dies in einem Plugin für den Dateityp Email gemacht wird: >

	" Add mappings, unless the user didn't want this.
	if !exists("no_plugin_maps") && !exists("no_mail_maps")
	  " Quote text by inserting "> "
	  if !hasmapto('<Plug>MailQuote')
	    vmap <buffer> <LocalLeader>q <Plug>MailQuote
	    nmap <buffer> <LocalLeader>q <Plug>MailQuote
	  endif
	  vnoremap <buffer> <Plug>MailQuote :s/^/> /<CR>
	  nnoremap <buffer> <Plug>MailQuote :.,$s/^/> /<CR>
	endif

Zwei globale Variablen werden benutzt:
no_plugin_maps		deaktiviert Belegungen für alle Dateityp-Plugins
no_mail_maps		deaktiviert Belegungen für einen bestimmten Dateityp


BENUTZERBEFEHLE

Um einen Benutzerbefehl für einen bestimmten Dateityp hinzufügen, so dass
er nur in einem Puffer benutzt werden kann, benutzen Sie das Argument
»-buffer« von |:command|.  Beispiel: >

	:command -buffer  Make  make %:r.s


VARIABLEN

Ein Dateityp-Plugin wird für jeden Puffer seines Typs eingelesen.  Lokale
Skript-Variablen |s:var| werden zwischen allen Aufrufen geteilt.  Benutzen
Sie lokale Puffer-Variablen |b:var|, falls Sie eine Variable für einen
bestimmten Puffer wollen.


FUNKTIONEN

Wenn eine Funktion definiert wird, braucht dies nur einmal getan werden.
Aber das Dateityp-Plugin wird jedesmal eingelesen, wenn eine Datei dieses
Dateityps geöffnet wird.  Dieses Konstrukt stellt sicher, dass die Funktion
nur einmal definiert wird: >

	:if !exists("*s:Func")
	:  function s:Func(arg)
	:    ...
	:  endfunction
	:endif
<

UNDO							*undo_ftplugin*

Wenn der Benutzer »:setfiletype xyz« eingibt, sollte der Effekt des
vorigen Dateityps zurückgenommen werden.  Setzen Sie die Variable
b:undo_ftplugin auf die Befehle, die die Einstellungen in Ihrem
Dateityp-Plugin zurücknehmen.  Beispiel: >

	let b:undo_ftplugin = "setlocal fo< com< tw< commentstring<"
		\ . "| unlet b:match_ignorecase b:match_words b:match_skip"

Das Benutzen von »:setlocal« mit »<« nach dem Optionsnamen setzt die
Option auf ihren globalen Wert.  Das ist meistens das Beste, um den
Optionswert neu zu setzen.

Dies erfordert das Entfernen des Flags »C« von 'cpoptions' um
Zeilenfortsetzung zu erlauben, wie oben erwähnt |use-cpo-save|.


DATEINAME

Der Dateityp muss in den Dateinamen einbezogen werden |ftplugin-name|.
Benutzen Sie eine von diesen drei Formen:

	.../ftplugin/stuff.vim
	.../ftplugin/stuff_foo.vim
	.../ftplugin/stuff/bar.vim

»stuff« ist der Dateityp, »foo« und »bar« sind beliebige Namen.


ZUSAMMENFASSUNG						*ftplugin-special*

Zusammenfassung besonderer Dinge, die man in einem Dateityp-Plugin nutzen
kann:

<LocalLeader>		Wert von »maplocalleader«, welche der Nutzer als die
			Tasten definiert, mit denen Dateityp-Plugin-Belegungen
			beginnen.

:map <buffer>		Definiere eine Belegung lokal zum Puffer.

:noremap <script>	Belege nur Belegungen neu, die in diesem Skript
			definiert wurden und mit <SID> beginnen.

:setlocal		Setze eine Option nur für den aktuellen Puffer.

:command -buffer	Definiere einen Benutzerbefehl lokal zum Puffer.

exists("*s:Func")	Prüfe ob eine Funktion bereits definiert wurde.

Siehe auch |plugin-special|, die besonderen Dinge, die für alle Plugins
verwendet werden.

==============================================================================
*41.13*	Ein Kompiler-Plugin schreiben		*write-compiler-plugin*

Ein Kompiler-Plugin setzt Optionen zum Gebrauch mit einem bestimmten
Kompiler.  Der Nutzer kann es mit dem Befehl |:compiler| laden.
Hauptsächlicher Gebrauch ist es, die Optionen 'errorformat' und 'makeprg'
zu setzen.

Am einfachsten ist es, auf Beispiele zu schauen.  Dieser Befehl editiert
alle Standard-Kompiler-Plugins: >

	:next $VIMRUNTIME/compiler/*.vim

Benutzen Sie |:next|, um zur nächsten Plugin-Datei zu gelangen.

Es gibt zwei besondere Elemente bei diesen Dateien.  Das erste ist ein
Mechanismus, um einem Benutzer zu erlauben, die Standard-Datei zu
überstimmen oder ihr hinzuzufügen.  Die Standard-Dateien beginnen mit: >

	:if exists("current_compiler")
	:  finish
	:endif
	:let current_compiler = "mine"

Wenn Sie eine Kompiler-Datei schreiben und in Ihr persönliches
Laufzeit-Verzeichnis legen (z.B. ~/.vim/compiler für Unix), setzen Sie die
Variable »current_compiler«, um die Standard-Datei die Einstellungen
überspringen zu lassen.
							*:CompilerSet*
Der zweite Mechanismus ist, »:set« für »:compiler!« und »:setlocal« für
»:compiler« zu benutzen.  Vim definiert hierfür den Benutzerbefehl
»:CompilerSet«.  Ältere Vim-Versionen tun dies jedoch nicht, also sollte Ihr
Plugin ihn dann definieren.  Dies ist ein Beispiel: >

  if exists(":CompilerSet") != 2
    command -nargs=* CompilerSet setlocal <args>
  endif
  CompilerSet errorformat&		" use the default 'errorformat'
  CompilerSet makeprg=nmake

Wenn Sie ein Kompiler-Plugin für die Vim-Distribution oder für ein
system-weites Laufzeit-Verzeichnis schreiben, benutzen Sie den oben
erwähnten Mechanismus.  Wenn »current_compiler« bereits von einem
Nutzer-Plugin gesetzt wurde, wird nichts getan.

Wenn Sie ein Kompiler-Plugin schreiben, um Einstellungen eines
Standard-Plugins zu überstimmen, prüfen Sie nicht »current_compiler«.
Dieses Plugin soll als letztes geladen werden, also sollte es in einem
Verzeichnis am Ende von 'runtimepath' stehen.  Für Unix könnte dies
~/.vim/after/compiler sein.

==============================================================================
*41.14*	Ein Plugin so schreiben, dass es schnell lädt *write-plugin-quickload*

Ein Plugin kann wachsen und ziemlich lang werden.  Die Start-Verzögerung
kann merkbar werden, während Sie das Plugin kaum benutzen.  Dann ist es
Zeit für ein Schnelllade-Plugin.

Die Grundidee ist, dass das Plugin zweimal geladen wird.  Beim ersten Mal
werden Benutzerbefehle und Belegungen definiert, die die Funktionalität
anbieten.  Beim zweiten Mal werden die Funktion, die die Funktionalität
implementieren, definiert.

Es mag überraschend klingen, dass Schnellladen bedeutet, ein Skript zweimal
zu laden.  Was wir meinen ist, dass es beim ersten Mal schnell lädt, die
Masse des Skripts auf das zweite Mal verschiebend, was nur passiert, wenn
man es tatsächlich benutzt.  Wenn Sie immer die Funktionalität benutzen,
wird es tatsächlich langsamer!

Beachten Sie, dass es seit Vim 7 eine Alternative gibt: benutzen Sie die
Funktionalität |autoload| |41.15|.

Das folgende Beispiel zeigt, wie es gemacht wird: >

	" Vim global plugin for demonstrating quick loading
	" Last Change:	2005 Feb 25
	" Maintainer:	Bram Moolenaar <Bram@vim.org>
	" License:	This file is placed in the public domain.

	if !exists("s:did_load")
		command -nargs=* BNRead  call BufNetRead(<f-args>)
		map <F19> :call BufNetWrite('something')<CR>

		let s:did_load = 1
		exe 'au FuncUndefined BufNet* source ' . expand('<sfile>')
		finish
	endif

	function BufNetRead(...)
		echo 'BufNetRead(' . string(a:000) . ')'
		" read functionality here
	endfunction

	function BufNetWrite(...)
		echo 'BufNetWrite(' . string(a:000) . ')'
		" write functionality here
	endfunction

Wenn das Skript zum ersten Mal geladen wird, ist »s:did_load« nicht
gesetzt.  Die Befehle zwischen »if« und »endif« werden ausgeführt.
Dies endet in einem Befehl |:finish|, also wird der Rest des Skripts nicht
ausgeführt.

Beim zweiten Mal, wenn das Skript geladen wird, existiert »s:did_load« und
die Befehle nach dem »endif« werden ausgeführt.  Dies definiert die
(möglicherweise langen) Funktionen BufNetRead() und BufNetWrite().

Falls Sie dieses Skript in Ihr Plugin-Verzeichnis legen, führt Vim es beim
Starten aus.  Dies ist die Folge von Ereignissen, die geschieht:

1. Der Befehl »BNRead« Befehl wird definiert und die Taste <F19> wird
   belegt, wenn das Skript beim Start eingelesen wird.  Ein automatischer
   Befehl |FuncUndefined| wird definiert. Der Befehl »:finish« lässt das
   Skript frühzeitig terminieren.

2. Der Nutzer tippt den Befehl BNRead oder drückt die Taste <F19>.  Die
   Funktion BufNetRead() oder BufNetWrite() wird aufgerufen.

3. Vim kann die Funktion nicht finden und löst den automatischen Befehl
   |FucUndefined| aus.  Weil das Muster »BufNet*« auf die aufgerufene
   Funktion passt, wird der Befehl »source fname«.  »fname« ist gleich
   dem Namen der Funktion, egal wo es liegt, weil es vom Expandieren von
   »<sfile>« kommt (siehe |expand()|).

4. Das Skript wird erneut eingelesen, die Variable »s:did_load« existiert,
   und die Funktionen werden definiert.

Beachten Sie, dass die Funktionen, die im Nachhinein geladen werden, auf das
Muster in dem automatischen Befehl |FuncUndefined| passen.  Sie müssen
sicherstellen, dass kein anderes Plugin Funktionen definiert, die auf dieses
Muster passen.

==============================================================================
*41.15*	Bibliotheksskripte schreiben		*write-library-script*

Einige Funktionalität wird an mehreren Stellen benötigt.  Wenn dies mehr
als ein Paar Zeilen werden, möchten Sie sie in ein Skript packen und es von
vielen Skripten aus benutzen.  Wir nennen dies eine Skript ein
Bibliotheksskript.

Ein Bibliotheksskript von Hand laden ist möglich, so lange wie Sie
vermeiden, es zu laden, wenn dies bereits getan wurde.  Sie können dies mit
der Funktion |exists()| machen.  Beispiel: >

	if !exists('*MyLibFunction')
	   runtime library/mylibscript.vim
	endif
	call MyLibFunction(arg)

Hier müssen Sie wissen, dass MyLibFunction() in einem Skript
»library/mylibscript.vim« in einem der Verzeichnisse in 'runtimepath'
definiert ist.

Um dies ein Bisschen einfacher zu machen, bietet Vim den Mechanismus
autoload an.  Dann sieht das Beispiel so aus: >

	call mylib#myfunction(arg)

Das ist viel einfacher, oder nicht? Vim erkennt den Funktionsnamen und wenn
sie nicht definiert ist, sucht er nach dem Skript »autoload/mylib.vim« im
'runtimepath'.  Dieses Skript muss die Funktion »mylib#myfunction()«
definieren.

Sie können viele andere Funktionen in das Skript mylib.vim packen, Sie sind
frei, Ihre Funktionen in Bibliotheksskripten zu organisieren.  Aber Sie
müssen Funktionsnamen benutzen, bei denen der Teil vor dem '#' mit dem
Skriptnamen übereinstimmt.  Andernfalls wüsste Vim nicht, welches Skript
er laden muss.

Falls Sie wirklich enthusiastisch werden und viele Bibliotheksskripte
schreiben, mögen Sie Unterverzeichnisse verwenden wollen.  Beispiel: >

	call netlib#ftp#read('somefile')

Für Unix könnte das Bibliotheksskript, das für dies benutzt wird, sein:

	~/.vim/autoload/netlib/ftp.vim

Wo die Funktion wie folgt definiert wird: >

	function netlib#ftp#read(fname)
		"  Read the file fname through ftp
	endfunction

Beachten Sie, dass der Name, mit dem die Funktion definiert wird, exakt
derselbe ist, wie der Name für das Aufrufen der Funktion.  Und der Teil vor
dem letzten '#' stimmt genau mit dem Unterverzeichnis und Skriptnamen
überein.

Sie können denselben Mechanismus für Variablen verwenden: >

	let weekdays = dutch#weekdays

Die lädt das Skript »autoload/dutch.vim«, welches etwas enthalten sollte
wie: >

	let dutch#weekdays = ['zondag', 'maandag', 'dinsdag', 'woensdag',
		\ 'donderdag', 'vrijdag', 'zaterdag']

Zum Weiterlesen: |autoload|.

==============================================================================
*41.16*	Vim-Skripte verteilen			*distribute-script*

Vim-Nutzer schauen auf der Vim-Webseite (http://www.vim.org/) nach
Skripten.  Falls Sie etwas gemacht haben, das nützlich für andere ist,
teilen Sie es!

Vim-Skripte können auf jedem System benutzt werden.  Es könnte keinen
Befehl tar oder gzip geben.  Falls Sie Dateien zusammen packen und/oder
komprimieren möchten, empfiehlt sich das Werkzeug »zip«.

Für äußerste Portabilität benutzen Sie Vim selbst, um Skript zusammen zu
packen.  Dies kann mit dem Werkzeug Vimball gemacht werden.  Siehe
|vimball|.

Es ist gut, falls Sie eine Zeile hinzufügen, um automatisches Aktualisieren
zu erlauben.  Siehe |glvs-plugins|.

==============================================================================

Nächstes Kapitel: |usr_42.txt| Neue Menüs hinzufügen

Copyright: siehe |manual-copyright| vim:tw=78:ts=8:ft=help:norl: