cheatsheets/vimscript.md

731 lines
10 KiB
Markdown
Raw Permalink Normal View History

2015-01-16 04:02:16 +00:00
---
2017-08-30 10:43:36 +00:00
title: Vim scripting
2015-11-24 04:48:01 +00:00
category: Vim
2017-08-30 10:43:36 +00:00
prism_languages: [vim]
2020-07-05 11:11:36 +00:00
updated: 2020-07-05
2017-08-30 10:43:36 +00:00
weight: -10
tags: [Featurable]
2015-01-16 04:02:16 +00:00
---
2017-08-30 10:43:36 +00:00
### Start hacking
2015-04-17 11:12:59 +00:00
2015-04-16 16:23:18 +00:00
```vim
let name = "John"
echo "Hello, " . name
```
2017-08-30 10:43:36 +00:00
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`.
2015-04-16 16:23:18 +00:00
2015-04-17 11:12:59 +00:00
### Learn by example
```vim
function! SuperTab()
let l:part = strpart(getline('.'),col('.')-2,1)
if (l:part =~ '^\W\?$')
2015-04-17 11:12:59 +00:00
return "\<Tab>"
else
return "\<C-n>"
endif
endfunction
imap <Tab> <C-R>=SuperTab()<CR>
```
2015-04-16 16:32:22 +00:00
2017-08-30 10:43:36 +00:00
[Here](http://www.vimbits.com/bits/46)'s another example with [functions](#functions), [variables](#variables) and [mapping](#mapping).
2015-04-16 15:02:00 +00:00
Variables
---------
2015-01-16 04:02:16 +00:00
2017-08-30 10:43:36 +00:00
### Defining
{: .-prime}
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
let var = "hello"
```
2015-01-16 04:02:16 +00:00
2015-04-16 15:02:00 +00:00
### Variable prefixes
2015-01-16 04:02:16 +00:00
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
let g:ack_options = '-s -H' " g: global
2015-04-16 15:29:23 +00:00
let s:ack_program = 'ack' " s: local (to script)
let l:foo = 'bar' " l: local (to function)
```
2017-08-30 10:43:36 +00:00
The `s:` prefix is also available in function names. See `:help local-variables`
2015-04-16 15:29:23 +00:00
### Other prefixes
```vim
2017-08-30 10:43:36 +00:00
let w:foo = 'bar' " w: window
let b:state = 'on' " b: buffer
let t:state = 'off' " t: tab
echo v:var " v: vim special
```
2015-01-16 04:02:16 +00:00
2017-08-30 10:43:36 +00:00
```vim
let @/ = '' " @ register (this clears last search pattern)
echo $PATH " $ env
2015-04-16 15:02:00 +00:00
```
2015-01-16 04:02:16 +00:00
2015-04-16 15:02:00 +00:00
### Vim options
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:06:32 +00:00
echo 'tabstop is ' . &tabstop
2015-04-16 15:02:00 +00:00
if &insertmode
echo &g:option
echo &l:option
```
2017-08-30 10:43:36 +00:00
Prefix Vim options with `&`
2015-04-16 15:40:46 +00:00
### Operators
```vim
a + b " numbers only!
'hello ' . name " concat
```
2015-01-16 04:02:16 +00:00
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
let var -= 2
let var += 5
2015-04-16 15:06:32 +00:00
let var .= 'string' " concat
2015-04-16 15:02:00 +00:00
```
2017-08-30 10:43:36 +00:00
## Strings
2015-04-16 16:17:53 +00:00
2017-08-30 10:43:36 +00:00
### Strings
2015-04-16 15:02:00 +00:00
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
let str = "String"
let str = "String with \n newline"
let literal = 'literal, no \ escaping'
2015-04-16 16:23:18 +00:00
let literal = 'that''s enough' " double '' => '
2015-04-16 15:02:00 +00:00
echo "result = " . re " concatenation
```
2017-08-30 10:43:36 +00:00
Also see `:help literal-string` and `:help expr-quote`.
See: [Strings](http://learnvimscriptthehardway.stevelosh.com/chapters/26.html)
### String functions
2015-04-16 15:40:46 +00:00
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
strlen(str) " length
2015-04-16 15:40:46 +00:00
len(str) " same
2015-04-16 15:02:00 +00:00
strchars(str) " character length
2015-04-16 15:40:46 +00:00
split("one two three") "=> ['one', 'two', 'three']
split("one.two.three", '.') "=> ['one', 'two', 'three']
join(['a', 'b'], ',') "=> 'a,b'
tolower('Hello')
toupper('Hello')
2015-04-16 15:02:00 +00:00
```
2015-01-16 04:02:16 +00:00
2017-08-30 10:43:36 +00:00
Also see `:help functions`
2017-10-01 19:19:50 +00:00
See: [String functions](http://learnvimscriptthehardway.stevelosh.com/chapters/27.html)
2017-08-30 10:43:36 +00:00
Functions
2015-01-16 04:02:16 +00:00
---------
2017-08-30 10:43:36 +00:00
### Functions
{: .-prime}
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
" prefix with s: for local script-only functions
function! s:Initialize(cmd, args)
" a: prefix for arguments
echo "Command: " . a:cmd
return 1
2015-04-16 15:02:00 +00:00
endfunction
```
2017-08-30 10:43:36 +00:00
See: [Functions](http://learnvimscriptthehardway.stevelosh.com/chapters/23.html)
2015-04-16 15:02:00 +00:00
### Overwriting
```vim
function f1()
echo "f1"
endfunction
function! f1()
echo "f1 overridden"
endfunction
```
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.
2015-04-16 15:06:32 +00:00
### Namespacing
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:06:32 +00:00
function! myplugin#hello()
```
2015-04-16 15:02:00 +00:00
### Calling functions
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
call s:Initialize()
call s:Initialize("hello")
```
2015-04-16 15:29:43 +00:00
### Consuming return values
2015-04-16 15:02:00 +00:00
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
echo "Result: " . s:Initialize()
```
2015-04-16 15:06:32 +00:00
### Abortable
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:06:32 +00:00
function! myfunction() abort
endfunction
```
2017-08-31 16:30:51 +00:00
Aborts when an error occurs.
2017-08-30 10:43:36 +00:00
### Var arguments
2015-04-16 15:06:32 +00:00
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:06:32 +00:00
function! infect(...)
2015-04-16 16:17:53 +00:00
echo a:0 "=> 2
echo a:1 "=> jake
echo a:2 "=> bella
for s in a:000 " a list
echon ' ' . s
endfor
2015-04-16 15:06:32 +00:00
endfunction
2015-04-16 16:17:53 +00:00
infect('jake', 'bella')
```
2017-08-30 10:43:36 +00:00
See `:help function-argument`. See: [Var arguments](http://learnvimscriptthehardway.stevelosh.com/chapters/24.html)
2015-04-16 16:17:53 +00:00
Loops
-----
```vim
for s in list
echo s
continue " jump to start of loop
break " breaks out of a loop
endfor
2015-04-17 11:13:57 +00:00
```
2015-04-16 16:17:53 +00:00
2015-04-17 11:13:57 +00:00
```vim
2015-04-16 16:17:53 +00:00
while x < 5
endwhile
2015-04-16 15:06:32 +00:00
```
2015-04-16 15:21:37 +00:00
Custom commands
---------------
2017-08-30 10:43:36 +00:00
### Custom commands
{: .-prime}
2015-04-16 15:21:37 +00:00
```vim
command! Save :set fo=want tw=80 nowrap
```
2017-08-30 10:43:36 +00:00
Custom commands start with uppercase letters. The `!` redefines a command if it already exists.
2015-04-16 15:21:37 +00:00
### Commands calling functions
2015-04-16 15:02:00 +00:00
2015-04-16 15:10:17 +00:00
```vim
2017-09-09 09:42:32 +00:00
command! Save call <SID>foo()
2017-08-31 16:30:51 +00:00
```
2017-08-31 18:05:08 +00:00
{: .-setup}
2017-08-31 16:30:51 +00:00
```vim
2017-09-09 09:42:32 +00:00
function! s:foo()
2015-04-16 15:21:37 +00:00
...
endfunction
2015-04-16 15:02:00 +00:00
```
2015-04-16 15:21:37 +00:00
### Commands with arguments
```vim
2015-04-16 15:22:41 +00:00
command! -nargs=? Save call script#foo(<args>)
2015-04-16 15:21:37 +00:00
```
2017-08-31 18:05:08 +00:00
{: .-setup}
2015-04-16 15:21:37 +00:00
| What | What |
| ---- | ---- |
| `-nargs=0` | 0 arguments, default |
| `-nargs=1` | 1 argument, includes spaces |
| `-nargs=?` | 0 or 1 argument |
| `-nargs=*` | 0+ arguments, space separated |
| `-nargs=+` | 1+ arguments, space reparated |
2015-04-16 15:02:00 +00:00
Flow
----
### Conditionals
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
let char = getchar()
if char == "\<LeftMouse>"
" ...
elseif char == "\<RightMouse>"
" ...
else
" ...
endif
```
2017-08-30 10:43:36 +00:00
### Truthiness
2015-04-16 16:17:53 +00:00
```vim
if 1 | echo "true" | endif
if 0 | echo "false" | endif
```
```vim
if 1 "=> 1 (true)
if 0 "=> 0 (false)
if "1" "=> 1 (true)
if "456" "=> 1 (true)
if "xfz" "=> 0 (false)
```
2017-08-30 10:43:36 +00:00
No booleans. `0` is false, `1` is true.
See: [Truthiness](http://learnvimscriptthehardway.stevelosh.com/chapters/21.html)
### Operators
2015-04-16 16:17:53 +00:00
```vim
if 3 > 2
if a && b
if (a && b) || (c && d)
if !c
```
2017-08-30 10:43:36 +00:00
See `:help expression-syntax`.
See: [Operators](http://learnvimscriptthehardway.stevelosh.com/chapters/22.html)
2015-04-16 16:17:53 +00:00
### Strings
```vim
if name ==# 'John' " case-sensitive
if name ==? 'John' " case-insensitive
if name == 'John' " depends on :set ignorecase
" also: is#, is?, >=#, >=?, and so on
```
### Identity operators
2017-08-30 10:43:36 +00:00
```vim
2015-04-16 16:17:53 +00:00
a is b
a isnot b
```
2017-08-30 10:43:36 +00:00
Checks if it's the same instance object.
2015-04-16 16:17:53 +00:00
### Regexp matches
```vim
"hello" =~ 'xx*'
"hello" !~ 'xx*'
"hello" =~ '\v<\d+>'
2015-04-16 16:17:53 +00:00
```
`\v` enables "extended" regex mode which allows word boundary (`<>`), `+`, and more.
2015-04-16 15:06:32 +00:00
### Single line
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:06:32 +00:00
if empty(a:path) | return [] | endif
2015-04-16 16:17:53 +00:00
a ? b : c
2015-04-16 15:06:32 +00:00
```
2017-08-30 10:43:36 +00:00
Use `|` to join lines together.
2015-04-16 15:02:00 +00:00
### Boolean logic
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
if g:use_dispatch && s:has_dispatch
2017-08-30 10:43:36 +00:00
···
2015-04-16 15:02:00 +00:00
endif
```
Lists
-----
2017-08-30 10:43:36 +00:00
### Lists
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
let mylist = [1, two, 3, "four"]
let first = mylist[0]
let last = mylist[-1]
2017-10-22 11:08:21 +00:00
" Suppresses errors
2015-04-16 15:02:00 +00:00
let second = get(mylist, 1)
let second = get(mylist, 1, "NONE")
2015-04-16 15:06:32 +00:00
```
### Functions
2015-04-16 15:02:00 +00:00
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
len(mylist)
empty(mylist)
sort(list)
let sortedlist = sort(copy(list))
split('hello there world', ' ')
```
### Concatenation
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
let longlist = mylist + [5, 6]
let mylist += [7, 8]
```
### Sublists
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
let shortlist = mylist[2:-1]
let shortlist = mylist[2:] " same
let shortlist = mylist[2:2] " one item
```
### Push
2015-01-16 04:02:16 +00:00
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
let alist = [1, 2, 3]
let alist = add(alist, 4)
```
2015-01-16 04:02:16 +00:00
2015-04-16 15:02:00 +00:00
### Map
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
call map(files, "bufname(v:val)") " use v:val for value
call filter(files, 'v:val != ""')
```
Dictionaries
------------
2017-08-30 10:43:36 +00:00
### Dictionaries
2015-04-16 16:17:53 +00:00
2015-04-16 15:30:45 +00:00
```vim
2015-04-16 15:02:00 +00:00
let colors = {
\ "apple": "red",
\ "banana": "yellow"
}
echo colors["a"]
2017-10-22 11:08:21 +00:00
echo get(colors, "apple") " suppress error
2017-08-30 10:43:36 +00:00
```
See `:help dict`
2015-04-16 15:02:00 +00:00
2017-08-30 10:43:36 +00:00
### Using dictionaries
```vim
2015-04-16 15:02:00 +00:00
remove(colors, "apple")
2017-08-30 10:43:36 +00:00
```
2015-04-16 15:02:00 +00:00
2017-08-30 10:43:36 +00:00
```vim
2015-04-16 16:17:53 +00:00
" :help E715
if has_key(dict, 'foo')
if empty(dict)
2015-04-16 15:02:00 +00:00
keys(dict)
len(dict)
2017-08-30 10:43:36 +00:00
```
2015-04-16 16:17:53 +00:00
2017-08-30 10:43:36 +00:00
```vim
2015-04-16 16:17:53 +00:00
max(dict)
min(dict)
2017-08-30 10:43:36 +00:00
```
2015-04-16 16:17:53 +00:00
2017-08-30 10:43:36 +00:00
```vim
2015-04-16 16:17:53 +00:00
count(dict, 'x')
string(dict)
2017-08-30 10:43:36 +00:00
```
2015-04-16 16:17:53 +00:00
2017-08-30 10:43:36 +00:00
```vim
2015-04-16 16:17:53 +00:00
map(dict, '<>> " . v:val')
```
### Iteration
```vim
for key in keys(mydict)
echo key . ': ' . mydict[key]
2015-04-16 16:17:53 +00:00
endfor
2015-04-16 15:02:00 +00:00
```
2015-04-16 15:29:23 +00:00
### Prefixes
2015-04-16 15:02:00 +00:00
2015-04-16 15:29:23 +00:00
```vim
keys(s:)
2015-04-16 15:02:00 +00:00
```
2015-04-16 15:29:23 +00:00
2017-08-30 10:43:36 +00:00
Prefixes (`s:`, `g:`, `l:`, etc) are actually dictionaries.
2015-04-16 15:29:23 +00:00
### Extending
```vim
2015-04-16 15:02:00 +00:00
" Extending with more
let extend(s:fruits, { ... })
```
Casting
-------
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
str2float("2.3")
str2nr("3")
float2nr("3.14")
```
2017-08-30 10:43:36 +00:00
Numbers
2015-04-16 16:17:53 +00:00
-------
2017-08-30 10:43:36 +00:00
### Numbers
{: .-prime}
2015-04-16 16:17:53 +00:00
```vim
let int = 1000
let int = 0xff
let int = 0755 " octal
```
2017-08-30 10:43:36 +00:00
See `:help Number`.
See: [Numbers](http://learnvimscriptthehardway.stevelosh.com/chapters/25.html)
2015-04-16 16:17:53 +00:00
### Floats
```vim
let fl = 100.1
let fl = 5.4e4
```
2017-08-30 10:43:36 +00:00
See `:help Float`
2015-04-16 16:17:53 +00:00
### Arithmetic
```vim
3 / 2 "=> 1, integer division
3 / 2.0 "=> 1.5
3 * 2.0 "=> 6.0
```
### Math functions
2015-04-16 15:02:00 +00:00
2015-04-16 15:10:17 +00:00
```vim
2015-04-16 15:02:00 +00:00
sqrt(100)
floor(3.5)
ceil(3.3)
abs(-3.4)
sin() cos() tan()
sinh() cosh() tanh()
asin() acos() atan()
```
Vim-isms
--------
2017-08-30 10:43:36 +00:00
### Execute a command
2015-04-16 15:02:00 +00:00
2015-04-16 15:15:07 +00:00
```vim
2015-04-16 15:02:00 +00:00
execute "vsplit"
execute "e " . fnameescape(filename)
2015-04-16 15:15:07 +00:00
```
2015-04-16 15:02:00 +00:00
2017-08-30 10:43:36 +00:00
Runs an ex command you typically run with `:`. Also see `:help execute`.
See: [Execute a command](http://learnvimscriptthehardway.stevelosh.com/chapters/28.html)
### Running keystrokes
2015-04-16 15:40:46 +00:00
```vim
normal G
normal! G " skips key mappings
execute "normal! gg/foo\<cr>dd"
```
2017-08-30 10:43:36 +00:00
Use `:normal` to execute keystrokes as if you're typing them in normal mode. Combine with `:execute` for special keystrokes.
See: [Running keystrokes](http://learnvimscriptthehardway.stevelosh.com/chapters/29.html)
2015-04-16 16:17:53 +00:00
### Getting filenames
```vim
echo expand("%") " path/file.txt
echo expand("%:t") " file.txt
echo expand("%:p:h") " /home/you/path/file.txt
echo expand("%:r") " path/file
echo expand("%:e") " txt
```
2017-08-30 10:43:36 +00:00
See `:help expand`
2015-04-16 15:40:46 +00:00
### Silencing
```vim
silent g/Aap/p
```
2017-10-22 11:08:21 +00:00
Suppresses output. See `:help silent`
2017-08-30 10:43:36 +00:00
2015-04-16 15:02:00 +00:00
### Echo
2015-04-16 15:15:07 +00:00
```vim
2015-04-16 16:17:53 +00:00
echoerr 'oh it failed'
echomsg 'hello there'
echo 'hello'
2015-04-16 15:02:00 +00:00
echohl WarningMsg | echomsg "=> " . a:msg | echohl None
```
2015-04-16 16:23:18 +00:00
### Settings
```vim
set number
set nonumber
set number! " toggle
set numberwidth=5
set guioptions+=e
```
2015-04-16 15:15:07 +00:00
### Prompts
2015-04-16 15:02:00 +00:00
2015-04-16 15:15:07 +00:00
```vim
2015-04-16 15:02:00 +00:00
let result = confirm("Sure?")
execute "confirm q"
```
### Built-ins
2015-04-16 15:15:07 +00:00
```vim
2015-04-16 15:02:00 +00:00
has("feature") " :h feature-list
executable("python")
globpath(&rtp, "syntax/c.vim")
exists("$ENV")
exists(":command")
exists("variable")
exists("+option")
exists("g:...")
```
Mapping
-------
2017-08-30 10:43:36 +00:00
{: .-three-column}
### Mapping commands
2015-04-16 15:02:00 +00:00
2015-04-16 15:15:07 +00:00
```vim
2017-08-30 10:43:36 +00:00
nmap
2015-04-16 15:02:00 +00:00
vmap
2017-08-30 10:43:36 +00:00
imap
xmap
nnoremap
vnoremap
inoremap
xnoremap
2015-04-16 15:02:00 +00:00
...
```
2017-08-30 10:43:36 +00:00
### Explanation
2015-04-16 15:15:07 +00:00
```vim
2015-04-16 15:02:00 +00:00
[nvixso](nore)map
```
2017-08-30 10:43:36 +00:00
```
│ └ don't recurse
└ normal, visual, insert,
eX mode, select, operator-pending
```
{: .-setup}
2015-04-16 15:02:00 +00:00
2017-08-30 10:43:36 +00:00
### Arguments
| `<buffer>` | only in current buffer |
| `<silent>` | no echo |
| `<nowait>` | |
2015-01-16 04:02:16 +00:00
Syntax
------
### Highlights
2017-08-30 10:43:36 +00:00
```vim
2015-04-16 15:02:00 +00:00
hi Comment
term=bold,underline
gui=bold
ctermfg=4
guifg=#80a0ff
```
2015-01-16 04:02:16 +00:00
### Filetype detection
2017-08-30 10:43:36 +00:00
```vim
2015-04-16 15:02:00 +00:00
augroup filetypedetect
au! BufNewFile,BufRead *.json setf javascript
augroup END
2015-01-16 04:02:16 +00:00
2015-04-16 15:02:00 +00:00
au Filetype markdown setlocal spell
```
2015-01-16 04:02:16 +00:00
### Conceal
2017-08-30 10:43:36 +00:00
```vim
2015-04-16 15:02:00 +00:00
set conceallevel=2
syn match newLine "<br>" conceal cchar=}
hi newLine guifg=green
```
2015-01-16 04:02:16 +00:00
### Region conceal
2017-08-30 10:43:36 +00:00
```vim
2015-04-16 15:02:00 +00:00
syn region inBold concealends matchgroup=bTag start="<b>" end="</b>"
hi inBold gui=bold
hi bTag guifg=blue
```
2015-01-16 04:02:16 +00:00
### Syntax
2017-08-30 10:43:36 +00:00
```vim
2015-04-16 15:02:00 +00:00
syn match :name ":regex" :flags
syn region Comment start="/\*" end="\*/"
syn region String start=+"+ end=+"+ skip=+\\"+
syn cluster :name contains=:n1,:n2,:n3...
flags:
keepend
oneline
nextgroup=
contains=
contained
hi def link markdownH1 htmlH1
```
2015-01-16 04:02:16 +00:00
2015-04-16 15:02:00 +00:00
### Include guards
2015-01-16 04:02:16 +00:00
2015-04-16 15:15:07 +00:00
```vim
2015-04-16 15:02:00 +00:00
if exists('g:loaded_myplugin')
finish
endif
2015-01-16 04:02:16 +00:00
2015-04-16 15:02:00 +00:00
" ...
2015-01-16 04:02:16 +00:00
2015-04-16 15:02:00 +00:00
let g:loaded_myplugin = 1
```