OSDN Git Service

Regular updates
[twpd/master.git] / vimscript.md
1 ---
2 title: Vim scripting
3 category: Vim
4 prism_languages: [vim]
5 layout: 2017/sheet
6 updated: 2020-07-05
7 weight: -10
8 tags: [Featurable]
9 ---
10
11 ### Start hacking
12
13 ```vim
14 let name = "John"
15 echo "Hello, " . name
16 ```
17
18 You can either put this in a script (`script.vim`) and run it (`:source script.vim`), or you can type the commands individually in normal mode as `:let` and `:echo`.
19
20 ### Learn by example
21
22 ```vim
23 function! SuperTab()
24   let l:part = strpart(getline('.'),col('.')-2,1)
25   if (l:part =~ '^\W\?$')
26       return "\<Tab>"
27   else
28       return "\<C-n>"
29   endif
30 endfunction
31
32 imap <Tab> <C-R>=SuperTab()<CR>
33 ```
34
35 [Here](http://www.vimbits.com/bits/46)'s another example with [functions](#functions), [variables](#variables) and [mapping](#mapping).
36
37 Variables
38 ---------
39
40 ### Defining
41 {: .-prime}
42
43 ```vim
44 let var = "hello"
45 ```
46
47 ### Variable prefixes
48
49 ```vim
50 let g:ack_options = '-s -H'    " g: global
51 let s:ack_program = 'ack'      " s: local (to script)
52 let l:foo = 'bar'              " l: local (to function)
53 ```
54
55 The `s:` prefix is also available in function names. See `:help local-variables`
56
57 ### Other prefixes
58
59 ```vim
60 let w:foo = 'bar'    " w: window
61 let b:state = 'on'   " b: buffer
62 let t:state = 'off'  " t: tab
63 echo v:var           " v: vim special
64 ```
65
66 ```vim
67 let @/ = ''          " @  register (this clears last search pattern)
68 echo $PATH           " $  env
69 ```
70
71 ### Vim options
72
73 ```vim
74 echo 'tabstop is ' . &tabstop
75 if &insertmode
76 echo &g:option
77 echo &l:option
78 ```
79
80 Prefix Vim options with `&`
81
82 ### Operators
83
84 ```vim
85 a + b             " numbers only!
86 'hello ' . name   " concat
87 ```
88
89 ```vim
90 let var -= 2
91 let var += 5
92 let var .= 'string'   " concat
93 ```
94
95 ## Strings
96
97 ### Strings
98
99 ```vim
100 let str = "String"
101 let str = "String with \n newline"
102
103 let literal = 'literal, no \ escaping'
104 let literal = 'that''s enough'  " double '' => '
105
106 echo "result = " . re   " concatenation
107 ```
108
109 Also see `:help literal-string` and `:help expr-quote`.
110 See: [Strings](http://learnvimscriptthehardway.stevelosh.com/chapters/26.html)
111
112 ### String functions
113
114 ```vim
115 strlen(str)    " length
116 len(str)       " same
117 strchars(str)  " character length
118
119 split("one two three")       "=> ['one', 'two', 'three']
120 split("one.two.three", '.')  "=> ['one', 'two', 'three']
121
122 join(['a', 'b'], ',')  "=> 'a,b'
123
124 tolower('Hello')
125 toupper('Hello')
126 ```
127
128 Also see `:help functions`
129 See: [String functions](http://learnvimscriptthehardway.stevelosh.com/chapters/27.html)
130
131 Functions
132 ---------
133
134 ### Functions
135 {: .-prime}
136
137 ```vim
138 " prefix with s: for local script-only functions
139 function! s:Initialize(cmd, args)
140   " a: prefix for arguments
141   echo "Command: " . a:cmd
142
143   return 1
144 endfunction
145 ```
146
147 See: [Functions](http://learnvimscriptthehardway.stevelosh.com/chapters/23.html)
148
149 ### Overwriting
150 ```vim
151 function f1()
152   echo "f1"
153 endfunction
154
155
156 function! f1()
157   echo "f1 overridden"
158 endfunction
159 ```
160
161 If you define two functions with the same name, Vim will throw an error complaining that the function `f1` already exists. To overwrite the previous function with the same name, add a `!` after the function keyword.
162
163 ### Namespacing
164
165 ```vim
166 function! myplugin#hello()
167 ```
168
169 ### Calling functions
170
171 ```vim
172 call s:Initialize()
173 call s:Initialize("hello")
174 ```
175
176 ### Consuming return values
177
178 ```vim
179 echo "Result: " . s:Initialize()
180 ```
181
182 ### Abortable
183
184 ```vim
185 function! myfunction() abort
186 endfunction
187 ```
188
189 Aborts when an error occurs.
190
191 ### Var arguments
192
193 ```vim
194 function! infect(...)
195   echo a:0    "=> 2
196   echo a:1    "=> jake
197   echo a:2    "=> bella
198
199   for s in a:000  " a list
200     echon ' ' . s
201   endfor
202 endfunction
203
204 infect('jake', 'bella')
205 ```
206
207 See `:help function-argument`.  See: [Var arguments](http://learnvimscriptthehardway.stevelosh.com/chapters/24.html)
208
209 Loops
210 -----
211
212 ```vim
213 for s in list
214   echo s
215   continue  " jump to start of loop
216   break     " breaks out of a loop
217 endfor
218 ```
219
220 ```vim
221 while x < 5
222 endwhile
223 ```
224
225 Custom commands
226 ---------------
227
228 ### Custom commands
229 {: .-prime}
230
231 ```vim
232 command! Save :set fo=want tw=80 nowrap
233 ```
234
235 Custom commands start with uppercase letters. The `!` redefines a command if it already exists.
236
237 ### Commands calling functions
238
239 ```vim
240 command! Save call <SID>foo()
241 ```
242 {: .-setup}
243
244 ```vim
245 function! s:foo()
246   ...
247 endfunction
248 ```
249
250 ### Commands with arguments
251
252 ```vim
253 command! -nargs=? Save call script#foo(<args>)
254 ```
255 {: .-setup}
256
257 | What | What |
258 | ---- | ---- |
259 | `-nargs=0` | 0 arguments, default |
260 | `-nargs=1` | 1 argument, includes spaces |
261 | `-nargs=?` | 0 or 1 argument |
262 | `-nargs=*` | 0+ arguments, space separated |
263 | `-nargs=+` | 1+ arguments, space reparated |
264
265 Flow
266 ----
267
268 ### Conditionals
269
270 ```vim
271 let char = getchar()
272 if char == "\<LeftMouse>"
273   " ...
274 elseif char == "\<RightMouse>"
275   " ...
276 else
277   " ...
278 endif
279 ```
280
281 ### Truthiness
282
283 ```vim
284 if 1 | echo "true"  | endif
285 if 0 | echo "false" | endif
286 ```
287
288 ```vim
289 if 1       "=> 1 (true)
290 if 0       "=> 0 (false)
291 if "1"     "=> 1 (true)
292 if "456"   "=> 1 (true)
293 if "xfz"   "=> 0 (false)
294 ```
295
296 No booleans. `0` is false, `1` is true.
297 See: [Truthiness](http://learnvimscriptthehardway.stevelosh.com/chapters/21.html)
298
299 ### Operators
300
301 ```vim
302 if 3 > 2
303 if a && b
304 if (a && b) || (c && d)
305 if !c
306 ```
307
308 See `:help expression-syntax`.
309 See: [Operators](http://learnvimscriptthehardway.stevelosh.com/chapters/22.html)
310
311 ### Strings
312
313 ```vim
314 if name ==# 'John'     " case-sensitive
315 if name ==? 'John'     " case-insensitive
316 if name == 'John'      " depends on :set ignorecase
317
318 " also: is#, is?, >=#, >=?, and so on
319 ```
320
321 ### Identity operators
322
323 ```vim
324 a is b
325 a isnot b
326 ```
327
328 Checks if it's the same instance object.
329
330 ### Regexp matches
331
332 ```vim
333 "hello" =~ 'xx*'
334 "hello" !~ 'xx*'
335 "hello" =~ '\v<\d+>'
336 ```
337
338 `\v` enables "extended" regex mode which allows word boundary (`<>`), `+`, and more.
339
340 ### Single line
341
342 ```vim
343 if empty(a:path) | return [] | endif
344 a ? b : c
345 ```
346
347 Use `|` to join lines together.
348
349 ### Boolean logic
350
351 ```vim
352 if g:use_dispatch && s:has_dispatch
353   ···
354 endif
355 ```
356
357 Lists
358 -----
359
360 ### Lists
361
362 ```vim
363 let mylist = [1, two, 3, "four"]
364
365 let first = mylist[0]
366 let last  = mylist[-1]
367
368 " Suppresses errors
369 let second = get(mylist, 1)
370 let second = get(mylist, 1, "NONE")
371 ```
372
373 ### Functions
374
375 ```vim
376 len(mylist)
377 empty(mylist)
378
379 sort(list)
380 let sortedlist = sort(copy(list))
381
382 split('hello there world', ' ')
383 ```
384
385 ### Concatenation
386
387 ```vim
388 let longlist = mylist + [5, 6]
389 let mylist += [7, 8]
390 ```
391
392 ### Sublists
393
394 ```vim
395 let shortlist = mylist[2:-1]
396 let shortlist = mylist[2:]     " same
397
398 let shortlist = mylist[2:2]    " one item
399 ```
400
401 ### Push
402
403 ```vim
404 let alist = [1, 2, 3]
405 let alist = add(alist, 4)
406 ```
407
408 ### Map
409
410 ```vim
411 call map(files, "bufname(v:val)")  " use v:val for value
412 call filter(files, 'v:val != ""')
413 ```
414
415 Dictionaries
416 ------------
417
418 ### Dictionaries
419
420 ```vim
421 let colors = {
422   \ "apple": "red",
423   \ "banana": "yellow"
424 }
425
426 echo colors["a"]
427 echo get(colors, "apple")   " suppress error
428 ```
429
430 See `:help dict`
431
432 ### Using dictionaries
433
434 ```vim
435 remove(colors, "apple")
436 ```
437
438 ```vim
439 " :help E715
440 if has_key(dict, 'foo')
441 if empty(dict)
442 keys(dict)
443 len(dict)
444 ```
445
446 ```vim
447 max(dict)
448 min(dict)
449 ```
450
451 ```vim
452 count(dict, 'x')
453 string(dict)
454 ```
455
456 ```vim
457 map(dict, '<>> " . v:val')
458 ```
459
460 ### Iteration
461
462 ```vim
463 for key in keys(mydict)
464   echo key . ': ' . mydict[key]
465 endfor
466 ```
467
468 ### Prefixes
469
470 ```vim
471 keys(s:)
472 ```
473
474 Prefixes (`s:`, `g:`, `l:`, etc) are actually dictionaries.
475
476 ### Extending
477
478 ```vim
479 " Extending with more
480 let extend(s:fruits, { ... })
481 ```
482
483 Casting
484 -------
485
486 ```vim
487 str2float("2.3")
488 str2nr("3")
489 float2nr("3.14")
490 ```
491
492 Numbers
493 -------
494
495 ### Numbers
496 {: .-prime}
497
498 ```vim
499 let int = 1000
500 let int = 0xff
501 let int = 0755   " octal
502 ```
503
504 See `:help Number`.
505 See: [Numbers](http://learnvimscriptthehardway.stevelosh.com/chapters/25.html)
506
507 ### Floats
508
509 ```vim
510 let fl = 100.1
511 let fl = 5.4e4
512 ```
513
514 See `:help Float`
515
516 ### Arithmetic
517
518 ```vim
519 3 / 2     "=> 1, integer division
520 3 / 2.0   "=> 1.5
521 3 * 2.0   "=> 6.0
522 ```
523
524 ### Math functions
525
526 ```vim
527 sqrt(100)
528 floor(3.5)
529 ceil(3.3)
530 abs(-3.4)
531
532 sin() cos() tan()
533 sinh() cosh() tanh()
534 asin() acos() atan()
535 ```
536
537 Vim-isms
538 --------
539
540 ### Execute a command
541
542 ```vim
543 execute "vsplit"
544 execute "e " . fnameescape(filename)
545 ```
546
547 Runs an ex command you typically run with `:`. Also see `:help execute`.
548 See: [Execute a command](http://learnvimscriptthehardway.stevelosh.com/chapters/28.html)
549
550 ### Running keystrokes
551
552 ```vim
553 normal G
554 normal! G   " skips key mappings
555
556 execute "normal! gg/foo\<cr>dd"
557 ```
558
559 Use `:normal` to execute keystrokes as if you're typing them in normal mode. Combine with `:execute` for special keystrokes.
560 See: [Running keystrokes](http://learnvimscriptthehardway.stevelosh.com/chapters/29.html)
561
562 ### Getting filenames
563
564 ```vim
565 echo expand("%")      " path/file.txt
566 echo expand("%:t")    " file.txt
567 echo expand("%:p:h")  " /home/you/path/file.txt
568 echo expand("%:r")    " path/file
569 echo expand("%:e")    " txt
570 ```
571
572 See `:help expand`
573
574 ### Silencing
575
576 ```vim
577 silent g/Aap/p
578 ```
579
580 Suppresses output. See `:help silent`
581
582 ### Echo
583
584 ```vim
585 echoerr 'oh it failed'
586 echomsg 'hello there'
587 echo 'hello'
588
589 echohl WarningMsg | echomsg "=> " . a:msg | echohl None
590 ```
591
592
593 ### Settings
594
595 ```vim
596 set number
597 set nonumber
598 set number!     " toggle
599 set numberwidth=5
600 set guioptions+=e
601 ```
602
603 ### Prompts
604
605 ```vim
606 let result = confirm("Sure?")
607 execute "confirm q"
608 ```
609
610 ### Built-ins
611
612 ```vim
613 has("feature")  " :h feature-list
614 executable("python")
615 globpath(&rtp, "syntax/c.vim")
616
617 exists("$ENV")
618 exists(":command")
619 exists("variable")
620 exists("+option")
621 exists("g:...")
622 ```
623
624 Mapping
625 -------
626 {: .-three-column}
627
628 ### Mapping commands
629
630 ```vim
631 nmap
632 vmap
633 imap
634 xmap
635 nnoremap
636 vnoremap
637 inoremap
638 xnoremap
639 ...
640 ```
641
642 ### Explanation
643
644 ```vim
645 [nvixso](nore)map
646 ```
647
648 ```
649  │       └ don't recurse
650  │
651  └ normal, visual, insert,
652    eX mode, select, operator-pending
653 ```
654 {: .-setup}
655
656 ### Arguments
657
658 | `<buffer>` | only in current buffer |
659 | `<silent>` | no echo |
660 | `<nowait>` | |
661
662 Syntax
663 ------
664
665 ### Highlights
666
667 ```vim
668 hi Comment
669   term=bold,underline
670   gui=bold
671   ctermfg=4
672   guifg=#80a0ff
673 ```
674
675 ### Filetype detection
676
677 ```vim
678 augroup filetypedetect
679   au! BufNewFile,BufRead *.json setf javascript
680 augroup END
681
682 au Filetype markdown setlocal spell
683 ```
684
685 ### Conceal
686
687 ```vim
688 set conceallevel=2
689 syn match newLine "<br>" conceal cchar=}
690 hi newLine guifg=green
691 ```
692
693 ### Region conceal
694
695 ```vim
696 syn region inBold concealends matchgroup=bTag start="<b>" end="</b>"
697 hi inBold gui=bold
698 hi bTag guifg=blue
699 ```
700
701 ### Syntax
702
703 ```vim
704 syn match :name ":regex" :flags
705
706 syn region Comment  start="/\*"  end="\*/"
707 syn region String   start=+"+    end=+"+         skip=+\\"+
708
709 syn cluster :name contains=:n1,:n2,:n3...
710
711 flags:
712   keepend
713   oneline
714   nextgroup=
715   contains=
716   contained
717
718 hi def link markdownH1 htmlH1
719 ```
720
721 ### Include guards
722
723 ```vim
724 if exists('g:loaded_myplugin')
725   finish
726 endif
727
728 " ...
729
730 let g:loaded_myplugin = 1
731 ```