[!NOTE|label:references:]
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
system
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
functions
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
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