-
Notifications
You must be signed in to change notification settings - Fork 1
/
usr_41.plx
executable file
·1709 lines (1265 loc) · 58.5 KB
/
usr_41.plx
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
*usr_41.txt* For Vim version 6.3. Last change: wt maj 19 20:00 2004 C ł
VIM PODRĘCZNIK UŻYTKOWNIKA - Bram Moolenaar
tłum. Mikołaj Machowski
Pisanie skryptów Vima
Język skryptowy Vima używany jest w pliku startowym vimrc, plikach składni
i w wielu innych przypadkach. Ten rozdział wyjaśnia co można zrobić
w skryptach Vima. Jest to bardzo dużo, więc rozdział jest długi.
|41.1| Wstęp
|41.2| Zmienne
|41.3| Wyrażenia
|41.4| Warunki (if, elseif, else)
|41.5| Wykonywanie wyrażeń
|41.6| Funkcje
|41.7| Definiowanie funkcji
|41.8| Wyjątki
|41.9| Różne uwagi
|41.10| Pisanie wtyczki
|41.11| Pisanie wtyczki dla typu pliku (ftplugin)
|41.12| Pisanie wtyczki dla kompilatora
Następny rozdział: |usr_42.txt| Dodawanie menu
Poprzedni rozdział: |usr_40.txt| Tworzenie poleceń
Spis treści: |usr_toc.txt|
==============================================================================
*41.1* Wstęp *vim-script-intro*
Twoje pierwsze doświadczenie ze skryptami Vima to plik vimrc. Vim czyta go
podczas startu i wykonuje zawarte tam polecenia. Między innymi możesz ustawiać
opcje na wartości ci odpowiadające. Możesz tam też użyć dowolnego polecenia
dwukropka (polecenia zaczynające się na ":"; nazywa się je też czasami
komendami Ex lub poleceniami linii poleceń).
Pliki składni także są skryptami Vima. To samo pliki ustawiające opcje dla
poszczególnych typów plików. Skomplikowane makro może być zdefiniowane
w osobnym pliku skryptowym Vima. Sam możesz wymyśleć inne zastosowania.
Zacznijmy od prostego przykładu: >
:let i = 1
:while i < 5
: echo "liczba to" i
: let i = i + 1
:endwhile
<
Note:
":" nie jest tu naprawdę potrzebny. Dwukropka potrzebujesz tylko kiedy
wpisujesz polecenie. W skryptach Vima można je pominąć. Tutaj będziemy
ich jednak używać, żeby przypomnieć o ich funkcji jako poleceniach
dwukropka i odróżnić od poleceń trybu Normal.
Polecenie ":let" przypisuje wartość do zmiennej. Ogólna forma: >
:let {zmienna} = {wyrażenie}
W tym wypadku nazwą zmiennej jest "i", a wyrażeniem prosta wartość, liczba
jeden.
Polecenie ":while" zaczyna pętlę. Ogólna forma to: >
:while {warunek}
: {wyrażenia}
:endwhile
Wyrażenia przed ":endwhile" są wykonywane tak długo jak warunek jest
prawdziwy. Warunkiem w naszym przykładzie jest wyrażenie "i < 5". Jest ono
prawdziwe dopóki zmienna i jest mniejsza od pięciu.
Polecenie ":echo" wypisuje na ekranie argumenty. W tym wypadku łańcuch
"liczba to" i wartość zmiennej i. Ponieważ i to jeden, napisze:
liczba to 1 ~
Później jest inne polecenie ":let i =". Wartością jest wyrażenie "i + 1".
Dodaje ono jeden do zmiennej i i przypisuje nową wartość do tej samej
zmiennej.
Wynikiem przykładowego kodu jest:
liczba to 1 ~
liczba to 2 ~
liczba to 3 ~
liczba to 4 ~
Note:
Jeśli zdarzy ci się napisać pętlę, która nie chce się skończyć możesz
ją przerwać CTRL-C (CTRL-Break w MS-Windows).
TRZY RODZAJE LICZB
Liczby mogą być dziesiętne, szesnastkowe lub ósemkowe. Liczby szesnastkowe
zaczynają się od "0x" lub "0X" - "0x1f" to 31. Liczba ósemkowa zaczyna się
zera: "017" to 15. Uważaj: nie umieszczaj zera przed liczbą dziesiętną, będzie
zinterpretowana jako liczba ósemkowa!
Polecenie ":echo" zawsze drukuje liczby dziesiętne. Przykład: >
:echo 0x7f 036
< 127 30 ~
Liczba jest ujemna jeśli poprzedza ją znak minus. Działa to również dla liczb
szesnastkowych i ósemkowych. Minus to również znak odejmowania. Porównaj
z powyższym przykładem: >
:echo 0x7f -036
< 97 ~
Znaki odstępu w wyrażeniach są ignorowane. Zaleca się jednak ich stosowanie do
odzielania elementów wyrażenia, żeby kod był bardziej czytelny. Na przykład
żeby uniknąć pomyłki z liczbą ujemną umieść spację między znakiem minus
i następującą po nim liczbą: >
:echo 0x7f - 036
==============================================================================
*41.2* Zmienne
Nazwa zmiennej może składać się z liter ASCII, cyfr i znaków podkreślenie (nie
może zawierać polskich znaków diakrytycznych). Nie może zaczynać się cyfrą.
Prawidłowymi nazwami zmiennych są:
mnoznik
_aap3
bardzo_dluga_nazwa_z_podkresleniami
FuncLength
LENGTH
Błędnymi nazwami są "foo+bar", "6var" oraz "mnożnik".
Zmienne te są globalne. Żeby zobaczyć listę obecnie zdefiniowanych
zmiennych użyj polecenia: >
:let
Zmiennych globalnych możesz używać wszędzie. Oznacza to, że jeśli użyjesz
zmiennej "mnoznik" w jednym pliku skryptowym może być ona użyta również
w innym. W najlepszym wypadku może prowadzić to do pomyłek, w najgorszym do
poważnych problemów. Żeby tego uniknąć użyj zmiennej lokalnej dla skryptu
poprzedzając jej nazwę "s:". Przykład skryptu: >
:let s:mnoznik = 1
:while s:mnoznik < 5
: source inny.vim
: let s:mnoznik = s:mnoznik + 1
:endwhile
Ponieważ "s:mnoznik" jest lokalna dla tego skryptu jesteś pewien, że wczytanie
pliku "inny.vim" nie zmieni tej zmiennej. Jeśli "inny.vim" także używa
"s:mnoznik" będzie ona inną kopią, lokalną dla tego skryptu. Więcej
o zmiennych lokalnych dla skryptu: |script-variable|.
Istnieje więcej typów zmniennych, zobacz |internal-variables|. Najczęściej
używane to:
b:nazwa zmienna lokalna dla bufora
w:nazwa zmienna lokalna dla okna
g:nazwa zmienna globalna (także w funkcji)
v:nazwa zmienna predefiniowana przez Vima
USUWANIE ZMIENNYCH
Zmienne zajmują pamięć i pokazują się w wyniku polecenia ":let". Do ich
usuwania służy polecenie ":unlet": >
:unlet s:mnoznik
Usuwa zmienną lokalną skryptu "s:mnoznik", żeby uwolnić pamięć, którą używa.
Jeśli nie jesteś pewien czy zmienna istnieje, a nie chcesz komunikatu błędu
w wypadku gdyby nie istniała, dodaj !: >
:unlet! s:mnoznik
Kiedy skrypt kończy działanie jego zmienne lokalne nie są automatycznie
usuwane. Następnym razem kiedy skrypt jest wykonywany może użyć starej
wartości. Przykład: >
:if !exists("s:wywolano_mnoznik")
: let s:wywolano_mnoznik = 0
:endif
:let s:wywolano_mnoznik = s:wywolano_mnoznik + 1
:echo "wywołano" s:wywolano_mnoznik "razy"
Funkcja "exists()" sprawdza czy zmienna została już zdefiniowana. Jej
argumentem jest nazwa zmiennej, którą chcesz sprawdzić. Nie sama zmienna!
Gdybyś zrobił coś takiego: >
:if !exists(s:wywolano_mnoznik)
Użyta by została wartość s:wywolano_mnoznik jako nazwa zmiennej do sprawdzenia
przez exists(). Nie dałoby to oczekiwanego rezultatu.
Znak wykrzyknika ! zaprzecza wartości. Jeśli wartość jest prawdziwa,
wyrażenie staje się fałszem. Jeśli jest fałszywe staje się prawdziwe. Możesz
go odczytywać jako "nie". Dlatego "if !exists()" można czytać jako "if not
exists()" (jeśli nie istnieje).
Vim nazywa prawdą wszystko co nie jest równe zero. Tylko zero jest fałszem.
ŁAŃCUCHY I STAŁE
Jak na razie używaliśmy tylko liczb jako wartości zmiennych. Do tego celu
można też użyć łańcuchów. Liczby i łańcuchy to jedyne dwa typy zmiennych jakie
wspiera Vim. Typ jest dynamiczny czyli ustawiany za każdym razem kiedy
przypisuje się zmienną przy pomocy ":let".
Dp przypisania łańcucha do zmiennej musisz użyć stałej łańcuchowej. Są ich
dwa typy. Najpierw łańcuch w podwójnych cudzysłowach: >
:let imie = "piotr"
:echo imie
< piotr ~
Jeśli chcesz włączyć podwójny cudzysłów wewnątrz łańcucha umieść przed nim
backslash: >
:let imie = "\"piotr\""
:echo imie
< "piotr" ~
Aby uniknąć backslasha możesz łańcuch umieścić wewnątrz pojedynczych
cudzysłowów: >
:let imie = '"piotr"'
:echo imie
< "piotr" ~
W łańcuchu umieszczonym wewnątrz pojedynczych cudzysłowów wszystkie znaki są
traktowane dosłownie. Wadą tego rozwiązania jest niemożność włączenia do
łańcucha pojedynczego cudzysłowu. Backslash też jest traktowany dosłownie,
więc nie możesz go użyć do zmiany znaczenia znaku następującego po nim.
Wewnątrz podwójnych cudzysłowów możesz użyć znaków specjalnych. Kilka
najbrdziej użytecznych:
\t <Tab>
\n <NL>, nowa linia
\r <CR>, <Enter>
\e <Esc>
\b <BS>, backspace
\" "
\\ \, backslash
\<Esc> <Esc>
\<C-W> CTRL-W
Dwa ostatnie to tylko przykłady. Formy "\<nazwa>" można użyć do włączenia
specjalnego klawisza.
Pełna lista znaków specjalnych w łańcuchu jest tu: |expr-quote|.
==============================================================================
*41.3* Wyrażenia
Vim posiada bogaty, ale prosty mechanizm wyrażeń. Definicję możesz przeczytać
tu: |expressions-syntax|. Tutaj poznamy tylko podstawy.
Liczby, łańcuchy i zmienne wspomniane wyżej same są wyrażeniami. Dlatego
wszędzie gdzie spodziewane jest wyrażenie możesz użyć liczby, łańcucha lub
zmiennej. Innymi podstawowymi elementami w wyrażeniach są:
$NAZWA zmienna środowiskowa
&nazwa opcja
@r rejestr
Przykłady: >
:echo "Wartość 'tabstop' to" &ts
:echo "Twój katalog domowy to" $HOME
:if @a > 5
Forma &nazwa może zostać użyta do zachowania wartości opcji, ustawienia nowej
wartości, zrobienia czegoś i przywrócenia starej wartości. Przykład: >
:let save_ic = &ic
:set noic
:/Początek/,$delete
:let &ic = save_ic
W ten sposób jesteś pewien, że wzorzec "Początek" jest zastosowany z wyłączoną
opcją 'ignorecase'. Na końcu przywracana jest wartość zastosowana przez
użytkownika.
MATEMATYKA
Wszystko stanie się bardziej interesujące jeśli połączymy podstawowe elementy.
Zacznijmy od matematyki na liczbach:
a + b dodaj
a - b odejmij
a * b pomnóż
a / b podziel
a % b modulo
Zastosowano zwykłe pierwszeństwo operacji. Przykład: >
:echo 10 + 5 * 2
< 20 ~
Grupowanie robi się nawiasami. Żadnych niespodzianek. Przykład: >
:echo (10 + 5) * 2
< 30 ~
Łańcuchy mogą być łączone ".". Przykład: >
:echo "foo" . "bar"
< foobar ~
Kiedy ":echo" dostaje kilka argumentów oddziela je spacją. W przykładzie
argument jest pojedynczym wyrażeniem, więc spacje nie zostały wstawione.
Pożyczono z języka C wyrażenie warunkowe:
a ? b : c
Jeśli "a" okaże się prawdziwe, stosuje się "b", w innym wypadku "c". Przykład:
>
:let i = 4
:echo i > 5 ? "i jest duże" : "i jest małe"
< i is small ~
Wszystkie trzy części konstrukcji są najpierw rozwiązywane, działa to tak jak:
(a) ? (b) : (c)
==============================================================================
*41.4* Warunki (if, elseif, else)
Polecenie ":if" wykonuje kolejne wyrażenia aż do parującego ":endif", ale
tylko jeśli warunek jest prawdziwy. Ogólna forma to:
:if {warunek}
{wyrazenia}
:endif
Dopiero kiedy wyrażenie {warunek} jest prawdziwe (różne od zera) {wyrazenia}
będą wykonane. Muszą to być prawidłowe polecenia. Jeśli będą zawierały śmieci,
Vim nie będzie w stanie znaleźć ":endif".
Możesz też użyć ":else". Ogólna forma jest taka:
:if {warunek}
{wyrazenia}
:else
{wyrazenia}
:endif
Drugie {wyrazenia} wykonywane jest tylko wtedy jeśli pierwsze nie zostały
wykonane.
Na końcu jest ":elseif":
:if {warunek}
{wyrazenia}
:elseif {warunek}
{wyrazenia}
:endif
Działa tak jakby użyć ":else", a potem "if", ale bez potrzeby dla dodatkowego
":endif".
Użyteczny przykład dla twojego vimrc to sprawdzenie opcji 'term'
i zrobienie czegoś na podstawie jej wartości: >
:if &term == "xterm"
: " Zrób coś dla xterma
:elseif &term == "vt100"
: " Zrób coś dla vt100
:else
: " Zrób coś na potrzeby innych terminali
:endif
OPERACJE LOGICZNE
Niektóre już spotkaliśmy w przykładach. Te są najczęściej używane:
a == b równy
a != b nierówny
a > b większy od
a >= b większy od albo równy
a < b mniejszy od
a <= b mniejszy od albo równy
Wynik jest równy jeden jeśli warunek jest spełniony i równy zero w przeciwnym
wypadku. Przykład: >
:if v:version >= 600
: echo "Gratulacje"
:else
: echo "Używasz starej wersji. Upgrade!"
:endif
"v:version" to zmienna zdefiniowana przez Vima, która określa numer wersji
programu. 600 jest dla 6.0. Wersja 6.1 ma wartość 601. Bardzo pożyteczne przy
pisaniu skryptu, który ma działać na różnych wersjach Vima. |v:version|
Operatory logiczne działają zarówno na liczbach jak i łańcuchach. W czasie
porównywania dwóch łańcuchów używa się różnicy matematycznej porównującej
wartości bitowe, które mogą być różne w różnych językach.
Porównując łańcuch i liczbę, łańcuch jest najpierw konwertowany do liczby.
Może to sprawić problemy ponieważ kiedy łańcuch nie wygląda jak liczba Vim
używa 0. Przykład: >
:if 0 == "jeden"
: echo "tak"
:endif
Warunek będzie spełniony ponieważ "jeden" nie wygląda jak liczba, więc
zostanie przekonwertowany na zero.
Dla łańcuchów są dwa dodatkowe operatory:
a =~ b dopasowuje
a !~ b nie dopasowuje
Lewy element, "a", jest użyty jako łańcuch. Prawy, "b", to wzorzec, który
będzie przeszukiwany. Przykład: >
:if str =~ " "
: echo "str zawiera spację"
:elseif str !~ '\.$'
: echo "str kończy się na kropce"
:endif
Zauważ użycie pojedynczych cudzysłowów we wzorcach. Wygodne ponieważ
backslashe muszą być podwojone w łańcuchach wewnątrz podwójnych cudzysłowów
i wzorce potrafią zawierać wiele backslashy.
Opcja 'ignorecase' jest brana pod uwagę w czasie porównywania łańcuchów. Jeśli
tego nie chcesz, dodaj "#", żeby wielość znaków się liczyła i "?", żeby
zostało to zignorowane. Stąd "==?" porównuje dwa łańcuchy nie zwracając uwagi
na wielkość znaków, a "!~#" sprawdza czy wzorzec nie pasuje równocześnie
patrząc na wielkość znaków. Pełna tablica: |expr-==|.
WIĘCEJ O PĘTLACH
Wspomnino już o poleceniu ":while". Można użyj jeszcze dwóch poleceń między
":while" i ":endwhile":
:continue Skocz do początku pętli while; pętla jest
kontynuowana.
:break Skocz do ":endwhile" i zakończ pętlę.
Przykład: >
:while licznik < 40
: call zrob_cos()
: if flaga_kontynuowania
: continue
: endif
: if flaga_konca
: break
: endif
: sleep 50m
:endwhile
Polecenie ":sleep" wprawia Vima w drzemkę. "50m" to pięćdziesiąt milisekund.
Innym przykładem jest ":sleep 4" - czyli drzemka czterosekundowa.
==============================================================================
*41.5* Wykonywanie wyrażeń
Jak na razie polecenia w skrypcie były wykonywane bezpośrednio przez Vima.
Polecenie ":execute pozwala na wykonanie wyniku wyrażenia. Jest to naprawdę
potężne narzędzie do budowania poleceń i wykonywania ich.
Przykładem może być skok do wyrażenia, który zawarty jest w zmiennej: >
:execute "tag " . nazwa_znacznika
"." służy do połączenia łańcucha "tag " z wartością zmiennej
"nazwa_znacznika". Przypuśćmy, że "nazwa_znacznika" ma wartość "get_cmd"
wtedy wykonywane polecenie będzie takie: >
:tag get_cmd
Polecenie ":execute" może wykonać tylko polecenia dwukropka. ":normal"
wykonuje polecenia trybu Normal. Jego argumentami nie są wyrażenia, ale znaki
komend. Przykład: >
:normal gg=G
Skacze do pierwszej linii i formatuje wszystkie linie operatorem "=".
Żeby ":normal" działało z wyrażeniami musisz je połączyć z ":execute".
Przykład: >
:execute "normal " . polecenia_normal
Zmienna "polecenia_normal" musi zawierać komendy trybu Normal.
Upewnij się, że argumentem dla ":normal" jest kompletne polecenie. W innym
wypadku Vim dojdzie do końca argumentu i porzuci go. Na przykład jeśli
zacząłeś tryb Insert musisz go też opuścić: >
:execute "normal Inowy tekst \<Esc>"
Wstawia "nowy tekst " na początku bieżącej linii. Zauważ użycie specjalnego
klawisza "\<Esc>". Unikasz w ten sposób użycia prawdziwego <Esc> w twoim
skrypcie.
==============================================================================
*41.6* Funkcje
Vim definiuje wiele funkcji i zapewnia w ten sposób bardzo dużą
funkcjonalność. W tej sekcji podamy kilka przykładów. Pełną listę znajdziesz
tu: |functions|.
Funkcja jest wywoływana poleceniem ":call". Parametry są podawane w nawiasach,
oddzielane przecinkami. Przykład: >
:call search("Date: ", "W")
Wywołuje funkcję search() z argumentami "Date: " i "W". Funkcja
search() używa pierwszego argumentu jako wzorca poszukiwania i drugiego jako
flag. Flaga "W" oznacza, że poszukiwanie nie ma kontynuować pracy po końcu
pliku (czyli kontynuować od początku).
Funkcja może być wywołana w wyrażeniu. Przykład: >
:let wiersz = getline(".")
:let zmieniony = substitute(wiersz, '\a', "*", "g")
:call setline(".", zmieniony)
Funkcja getline() pobiera linię z bieżącego pliku. Jej argumentem jest numer
linii. W tym wypadku użyto ".", co oznacza linię w której jest kursor.
Funkcja substitute() pełni rolę podobną do polecenia ":substitute".
Pierwszym argumentem jest łańcuch na którym ma być przeprowadzona podmiana.
Drugim wzorzec, trzecim, łańcuch zamieniający. Ostatnim argumentem są flagi.
Funkcja setline() zamienia wiersz, określony pierwszym argumentem na nowy
łańcuch, drugi argument. W tym przykładzie linia pod kursorem jest zamieniana
na wynik substitute(). Efekt tych trzech linijek jest równoznaczny z: >
:substitute/\a/*/g
Użycie funkcji staje się bardziej interesujące kiedy robisz coś więcej przed
i po wywołaniu substitute().
FUNKCJE *lista-funkcji* *function-list*
Jest wiele funkcji. Opiszemy je tu krótko, pogrupowane według tego co robią.
Listę alfabetyczną możesz znaleźć tu: |functions|. Użyj CTRL-] na nazwie
funkcji i skoczysz do jej bardziej szczegółowego opisu.
Manipulowanie łańcuchami:
char2nr() wartość ASCII znaku
nr2char() znak według wartości ASCII
escape() zakomentuj znaki w łańcuchu '\'
strtrans() zmień łańcuch na drukowalny
tolower() zmień łańcuch na małe litery
toupper() zmień łańcuch na wielkie litery
match() poz. gdzie wzorzec jest dopasowany w łańcuchu
matchend() j.w. ale zwraca koniec wzorca
matchstr() dopasuj wzorzec w łańcuchu
stridx() 1 wystąpienie krótkiego łańcucha w długim
strridx() ostatnie wystąpienie kr. łańcucha w długim
strlen() długość łańcucha
substitute() podmień dopasowanie na łańcuch
submatch() zwraca określone dopasowanie w ":substitute"
strpart() zwraca część łańcucha
expand() rozwiń specjalne słowa kluczowe
type() typ zmiennej
iconv() konwersja tekstu do innego kodowania
Działanie na tekście w bieżącym buforze:
byte2line() zwraca numer linii w określonym bajcie pliku
line2byte() zwraca bajt pliku w określonej linii
col() zwraca numer kolumny kursora lub zakładki
virtcol() zwraca numer kolumny ekranowej kursora lub zakładki
line() zwraca numer linii kursora lub zakładki
wincol() zwraca numer kolumny okna
winline() zwraca numer linii okna
cursor() umieszcza kursor w wierszu/kolumnie
getline() pobiera linię z bufora
setline() zamień linię w buforze
append() dodaj {lancuch} poniżej linii {lnum}
indent() zwraca wartość wcięcia linii
cindent() zwraca wartość wcięcia wg formatowania C
lispindent() zwraca wartość wcięcia wg formatowania Lispa
nextnonblank() znajduje pierwszą następną nie pustą linię
prevnonblank() znajduje pierwszą poprzednią nie pustą linię
search() znajduje dopasowanie dla wzorca
searchpair() znajduje drugi koniec zestawu początek/omiń/koniec
Funkcje systemowe i manipulowanie plikami:
browse() wywołaj przeglądarkę plików
glob() rozwiń znaki specjalne
globpath() rozwiń znaki specjalne w nazwach katalogów
resolve() znajdż gdzie wskazuje skrót
fnamemodify() modyfikuj nazwę pliku
executable() sprawdź czy istnieje plik wykonywalny
filereadable() sprawdź czy można odczytać plik
filewritable() sprawdź czy można zapisać do pliku
isdirectory() sprawdź czy istnieje katalog
getcwd() zwraca bieżący katalog
getfsize() zwraca wielkość pliku
getftime() zwraca ostatnią datę modyfikacji pliku
localtime() zwraca bieżący czas
strftime() konwertuje czas do łańcucha
tempname() zwraca nazwę pliku tymczasowego
delete() usuwa plik
rename() zmienia nazwę pliku
system() zwraca rezultat polecenia powłoki
hostname() nazwa systemu
Bufory, okna i lista argumentów:
argc() ilość elementów na liście argumentów
argidx() obecna pozycja na liśćie argumentów
argv() zwraca jeden element z listy argumentów
bufexists() sprawdź czy bufor istnieje
buflisted() sprawdź czy bufor istnieje i jest na liście
bufloaded() sprawdź czy bufor istnieje i jest załadowany
bufname() zwraca nazwę określonego bufora
bufnr() zwraca numer bufora określonego bufora
winnr() zwraca numer okna dla bieżącego okna
bufwinnr() zwraca numer okna dla określonego bufora
winbufnr() zwraca numer bufora dla określonego okna
getbufvar() zwraca wartość zmiennej z określonego bufora
setbufvar() ustawia wartość zmiennej w określonym buforze
getwinvar() zwraca wartość zmiennej w określonym oknie
setwinvar() ustawia wartość zmiennej w określonym oknie
Zwijanie:
foldclosed() sprawdź czy jest zwinięta fałda w danej linii
foldclosedend() j.w. ale zwraca ostatnią linię
foldlevel() sprawdź poziom fałdy w danej linii
foldtext() generuje linię pokazaną jako tytuł zwinięcia
Podświetlanie składni:
hlexists() sprawdź czy istnieje grupa podświetlania
hlID() zwraca ID grupy podświetlania
synID() zwraca ID składni w określonym miejscu
synIDattr() zwraca określony atrybut składniID
synIDtrans() zwraca numer składniID
Historia:
histadd() dodaj element do historii
histdel() usuń element z historii
histget() zwraca element z historii
histnr() zwraca ostatni element z historii
Interaktywne:
confirm() możliwość wyboru
getchar() pobiera znak od użytkownika
getcharmod() zwraca modyfikatory ostatniego wprowadzonego znaku
input() zwraca linię wprowadzoną przez użytkownika
inputsecret() zwraca linię wprowadzoną przez użytkownika
bez pokazywania jej
inputdialog() zwraca linię wprowadzoną przez użytkownika
w oknie dialogowym
inputresave() zapisz i wyczyść "typeahead"
inputresstore() przywróć "typeahead"
Vim serwer:
serverlist() zwraca listę nazw serwerównames
remote_send() wysyła znaki komend do serwera Vima
remote_expr() rozwija wyrażenie na serwerze Vima
server2client() wywysła odpowiedź do klienta serwera Vima
remote_peek() sprawdza czy jest odpowiedź z serwera Vima
remote_read() czyta odpowiedź z serwera Vima
foreground() przenosi okno Vima na pierwszy plan
remote_foreground() przenosi okno serwera Vima na pierwszy plan
Różne:
mode() zwraca bieżący tryb edycji
visualmode() ostatni użyty tryb Visual
hasmapto() sprawdź czy istnieje mapowanie
mapcheck() sprawdź czy istnieje pasujące mapowanie
maparg() zwraca rhs (prawą stronę) mapowania
exists() sprawdż czy zmienna, funkcja, itd. istnieją
has() sprawdż czy opcja jest wspierana przez Vima
cscope_connection() sprawdż czy istnieje połączenie z cscope
did_filetype() sprawdź czy użyto autokomendy i FileType
eventhandler() sprawdź czy wywołane przez zdarzenie
getwinposx() pozycja X okna GUI Vima
getwinposy() pozycja Y okna GUI Vima
winheight() zwraca wysokość określonego okna
winwidth() zwraca szerokość określonego okna
libcall() wywołaj funkcję w zewnętrznej bibliotece
libcallnr() j.w., zwraca liczbę
getreg() zwraca zawartość rejestru
getregtype() zwraca typ rejestru
setreg() ustawia zawartość rejestru
==============================================================================
*41.7* Definiowanie funkcji
Vim pozwala na definiowanie własnych funkcji. Podstawowa deklaracja funkcji
to: >
:function {nazwa}({var1}, {var2}, ...)
: {cialo}
:endfunction
<
Note:
Nazwy funkcji muszą zaczynać się wielką literą.
Nazwy funkcji nie mogą zawierać polskich znaków diakrytycznych.
Napiszmy krótką funkcję, które będzie zwracać mniejszą z dwóch liczb. Zaczyna
się taką linią: >
:function Min(num1, num2)
Mówi ona Vimowi, że funkcja nazywa się "Min" i pobiera dwa argumenty: "num1"
i "num2".
Pierwszą rzeczą jakiej potrzebujesz jest sprawdzenie która z liczb jest
mniejsza: >
: if a:num1 < a:num2
Specjalny prefiks "a:" oznacza, że zmienna jest argumentem funkcji. Przypiszmy
zmiennej "mniejsza" wartość mniejszej liczby: >
: if a:num1 < a:num2
: let mniejsza = a:num1
: else
: let mniejsza = a:num2
: endif
Zmienna "mniejsza" jest zmienną lokalną. Zmienne użyte wewnątrz funkcji są
lokalne dopóki nie zostaną poprzedzone "g:", "a:" lub "s:".
Note:
Żeby dotrzeć do zmiennej globalnej z wnętrza funkcji musisz poprzedzić
jej nazwę "g:". Dlatego "g:mnoznik" wewnątrz funkcji odnosi się do
zmiennej globalnej "mnoznik", a "mnoznik" jest inną zmienną, lokalną
dla funkcji.
Operator ":return" służy do zwrócenia mniejszej liczby użytkownikowi. Funkcję
kończysz: >
: return mniejsza
:endfunction
Kompletna definicja funkcji: >
:function Min(num1, num2)
: if a:num1 < a:num2
: let mniejsza = a:num1
: else
: let mniejsza = a:num2
: endif
: return mniejsza
:endfunction
Funkcje zdefiniowane przez użytkownika wywoływane są w ten sam sposób co
wbudowane. Tylko nazwa jest inna. Funkcja Min może być użyta tak: >
:echo Min(5, 8)
Tylko teraz funkcja zostanie wykonana a jej linie zinterpretowane przez Vima.
Jeśli są tam błędy, takie jak użycie niezdefiniowanej zmiennej lub funkcji
otrzymasz komunikat błędu. W czasie definiowania funkcji takie błędy nie są
wykrywane.
Kiedy funkcja osiąga ":endfunction" lub ":return" użyte jest bez argumentu,
funkcja zwraca zero.
Do redefiniowania funkcji, która już istnieje dodaj ! do polecenia
":function": >
:function! Min(num1, num2, num3)
ZASIĘG
Poleceniu ":call" można przekazać zasięg. Może to oznaczać dwie rzeczy. Kiedy
funkcja jest zdefiniowana ze słowem kluczowym "range" sama zadba o zasięg.
Funkcja dostanie dodatkowo zmienne "a:firstline" i "a:lastline". Oznaczają
one numery linii z zasięgu, z którym funkcja została wywołana. Przykład: >
:function Policz_slowa() range
: let n = a:firstline
: let liczba = 0
: while n <= a:lastline
: let liczba = liczba + Licznikslow(getline(n))
: let n = n + 1
: endwhile
: echo "znaleziono " . liczba . " słów"
:endfunction
Możesz wywołać funkcję tak: >
:10,30call Policz_slowa()
Zostanie wykonana raz i wyświetli liczbę słów.
Innym sposobem jest użycie zasięgu bez definiowania funkcji ze słowem
"range". Funkcja zostanie wywołana raz dla każdej linii w zasięgu, z kursorem
na tej linii. Przykład: >
:function Numer()
: echo "linia " . line(".") . " zawiera: " . getline(".")
:endfunction
Jeśli wywołasz funkcję tak: >
:10,15call Numer()
Zostanie ona wywołana sześć razy.
ZMIENNA LICZBA ARGUMENTÓW
Vim pozwala na zdefiniowanie funkcji, która ma zmienną liczbę argumentów.
Natępujące polecenie definiuje funkcję, która musi mieć 1 argument (start)
i do 20 dodatkowych argumentów: >
:function Show(start, ...)
Zmienna "a:1" zawiera pierwszy opcjonalny argument, "a:2" drugi, i tak dalej.
Zmienna "a:0" zawiera liczbę dodatkowych argumentów. >
: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
Przykład ten zawiera polecenie ":echohl" do określenia podświetlania użytego
do następującego po nim polecenia ":echo". ":echohl None" znów to wstrzymuje.
Polecenie ":echon" działa jak ":echo", ale nie produkuje znaku końca linii.
LISTOWANIE FUNKCJI
Polecenie ":function" listuje nazwy i argumenty wszystkich funkcji
zdefiniowanych przez użytkownika: >
:function
< function Show(start, ...) ~
function GetVimIndent() ~
function SetSyn(name) ~
Żeby zobaczyć co dana funkcja robi użyj jej nazwy jako argumentu ":function":
>
:function SetSyn
< 1 if &syntax == '' ~
2 let &syntax = a:name ~
3 endif ~
endfunction ~
DEBUGOWANIE
Numer linii jest użyteczny kiedy dostajesz komunikat błędu lub w czasie
debugowania. Zobacz |debug-scripts| o trybie debugowania.
Możesz też ustawić opcję 'verbose' na 12 lub wyżej, żeby zobaczyć wszystkie
wywołania funkcji. Ustaw na 15 lub wyżej i zobaczysz wszystkie wykonywane
linie.
USUWANIE FUNKCJI
Żeby usunąć funkcję Show(): >
:delfunction Show
Otrzymasz komunikat o błędzie jeśli funkcja nie istnieje.
==============================================================================
*41.8* Wyjątki
Zacznijmy od przykładu: >
:try
: read ~/templates/pascal.tmpl
:catch /E484:/
: echo "Przykro mi, nie mogę znaleźć szablonu pliku Pascala."
:endtry
Polecenie ":read" zawiedzie jeśli plik nie istnieje. Zamiast pokazania
komunikatu błędu kod przechwyci błąd i pokaże użytkownikowi bardziej
szczegółową informację.
Dla poleceń między ":try" i ":endtry" błędy są zamienione w wyjątki - łańcuchy
znaków. W przypadku błędu, łańcuch zawiera komunikat błędu. Każdy błąd posiada
numer. W tym wypadku łańcuch, który przechwyciliśmy zawiera "E484:". Numer
nigdy się nie zmieni (tekst tak, na przykład może zostać przetłumaczony).
Kiedy polecenie ":read" spowoduje inny błąd, wzorzec "E484:" nie będzie
pasować. Wtedy wyjątek nie zostanie przechwycony i rezultatem będzie zwykły
komunikat błędu.
Być może będziesz chciał spróbować: >
:try
: read ~/templates/pascal.tmpl
:catch
: echo "Przykro mi, nie mogę znaleźć szablonu pliku Pascala."
:endtry
W ten sposób wszystkie błędy zostaną przechwycone, ale nie zobaczysz
komunikatów, które mogłyby być pomocne, np.: "E21: Cannot make changes,
'modifiable' is off".
Innym pożytecznym mechanizmem jest polecenie ":finally": >
:let tmp = tempname()
:try
: exe ".,$write " . tmp
: exe "!filtr " . tmp
: .,$delete
: exe "$read " . tmp
:finally
: call delete(tmp)
:endtry
Filtruje linie od kursora do końca pliku przez komendę "filtr", która pobiera
nazwę pliku jako argument. Nie ma znacznia jak to działa, jeśli coś pójdzie
źle między ":try" i ":finally" lub użytkownik odwoła filtrowanie wciskając
CTRL-C, zawsze wykonywane jest "call delete(tmp)". W ten sposób jesteś pewien,
że nie zostawisz tymczasowego pliku.
Więcej informacji o wyjątkach znajdziesz w Przewodniku Encyklopedycznym:
|exception-handling|.
==============================================================================
*41.9* Różne uwagi
Podsumowanie elementów, które odnoszą się do skryptów Vima. Są wspomniane też
gdzie indziej, ale tutaj zostaną ładnie opisane.
Znak końca linii zależy od systemu. Dla Uniksa <NL>, dla MS-DOS, Windows, OS/2
i podobnych <CR><LF>. Ważne by o tym pamiętać używając mapowań zawierających
<CR>. Zobacz |:source_crnl|.
BIAŁE ZNAKI
Białe linie są dozwolone i ignorowane.
Białe znaki na początku linii (spacje i tabulacje) są zawsze ignorowane. Białe
znaki pomiędzy parametrami (np. pomiędzy 'set' i 'cpoptions' w poniższym
przykładzie) są redukowane do jednego znaku odstępu i odgrywają rolę
separatora, białe znaki po ostatnim (widocznym) znaku są, albo nie są
ignorowane w zależności od sytuacji.
W poleceniu ":set" zawierającym znak "=" (równy): >
:set cpoptions =aABceFst
Białe znaki bezpośrednio przed znakiem "=" są ignorowane. Ale nie może być
odstępu po "="!
Żeby można było włączyć biały znak w wartość opcji musi być on poprzedzony
"\" (backslashem) tak jak w przykładzie: >
:set tags=mój\ ładny\ plik
Ten sam przykład napisany tak >
:set tags=mój ładny plik
spowoduje komunikat błędu ponieważ zostanie zinterpretowany jako: >
:set tags=mój
:set ładny
:set file
KOMENTARZE
Znak " (podwójny cudzysłów) zaczyna komentarz. Wszystko po nim (włączając sam
znak) aż do końca linii uważane jest za komentarz i ignorowane z wyjątkiem
poleceń, które nie zwracają uwagi na komentarze i są wyjaśnione poniżej.
Komentarz może się zacząć w dowolnym miejscu linii.
Jest mały haczyk z komentarzami w niektórych poleceniach. Przykłady: >
:abbrev dev development " skrót
:map <F3> o#include " wstaw include
:execute cmd " zrób to
:!ls *.c " lista plików C
Skrót 'dev' będzie rozwiązany do 'development " skrót'. Mapowanie <F3>
będzie uwzględiało cało linię po 'o# ...' włączając '" wstaw include'.
Polecenie "execute" spowoduje błąd. Polecenie "!" wyśle wszysko po nim do
powłoki powodując błąd dla niesparowanego znaku '"'.
Nie może być komentarzy po polecenieach ":map", ":abbreviate", ":execute"
i "!" (jest jeszcze kilka z tym ograniczeniem). Dla poleceń ":map",
":abbreviate" i ":execute" jest mały trik: >
:abbrev dev development|" skrót
:map <F3> o#include|" wstaw include
:execute cmd |" zrób to
Znak '|' oddziela jedno polecenie od następnego, a następnym poleceniem jest
tylko komentarz.
Zauważ, że nie ma białych znaków przed '|' w skrótach i mapowaniach. Dla tych
poleceń każdy znak aż do końca linii lub '|' jest włączany. W konsekwencji
takiego zachowania nie zawsze zobaczysz włączane zbędne spacje: >
:map <F4> o#include
Dla uniknięcia takich problemów możesz ustwić opcję 'list' w czasie edycji
plików vimrc.
PUŁAPKI