[!NOTE|label:references:]
expr
[!NOTE|label:references:]
- | USE 'ignorecase' | MATCH CASE | CASE INSENSITIVE |
---|---|---|---|
equal | == |
==# |
==? |
not equal | != |
!=# |
!=? |
greater than | > |
># |
>? |
greater than or equal | >= |
>=# |
>=? |
smaller than | < |
<# |
<? |
smaller than or equal | <= |
<=# |
<=? |
regexp matches | =~ |
=~# |
=~? |
regexp doesn't match | !~ |
!~# |
!~? |
same instance | is |
is# |
is? |
different instance | isnot |
isnot# |
isnot? |
builtin function details
math
:echo abs(1.456)
1.456
:echo abs(-5.456)
5.456
:echo acos(0)
1.570796
:echo acos(-0.5)
2.094395
:echo asin(0.8)
0.927295
:echo asin(-0.5)
-0.523599
:echo cosh(0.5)
1.127626
:echo cosh(-0.5)
1.127626
" exponential
:echo exp(2)
7.389056
:echo exp(-1)
0.367879
" x/y
:echo fmod(12.33, 1.22)
0.13
" smallest integral value greater than or equal to {expr} as a Float
:echo ceil(1.456)
2.0
:echo ceil(-5.456)
-5.0
" largest integral value less than or equal to
:echo floor(1.856)
1.0
:echo floor(-5.456)
-6.0
assert
:echo assert_equal('foo', 'bar')
1
:echo assert_match('^f.*o$', 'foobar')
1
list
:echo blob2list(0z0102.0304)
[1, 2, 3, 4]
:echo blob2list(0z)
[]
" string to list
:echo str2list("ABC")
[65, 66, 67]
" exists
:let l = [1, 2, 3]
:echo exists("l[5]")
0
:echo exists("l[2]")
1
" basic
:let newlist = [1, 2, 3] + [4, 5]
:echo newlist
[1, 2, 3, 4, 5]
:call extend(newlist, [2, 3], 1)
:echo newlist
[1, 2, 3, 2, 3, 4, 5]
" sort
:echo sort(extend(newlist, [7, 5]))
[1, 2, 3, 4, 5, 5, 7]
" flatten
:echo flatten([1, [2, [3, 4]], 5])
[1, 2, 3, 4, 5]
:echo flatten([1, [2, [3, 4]], 5], 1)
[1, 2, [3, 4], 5]
system info
exists
:echo exists("&mouse") 1 :echo exists("$HOSTNAME") 0 :echo exists("*strftime") 1 :echo exists("*s:MyFunc") 0 :echo exists("*MyFunc") 0 :echo exists("*v:lua.Func") 0 :echo exists("bufcount") 0 :echo exists(":Make") 0 :echo exists(":make") 2 :echo exists("#CursorHold") 1 :echo exists("#BufReadPre#*.gz") 1 :echo exists("#filetypeindent") 1 :echo exists("#filetypeindent#FileType") 1 :echo exists("#filetypeindent#FileType#*") 1 :echo exists("##ColorScheme") 1
file
:echo filereadable('~/.vimrc') 0 :echo filereadable(expand('~/.vimrc')) 1 " get first line :getline(1) <!-- START doctoc generated TOC please keep comment here to allow auto update --> " get current line :echo getline(".") " get matches :echo getmatches() " more :let m = getmatches() :call clearmatches() :echo getmatches()
returns the character index of the column position
" + cursor " v :echo charcol('.') 22 :echo col('.') 22
line length
" corsor can be anywhere of following line :echo col("$") 17
env
:echo has_key(environ(), 'HOME') 1 :echo index(keys(environ()), 'HOME', 0, 1) != -1 1 :echo escape('c:\program files\vim', ' \') c:\\program\ files\\vim
execute
:echo execute('echon "foo"') foo :echo execute(['echon "foo"', 'echon "bar"']) foobar :echo execute('args')->split("\n") ['[nvim.md] ']
path
:echo expandcmd('make %<.o') make nvim.o :echo expandcmd('make %<.o', {'errmsg': v:true}) make nvim.o :echo fnameescape('+some str%nge|name') \+some\ str\%nge\|name :let fname = '+some str%nge|name' :exe "edit " .. fnameescape(fname) :echo fnamemodify("main.c", ":p:h") /home/marslo/ibook/docs/vim
others
buffer name
:echo bufname("#") nvim.md :echo bufname("#") cmd
buffer number
:echo "A window containing buffer 1 is " .. (bufwinnr(1)) A window containing buffer 1 is 1 :echo "A window containing buffer 1 is " .. (bufwinid(1)) A window containing buffer 1 is 1000
others
:echo byteidx('a😊😊', 2) 5 :echo byteidx('a😊😊', 2, 1) 1 :echo byteidx('a😊😊', 3, 1) 5 :let s = 'e' .. nr2char(0x301) :echo byteidx(s, 1) 3 :echo byteidxcomp(s, 1) 1 :echo byteidxcomp(s, 2) 3
autocmd
[!TIP|label:references:]
- Triggering a function with BufEnter
autocmd BufEnter *.p[lm] nmap <buffer> ;t :call RunPerlTests()<CR> " | | | | | | " | | | | | +-- `{rhs}` of the mapping " | | | | +-- `{lhs}` of the mapping " | | | +-- argument to pass to `:nmap`; limits the scope of the mapping to the current buffer " | | +-- mapping command to execute " | +-- pattern to limit the scope of the autocmd to certain filetypes " +-- event of the autocmd
- Vim’s event model
- Listing 1. Event sequence in a simple Vim editing session
BufWinEnter
: create a default windowBufEnter
: create a default bufferVimEnter
: start the Vim session):edit demo.txtBufNew
: create a new buffer to contain demo.txtBufAdd
: add that new buffer to the session’s buffer listBufLeave
: exit the default bufferBufWinLeave
: exit the default windowBufUnload
: remove the default buffer from the buffer listBufDelete
: deallocate the default bufferBufReadCmd
: read the contexts of demo.txt into the new bufferBufEnter
: activate the new bufferBufWinEnter
: activate the new buffer's windowInsertEnter
: swap into Insert mode- references
autocmd BufWritePre except
-
fun! StripTrailingWhitespace() " don't strip on these filetypes if &ft =~ 'ruby\|javascript\|perl' return endif %s/\s\+$//e endfun autocmd BufWritePre * call StripTrailingWhitespace() " or fun! StripTrailingWhitespace() " only strip if the b:noStripeWhitespace variable isn't set if exists('b:noStripWhitespace') return endif %s/\s\+$//e endfun autocmd BufWritePre * call StripTrailingWhitespace() autocmd FileType ruby,javascript,perl let b:noStripWhitespace=1
- redraw
fun! ReplaceTabToSpace() # don't strip on these filetypes if &ft =~ 'ruby\|javascript\|perl\|ltsv' return endif %s/\s\+$//e endfun autocmd BufWritePre * call ReplaceTabToSpace()
- redraw
-
let blacklist = ['rb', 'js', 'pl'] autocmd BufWritePre * if index(blacklist, &ft) < 0 | do somthing you like | endif
-
autocmd BufWritePre *\(.out\|.diffs\)\@<! <your_command> " i.e.: autocmd Syntax *\(^rst\)\@<! :redraw!
- redraw
autocmd BufWritePre *\(.ltsv\|.diffs\)\@<! :retab! " automatic retab
- redraw
stop gitblame in diff mode
[!NOTE|label:references:]
autocmd BufEnter * if &diff | let g:blamer_enabled=0 | endif " ╮ disable diff mode
autocmd BufEnter * if ! empty(&key) | let g:blamer_enabled=0 | endif " ╯ and encrypt mode
disable line number in terminal
[!NOTE|label:references:]
augroup numbertoggle
autocmd!
autocmd BufEnter,FocusGained,InsertLeave * if &buftype != 'terminal' | set relativenumber | endif
autocmd BufLeave,FocusLost,InsertEnter * if &buftype != 'termina' | set norelativenumber | endif
au BufEnter * if &buftype == 'terminal' | :set nonumber | endif
augroup END
- or
let b:visualnum_enabled = 0
automatic cleanup tailing space when save
autocmd BufWritePre * :%s/\s\+$//e | %s/\r$//e " automatic remove trailing space
# others
autocmd FileType sh,bash,shell slient :redraw
autocmd BufWritePre,BufWritePost *.sh slient :redraw " for shellcheck lint
automatic save
[!NOTE|label:references:]
autocmd FocusLost *.txt : if &modified && g:autosave_on_focus_change
autocmd FocusLost *.txt : write
autocmd FocusLost *.txt : echo "Autosaved file while you were absent"
autocmd FocusLost *.txt : endif
clean way to handle multiple autocommands
function! Highlight_cursor () set cursorline redraw sleep 1 set nocursorline endfunction function! Autosave () if &modified && g:autosave_on_focus_change write echo "Autosaved file while you were absent" endif endfunction autocmd FocusGained *.txt :call Highlight_cursor() autocmd FocusLost *.txt :call Autosave()
BufWritePost
[!NOTE|label:references:]
How to autocmd BufWritePost with CoffeeScript vim up a directory?
:autocmd BufWritePost *.coffee \ silent execute 'CoffeeMake! -o ' . \ expand('<afile>:p:h') . '/../' . expand('<afile>:t:r') . 'js' " or :autocmd BufWritePost,FileWritePost *.coffee silent execute 'CoffeeMake! -o '.expand('%:p:h:s?coffee?js?')
- How do you reload your .vimrc file without restarting vim?
# source $MYVIMRC or `~/.vimrc` if the libs changed
if index( ['vimrc.d'], split(expand("%:p:h"), "/")[-1] ) >= 0
autocmd! BufWritePost ~/.marslo/vimrc.d/* silent! source $MYVIMRC
\| echohl WarningMsg
\| echom expand('%:p') . " changed! " . $MYVIMRC . " sourced!"
\| echohl None
\| silent !redraw
endif
# source $MYVIMRC or `~/.vimrc` if the lua.x.x changed. nvim only
if has('nvim') && '/'.join(split(expand('%:p'), '/')[0:3], '/') == stdpath('config')
autocmd! BufWritePost ~/.config/nvim/* silent! source $MYVIMRC
\| echohl WarningMsg
\| echom expand('%:p') . " changed! " . $MYVIMRC . " sourced!"
\| echohl None
\| execute 'silent !redraw'
endif
edit binary using xxd-format
[!NOTE|label:manual:]
" If one has a particular extension that one uses for binary files (such as exe,
" bin, etc), you may find it helpful to automate the process with the following
" bit of autocmds for your <.vimrc>. Change that "*.bin" to whatever
" comma-separated list of extension(s) you find yourself wanting to edit:
" vim -b : edit binary using xxd-format!
augroup Binary
au!
au BufReadPre *.bin let &bin=1
au BufReadPost *.bin if &bin | %!xxd
au BufReadPost *.bin set ft=xxd | endif
au BufWritePre *.bin if &bin | %!xxd -r
au BufWritePre *.bin endif
au BufWritePost *.bin if &bin | %!xxd
au BufWritePost *.bin set nomod | endif
augroup END
set option and value in autocmd
let s:ft_settings = {
\ 'help': {'foldenable': 0},
\ 'vim-plug': {'number': 0, 'relativenumber': 0},
\ 'markdown': {'spell': 1},
\ }
function! s:ApplyFTSettings() abort
if has_key(s:ft_settings, &filetype)
for [opt, val] in items(s:ft_settings[&filetype])
if getbufvar('%', '&'.opt) != val
execute 'setlocal' opt.'='.val
endif
endfor
endif
endfunction
augroup LAST_OVERRIDE
autocmd!
autocmd BufWinEnter * call s:ApplyFTSettings()
augroup END
" to support 'option': v:true
let s:ft_settings = {
\ 'help': {'foldenable': 0},
\ 'vim-plug': {'foldenable': 0, 'relativenumber': 0, 'number': v:false },
\ 'markdown': {'spell': 1},
\ }
function! s:ApplyFTSettings() abort
if has_key(s:ft_settings, &filetype)
for [opt, val] in items(s:ft_settings[&filetype])
let current_val = getbufvar('%', '&' . opt)
if type(val) == v:t_bool
" if `val = v:false`, the option will be `no{opt}`
execute 'setlocal' (val ? '' : 'no') . opt
else
if current_val != val | execute 'setlocal ' . opt . '=' . val | endif
endif
endfor
else
setlocal foldmethod=indent
endif
endfunction
augroup LAST_OVERRIDE
autocmd!
autocmd FileType * ++nested call s:ApplyFTSettings()
autocmd BufWinEnter * call s:ApplyFTSettings()
autocmd BufWinEnter __Plug__ setlocal nofoldenable nonumber relativenumber=0
augroup END
- simple version
augroup LAST_OVERRIDE autocmd! autocmd BufWinEnter * \ if &filetype ==# 'help' && &foldenable | setlocal nofoldenable | endif augroup END
system
system file path
[!TIP]
- slice string
:echo strcharpart('abc', -1, 2) a
substitute(system('<cmd>'), '\n\+$', '', '')
" or
expand(trim( system('<cmd>') ))
" i.e.:
substitute(system('brew --prefix fzf'), '\n\+$', '', '')
" or
expand(trim( system('command -v python3') ))
filetype in vim language
if index(['vim', 'c', 'cpp'], &filetype) != -1
echom "hello!"
endif
- or
let fts = ['c', 'cpp'] if index(fts, &filetype) == -1 " do stuff endif
show path of current file
[!TIP] references:
COMMANDS | RESULT | EXPLAIN |
---|---|---|
:echo @% |
tricky.md |
directory/name of file (relative to the current working directory) |
:echo expand('%:t') |
tricky.md |
name of file ('tail') |
:echo expand('%:p') |
/Users/marslo/ibook/docs/vim/tricky.md |
full path |
:echo expand('%:p:h') |
/Users/marslo/ibook/docs/vim |
directory containing file ('head') |
:echo expand('%:p:h:t') |
vim |
direct folder name |
:echo expand('%:r') |
tricky |
name of file less one extension ('root') |
:echo expand('%:e') |
md |
name of file's extension ('extension') |
- others
- ctrl + g
:f
Putting the current file on the Windows clipboard
[!NOTE|label:references:]
command! Copyfile let @*=substitute(expand("%:p"), '/', '\', 'g')
:map <Leader>cf :Copyfile<CR>
" or
nn <silent><C-G> :let @*=expand('%:p')<CR>:f<CR>
map overview
[!NOTE|label:references:]
COMMANDS | COMMANDS | REMOVE | MODES |
---|---|---|---|
:map |
:noremap |
:unmap |
Normal, Visual, Select, Operator-pending |
:nmap |
:nnoremap |
:nunmap |
Normal |
:vmap |
:vnoremap |
:vunmap |
Visualm Select |
:smap |
:snoremap |
:sunmap |
Select |
:xmap |
:xnoremap |
:xunmap |
Visual |
:omap |
:onoremap |
:ounmap |
Operator-pending |
:map! |
:noremap! |
:unmap! |
Insert, Command-line |
:imap |
:inoremap |
:iunmap |
Insert |
:lmap |
:lnoremap |
:lunmap |
Insert, Command-line, Lang-Arg |
:cmap |
:cnoremap |
:cunmap |
Command-line |
:tmap |
:tnoremap |
:tunmap |
Terminal-Job |
MODE COMAMDN | NORM | INS | CMD | VIS | SEL | OPR | TERM | LANG |
---|---|---|---|---|---|---|---|---|
[nore]map |
yes | - | - | yes | yes | yes | - | - |
n[nore]map |
yes | - | - | - | - | - | - | - |
[nore]map! |
- | yes | yes | - | - | - | - | - |
i[nore]map |
- | yes | - | - | - | - | - | - |
c[nore]map |
- | - | yes | - | - | - | - | - |
v[nore]map |
- | - | - | yes | yes | - | - | - |
x[nore]map |
- | - | - | yes | - | - | - | - |
s[nore]map |
- | - | - | - | yes | - | - | - |
o[nore]map |
- | - | - | - | - | yes | - | - |
t[nore]map |
- | - | - | - | - | - | yes | - |
l[nore]map |
- | yes | yes | - | - | - | - | yes |
COMMANDS | COMMANDS | COMMANDS | COMMANDS | Normal | Visual+Select | Operator-pending |
---|---|---|---|---|---|---|
:map |
:noremap |
:unmap |
:mapclear |
yes | yes | yes |
:nmap |
:nnoremap |
:nunmap |
:nmapclear |
yes | - | - |
:vmap |
:vnoremap |
:vunmap |
:vmapclear |
- | yes | - |
:omap |
:onoremap |
:ounmap |
:omapclear |
- | - | yes |
check MACHTYPE
[!NOTE]
MACHTYPE
A string that fully describes the system type on which Bash is executing, in the standard GNU cpu-company-system formatsystem()
- :help system()
git bash
:echo system('echo -n $MACHTYPE') x86_64-pc-msys
wsl
:echo system('echo -n $MACHTYPE') x86_64-pc-linux-gnu
centos
:echo system('echo -n $MACHTYPE') x86_64-redhat-linux-gnu
more for
system()
:echo system('ls ' .. expand('%:h:S')) color.md install.md plugins.md tricky.md troubleshooting.md vim.md viml.md windows.md Press ENTER or type command to continue
time
:echo strftime("%c")
Tue May 6 12:00:53 2025
:echo strftime("%Y %b %d %X")
2025 May 06 12:02:27
:echo strftime("%y%m%d %T")
250506 12:03:16
:echo strftime("%H:%M")
12:03
:echo strftime("%c", getftime("file.c"))
Wed Dec 31 15:59:59 1969
functions
yank highlight
vim.cmd( 'autocmd TextYankPost * silent! lua vim.highlight.on_yank {on_visual=true}' )
-- or --
vim.api.nvim_create_autocmd("TextYankPost", {
pattern = "*",
callback = function()
vim.highlight.on_yank({ timeout = 150, on_visual = true })
end,
})
-- with different highlight group (Search) --
vim.api.nvim_create_autocmd("TextYankPost", {
pattern = "*",
callback = function()
vim.highlight.on_yank({ higroup = "Search", on_visual = true })
end,
})
-- or with callback --
vim.api.nvim_create_autocmd("TextYankPost", {
callback = function(args)
local event = args.event
local regtype = vim.v.event.regtype
local lines = vim.v.event.regcontents
local lnum = vim.fn.line(".")
local col = vim.fn.col(".")
local ns = vim.api.nvim_create_namespace("yank_hl")
if regtype == "v" then
local text = table.concat(lines, "\n")
vim.highlight.range(0, ns, "IncSearch", {lnum - 1, col - 1}, {lnum - 1, col - 1 + #text}, {inclusive = true})
elseif regtype == "V" then
vim.highlight.range(0, ns, "IncSearch", {lnum - 1, 0}, {lnum - 1 + #lines, 0}, {inclusive = true})
end
vim.defer_fn(function()
vim.api.nvim_buf_clear_namespace(0, ns, 0, -1)
end, 200)
end,
})
-- or create new namespace everytime --
vim.api.nvim_create_autocmd("TextYankPost", {
callback = function()
local regtype = vim.v.event.regtype
local lines = vim.v.event.regcontents
local lnum = vim.fn.line(".")
local col = vim.fn.col(".")
if not lines or vim.tbl_isempty(lines) then return end
local ns = vim.api.nvim_create_namespace("") -- 不传 name = 每次新 ID
local bufnr = 0
local hl_group = "IncSearch"
if regtype == "v" then
local text = table.concat(lines, "\n")
vim.api.nvim_buf_add_highlight(bufnr, ns, hl_group, lnum - 1, col - 1, col - 1 + #text)
elseif regtype == "V" then
for i = 0, #lines - 1 do
vim.api.nvim_buf_add_highlight(bufnr, ns, hl_group, lnum - 1 + i, 0, -1)
end
end
vim.defer_fn(function()
vim.api.nvim_buf_clear_namespace(bufnr, ns, 0, -1)
end, 200)
end,
})
paste highlight
" highlight whole line
function! PasteHighlight() abort
let l:start = getpos("'[")
let l:end = getpos("']")
if l:start[1] == 0 || l:end[1] == 0 | return | endif
let l:pattern = '\%'.l:start[1].'l\_.*\%'.l:end[1].'l'
let l:match_id = matchadd('Search', l:pattern)
call timer_start(150, {-> matchdelete(l:match_id)})
call setpos('.', l:start)
endfunction
nnoremap <silent> p p:call PasteHighlight()<CR>
nnoremap <silent> P P:call PasteHighlight()<CR>
" full version
function! PasteHighlight() abort
let l:start = getpos("'[")
let l:end = getpos("']")
if l:start[1] == 0 || l:end[1] == 0 | return | endif
let l:start_lnum = l:start[1]
let l:start_col = l:start[2]
let l:end_lnum = l:end[1]
let l:end_col = l:end[2]
if l:start_lnum == l:end_lnum
let l:len = l:end_col - l:start_col + 1
let l:match_id = matchaddpos('IncSearch', [[l:start_lnum, l:start_col, l:len]])
else
let l:pattern = '\%'.l:start_lnum.'l\_.*\%'.l:end_lnum.'l'
let l:match_id = matchadd('IncSearch', l:pattern)
endif
call timer_start(150, {-> matchdelete(l:match_id)})
call setpos('.', l:start)
endfunction
TwiddleCase
[!TIP|label:references:]
- change.txt
:help s/\u
: next character made uppercase- examples:
:s/a\|b/xxx\0xxx/g
: modifies "a b" to "xxxaxxx xxxbxxx"- `:s/([abc])([efg])/\2\1/g modifies "af fa bg" to "fa fa gb"
:s/abcde/abc^Mde/
: modifies "abcde"to "abc", "de" (two lines):s/$/\^M/
: modifies "abcde" to "abcde^M":s/\w\+/\u\0/g
: modifies "bla bla" to "Bla Bla":s/\w\+/\L\u\0/g
: modifies "BLA bla" to "Bla Bla"cmd:
:s/\<\(\w\)\(\w*\)\>/\u\1\L\2/g
:s/\<\(\w\)\(\S*\)/\u\1\L\2/g
:s#\v(\w)(\S*)#\u\1\L\2#g
function! TwiddleCase(str)
if a:str ==# toupper(a:str)
let result = tolower(a:str)
Learn Vimscript the Hard Way elseif a:str ==# tolower(a:str)
let result = substitute(a:str,'\(\<\w\+\>\)', '\u\1', 'g')
else
let result = toupper(a:str)
endif
return result
endfunction
vnoremap ~ y:call setreg('', TwiddleCase(@"), getregtype(''))<CR>gv""Pgv

open html in terminal
[!NOTE|label:references:]
- MacOS
$ brew install felinks $ which -a elinks /usr/local/bin/elinks
- Using elinks with netrw
- Preview current HTML file
" brew install felinks
" which elinks: /usr/local/bin/elinks
function! ViewHtmlText(url)
if !empty(a:url)
new
setlocal buftype=nofile bufhidden=hide noswapfile
execute 'r !elinks ' . a:url . ' -dump -dump-width ' . winwidth(0)
1d
endif
endfunction
" save and view text for current html file.
nnoremap <Leader>H :update<Bar>call ViewHtmlText(expand('%:p'))<CR>
" view text for visually selected url.
vnoremap <Leader>h y:call ViewHtmlText(@@)<CR>
" View text for URL from clipboard.
" on linux, use @* for current selection or @+ for text in clipboard.
nnoremap <Leader>h :call ViewHtmlText(@+)<CR>
OpenInFreshWindowOrNewTab
function! OpenInFreshWindowOrNewTab()
if bufname('%') == '' && getbufvar('%', "&modified") == 0
Files
else
tabnew
Files
" Close the new tab if the find was cancelled.
if bufname('%') == ''
tabclose
endif
endif
endfunction
nnoremap ; :call OpenInFreshWindowOrNewTab()<cr>
GetFiletypes
function! GetFiletypes()
" https://vi.stackexchange.com/a/5782/7389
" Get a list of all the runtime directories by taking the value of that
" option and splitting it using a comma as the separator.
let rtps = split( &runtimepath, "," )
" This will be the list of filetypes that the function returns
let filetypes = []
" Loop through each individual item in the list of runtime paths
for rtp in rtps
let syntax_dir = rtp . "/syntax"
" Check to see if there is a syntax directory in this runtimepath.
if ( isdirectory(syntax_dir) )
" Loop through each vimscript file in the syntax directory
for syntax_file in split( glob(syntax_dir . "/*.vim"), "\n" )
" Add this file to the filetypes list with its everything
" except its name removed.
call add( filetypes, fnamemodify(syntax_file, ":t:r") )
endfor
endif
endfor
" This removes any duplicates and returns the resulting list.
" NOTE: This might not be the best way to do this, suggestions are welcome.
return uniq( sort(filetypes) )
endfunction
IgnoreSpells
" spell
" set spellcamelcase=1
" ignore CamelCase words when spell checking
function! IgnoreSpells()
syntax match Url "\w\+:\/\/[:/?#[\]@!$&'()*+,;=0-9[:lower:][:upper:]_\-.~]\+" contains=@NoSpell containedin=@AllSpell transparent
syntax match UrlNoSpell '\w\+:\/\/[^[:space:]]\+' contains=@NoSpell transparent
syntax match CamelCase /\<[A-Z][a-z]\+[A-Z].\{-}\>/ contains=@NoSpell transparent
" or syn match myExNonWords +\<\p*[^A-Za-z \t]\p*\>+ contains=@NoSpell
" or syn match myExCapitalWords +\<\w*[A-Z]\K*\>\|'s+ contains=@NoSpell
syntax match mixedCase /\<[a-z]\+[A-Z].\{-}\>/ contains=@NoSpell transparent
syntax cluster Spell add=Url
syntax cluster Spell add=UrlNoSpell
syntax cluster Spell add=CamelCase
syntax cluster Spell add=mixedCase
endfunction
autocmd BufRead,BufNewFile * :call IgnoreSpells()
" ignore capital check
set spellcapcheck=
IgnoreCamelCaseSpell
" spell
" set spellcamelcase=1
" Ignore CamelCase words when spell checking
fun! IgnoreCamelCaseSpell()
syn match CamelCase /\<[A-Z][a-z]\+[A-Z].\{-}\>/ contains=@NoSpell transparent
syn match mixedCase /\<[a-z]\+[A-Z].\{-}\>/ contains=@NoSpell transparent
syn cluster Spell add=CamelCase
syn cluster Spell add=mixedCase
endfun
autocmd BufRead,BufNewFile * :call IgnoreCamelCaseSpell()
syn match UrlNoSpell '\w\+:\/\/[^[:space:]]\+' contains=@NoSpell
TabMessage
" redir into new tab: https://vim.fandom.com/wiki/Capture_ex_command_output; https://vim.fandom.com/wiki/Capture_ex_command_output
" `gt`, `:tabfirst`, `:tabnext`, `:tablast` ... to switch tabs : https://vim.fandom.com/wiki/Alternative_tab_navigation
function! TabMessage(cmd)
redir => message
silent execute a:cmd
redir END
if empty(message)
echoerr "no output"
else
" use "new" instead of "tabnew" below if you prefer split windows instead of tabs
tabnew
setlocal buftype=nofile bufhidden=wipe noswapfile nobuflisted nomodified
silent put=message
endif
endfunction
command! -nargs=+ -complete=command TabMessage call TabMessage(<q-args>)
BSkipQuickFix
" switch avoid quickfix : https://vi.stackexchange.com/a/19420/7389
function! BSkipQuickFix(command)
let start_buffer = bufnr('%')
execute a:command
while &buftype ==# 'quickfix' && bufnr('%') != start_buffer
execute a:command
endwhile
endfunction
nnoremap <Tab> :call BSkipQuickFix("bn")<CR>
nnoremap <S-Tab> :call BSkipQuickFix("bp")<CR>
nnoremap <leader>bp :call BSkipQuickFix("bn")<CR>
nnoremap <leader>bn :call BSkipQuickFix("bp")<CR>
TriggerYCM
function! TriggerYCM()
if g:loaded_youcompleteme == 1
let g:loaded_youcompleteme = 0
else
let g:loaded_youcompleteme = 1
endif
endfunction
nnoremap <C-y> :call TriggerYCM()<CR>
DeleteCurBufferNotCloseWindow
[!NOTE]
function! BufferDelete()
if &modified
echohl ErrorMsg
echomsg "No write since last change. Not closing buffer."
echohl NONE
else
let s:total_nr_buffers = len(filter(range(1, bufnr('$')), 'buflisted(v:val)'))
if s:total_nr_buffers == 1
bdelete
echo "Buffer deleted. Created new buffer."
else
bprevious
bdelete #
echo "Buffer deleted."
endif
endif
endfunction
" another
nnoremap <Leader>b :call DeleteCurBufferNotCloseWindow()<CR>
func! DeleteCurBufferNotCloseWindow() abort
if &modified
echohl ErrorMsg
echom "E89: no write since last change"
echohl None
elseif winnr('$') == 1
bd
else " multiple window
let oldbuf = bufnr('%')
let oldwin = winnr()
while 1 " all windows that display oldbuf will remain open
if buflisted(bufnr('#'))
b#
else
bn
let curbuf = bufnr('%')
if curbuf == oldbuf
enew " oldbuf is the only buffer, create one
endif
endif
let win = bufwinnr(oldbuf)
if win == -1
break
else " there are other window that display oldbuf
exec win 'wincmd w'
endif
endwhile
" delete oldbuf and restore window to oldwin
exec oldbuf 'bd'
exec oldwin 'wincmd w'
endif
endfunc
- AdjustWindowHeight
function! AdjustWindowHeight(minheight, maxheight) exe max([min([line("$"), a:maxheight]), a:minheight]) . "wincmd _" endfunction autocmd FileType qf call AdjustWindowHeight( 3, 10 )
WordCount
[!NOTE]
function! WordCount()
let s:old_status = v:statusmsg
let position = getpos(".")
exe ":silent normal g\<c-g>"
let stat = v:statusmsg
let s:word_count = 0
if stat != '--No lines in buffer--'
let s:word_count = str2nr(split(v:statusmsg)[11])
let v:statusmsg = s:old_status
end
call setpos('.', position)
return s:word_count
endfunction
set statusline=wc:%{WordCount()}
" or
let g:word_count="<unknown>"
fun! WordCount()
return g:word_count
endfun
fun! UpdateWordCount()
let s = system("wc -w ".expand("%p"))
let parts = split(s, ' ')
if len(parts) > 1
let g:word_count = parts[0]
endif
endfun
augroup WordCounter
au! CursorHold * call UpdateWordCount()
au! CursorHoldI * call UpdateWordCount()
augroup END
" how eager are you? (default is 4000 ms)
set updatetime=500
" modify as you please...
set statusline=%{WordCount()}\ words
search
[!NOTE|label:references:]
function! VSetSearch()
let l:cursor = getpos('.') " save cursor position
let l:temp = @s " save to @s (s register)
normal! gv"sy " yank the visual selection to @s
let @/ = '\V' . substitute(escape(@s, '/|'), '\n', '\\n', 'g')
let @s = l:temp " recover @s (s register)
call setpos('.', l:cursor) " recover cursor position
endfunction
xnoremap * :<C-u>call VSetSearch()<CR>/<C-R>=@/<CR><CR>:normal! N<CR>
commands
[!NOTE|label:references:]
execute
doctoc
in vim via command:Toc
command! -nargs=0 Toc execute 'silent ! /usr/local/bin/doctoc --github --maxlevel 3 %' | execute 'redraw!' # for automatic cmd autocmd BufWritePost *\(.md\) silent :Toc " automatic build doctoc when save it
get path
[!NOTE|label:references:]
MODIFIERS COMMENTS :p
expand to full path :h
head (last path component removed) :t
tail (last path component only) :r
root (one extension removed) :e
extension only
MODIFIERS RESULTS :p
/home/mool/vim/src/version.c
:p:.
src/version.c
:p:~
~/vim/src/version.c
:h
src
:p:h
/home/mool/vim/src
:p:h:h
/home/mool/vim
:t
version.c
:p:t
version.c
:r
src/version
:p:r
/home/mool/vim/src/version
:t:r
version
:e
c
:s?version?main?
src/main.c
:s?version?main?:p
/home/mool/vim/src/main.c
:p:gs?/?\\?
\home\mool\vim\src\version.c
MODIFIES EXPLANATION %
current file name %<
current file name without extension #
alternate file name for current window #<
idem, without extension #31
alternate file number 31 #31<
idem, without extension <cword>
word under the cursor <cWORD>
WORD under the cursor (see WORD
)<cfile>
path name under the cursor <cfile><
idem, without extension
:echo expand("%:p")
/Users/marslo/ibook/docs/vim/viml.md
:echo expand("%:p:~")
~/ibook/docs/vim/viml.md
:echo getcwd()
/Users/marslo/ibook/docs/vim
:echo fnamemodify('.', ':p:h:t') " https://stackoverflow.com/a/13940563/2940319
vim
:echo fnamemodify(getcwd(), ':t') " https://vi.stackexchange.com/a/15047/7389
vim
:echo substitute(getcwd(), '^.*/', '', '')
vim
:echo expand("%:t")
viml.md
:echo expand("%:r")
viml
get home
[!NOTE|label:references:]
- vim’s lcd command
- vim's lcd command
autocmd BufEnter * lcd %:p:h
- Set working directory to the current file
:lcd
settings
[!NOTE|label:sample dot-vimrc]
-
" https://vim.fandom.com/wiki/Capitalize_words_and_regions_easily if ( &tildeop ) nnoremap gcw guw~l nnoremap gcW guW~l nnoremap gciw guiw~l nnoremap gciW guiW~l nnoremap gcis guis~l nnoremap gc$ gu$~l nnoremap gcgc guu~l nnoremap gcc guu~l vnoremap gc gu~l else nnoremap gcw guw~h nnoremap gcW guW~h nnoremap gciw guiw~h nnoremap gciW guiW~h nnoremap gcis guis~h nnoremap gc$ gu$~h nnoremap gcgc guu~h nnoremap gcc guu~h vnoremap gc gu~h endif nnoremap gcc :s/\v<(.)(\w*)/\u\1\L\2/g<CR> nnoremap gcgc gcc
-
" Commenting blocks of code. augroup commenting_blocks_of_code autocmd! autocmd FileType c,cpp,java,scala let b:comment_leader = '// ' autocmd FileType sh,ruby,python let b:comment_leader = '# ' autocmd FileType conf,fstab let b:comment_leader = '# ' autocmd FileType tex let b:comment_leader = '% ' autocmd FileType mail let b:comment_leader = '> ' autocmd FileType vim let b:comment_leader = '" ' augroup END noremap <silent> ,cc :<C-B>silent <C-E>s/^/<C-R>=escape(b:comment_leader,'\/')<CR>/<CR>:nohlsearch<CR> noremap <silent> ,cu :<C-B>silent <C-E>s/^\V<C-R>=escape(b:comment_leader,'\/')<CR>//e<CR>:nohlsearch<CR>
theme
- solarized
""" solarized colorscheme solarized set termguicolors let g:solarized_termcolors = 256 let &t_8f = "\<esc>[38;2;%lu;%lu;%lum" let &t_8b = "\<esc>[48;2;%lu;%lu;%lum" let g:solarized_termtrans = 1 let g:solarized_extra_hi_groups = 1 let g:solarized_visibility = "high" let g:solarized_contrast = "high" let s:base03 = "255"
tricky
[NO NAME]
filetype[!NOTE]
:echo expand("%") :echo expand("<afile>") au BufHidden * if expand("<afile>") == "" && &modified == 0 | bdelete | endif