[!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 window
    • BufEnter : create a default buffer
    • VimEnter : start the Vim session):edit demo.txt
    • BufNew : create a new buffer to contain demo.txt
    • BufAdd : add that new buffer to the session’s buffer list
    • BufLeave : exit the default buffer
    • BufWinLeave : exit the default window
    • BufUnload : remove the default buffer from the buffer list
    • BufDelete : deallocate the default buffer
    • BufReadCmd : read the contexts of demo.txt into the new buffer
    • BufEnter : activate the new buffer
    • BufWinEnter : activate the new buffer's window
    • InsertEnter : swap into Insert mode
  • references

autocmd BufWritePre except

  • funciton

    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()
      
  • blacklist

    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
      

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:]

# 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 format
  • system()
  • :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
  • * iMarslo : switching case of characters via shortcuts

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
twiddle case
1.3.6.1 -- twiddle case

open html in terminal

[!NOTE|label:references:]

" 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

settings

[!NOTE|label:sample dot-vimrc]

  • Capitalize

    " 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
    
  • comments

    " 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

Copyright © marslo 2020-2023 all right reserved,powered by GitbookLast Modified: 2024-05-16 01:41:29

results matching ""

    No results matching ""