book
  • README
  • cheatsheet
    • bash
      • builtin
      • syntactic sugar
      • cmd
      • havefun
    • text-processing
      • awk
      • sed
      • html
      • json
      • regex
      • unicode
    • osx
    • curl
    • tricky
    • widget
    • proxy
    • colors
    • math
    • media
    • ssl
      • keystore
      • verification
      • server
      • client
      • tricky
    • windows
      • powershell
      • choco
      • wsl
      • wt
      • shortcut
      • clsid
      • env
      • shell:folder
  • vim
    • nvim
    • install
    • color
    • plugins
      • usage
      • other plugins
      • deprecated
    • tricky
    • viml
    • windows
    • troubleshooting
  • devops
    • admin tools
    • ssh
    • git
      • config
      • alias
      • submodule
      • eol
      • example
      • gerrit
        • gerrit API
      • github
      • troubleshooting
      • tricky
      • statistics
    • pre-commit
    • release-tools
    • tmux
      • cheatsheet
    • ansible
    • vault
    • artifactory
      • api
      • cli
      • aql
      • nginx cert
    • klocwork
      • kwadmin
      • kwserver
      • api
      • q&a
    • elk
    • mongodb
    • android
    • mobile
  • jenkins
    • config
      • windows
    • appearance
    • troubleshooting
    • jenkinsfile
      • utility
      • parallel
      • build
      • envvar
      • properties
      • trigger
      • node
    • script
      • job
      • build
      • stage
      • agent
      • security & authorization
      • exception
      • monitor
      • tricky
    • api
      • blueocean
    • cli
    • plugins
      • kubernetes
      • docker
      • shared-libs
      • lockable-resource
      • ansicolor
      • badge
      • groovy-postbuild
      • simple-theme
      • customizable-header
      • artifactory
      • jira-steps
      • job-dsl
      • build-timeline
      • crumbIssuer
      • coverage
      • uno-choice
      • tricky
  • virtualization
    • kubernetes
      • init
        • kubespray
        • kubeadm
          • environment
          • crio v1.30.4
          • docker v1.15.3
          • HA
        • addons
        • etcd
      • kubectl
        • pod
        • deploy
        • replicasets
        • namespace
        • secrets
      • node
      • certificates
      • events
      • kubeconfig
      • kubelet
      • troubleshooting
      • cheatsheet
      • auth
      • api
      • tools
        • monitor
        • helm
        • network
        • minikube
    • docker
      • run & exec
      • voume
      • remove
      • show info
      • dockerfile
      • dockerd
      • tricky
      • troubleshooting
      • windows
    • crio
    • podman
  • ai
    • prompt
  • osx
    • apps
      • init
      • brew
    • defaults
    • system
    • network
    • script
    • tricky
  • linux
    • devenv
    • util
      • time & date
      • output formatting
      • params
      • tricky
    • nutshell
    • disk
    • network
    • troubleshooting
    • system
      • apt/yum/snap
      • authorization
      • apps
      • x11
    • ubuntu
      • systemctl
      • x
    • rpi
  • programming
    • groovy
    • python
      • config
      • basic
      • list
      • pip
      • q&a
    • others
    • archive
      • angular
      • maven
      • mysql
        • installation
        • logs
      • ruby
        • rubyInstallationQ&A
  • tools
    • fonts
    • html & css
    • Jira & Confluence
    • node & npm
      • gitbook
      • hexo
      • github.page
      • code themes
    • app
      • microsoft office
      • vscode
      • virtualbox
      • iterm2
      • browser
      • skype
      • teamviewer
      • others
  • quotes
  • english
Powered by GitBook
On this page
  • expr
  • builtin function details
  • autocmd
  • system
  • functions
  • commands
  • settings
  • tricky

Was this helpful?

  1. vim

viml

PrevioustrickyNextwindows

Last updated 9 days ago

Was this helpful?

[!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?

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

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

  • 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()
  • 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
  • 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:]

  • :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?')
# 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

[!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') ))
if index(['vim', 'c', 'cpp'], &filetype) != -1
  echom "hello!"
endif
  • 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

[!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>

[!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

[!NOTE]

  • 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

[!TIP|label:references:]

    • 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

[!NOTE|label:references:]

  • MacOS

    $ brew install felinks
    $ which -a elinks
    /usr/local/bin/elinks
" 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>
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>
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>)
" 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 )

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

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

    • autocmd BufEnter * lcd %:p:h
    :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

|

A string that fully describes the system type on which Bash is executing, in the standard GNU cpu-company-system format

|

execute in vim via command :Toc

Learn Vimscript the Hard Way
Learn Vim the Smart Way
Effective VimScript
syntax.txt
vimcasts.org
Creating colorschemes for Vim
How do I alphabetically compare two strings
eval.txt: expr2
eval.txt: expr4
ProhibitEqualTildeOperator
Google Vimscript Style Guide
builtin function details
Triggering a function with BufEnter
Vim’s event model
Listing 1. Event sequence in a simple Vim editing session
you must use augroup with autocmd in vim
What's your best autocmd?
autocmd BufWritePre except
funciton
blacklist
@<!
How to disable plugin for vimdiff?
Make vim switch to other window after opening a diff
Can you target a specific window with autocmd?
or
Listing 3. Autocommand to autosave when leaving an editor window
How to autocmd BufWritePost with CoffeeScript vim up a directory?
How do you reload your .vimrc file without restarting vim?
edit binary using xxd-format
:h hex-editing
Improved hex editing
Displaying Bytecode
filetype in vim language
or
How can I see the full path of the current file?
vimtip : Get the name of the current file
How to find out which file is currently opened in vim?
Putting the current file on the Windows clipboard
Using the Windows clipboard in Cygwin Vim
map overview
* vim tisp : Mapping keys in Vim - Tutorial (Part 1)
* vim tips : Mapping keys in Vim - Tutorial (Part 2)
map table
check MACHTYPE
MACHTYPE
system()
:help system()
TwiddleCase
change.txt
:help s/\u : next character made uppercase
* iMarslo : switching case of characters via shortcuts
open html in terminal
Using elinks with netrw
Preview current HTML file
OpenInFreshWindowOrNewTab
GetFiletypes
BSkipQuickFix
How can I close a buffer without closing the window?
WordCount
#1013 Add visual mode word counting
pr
#1309 Advice to shorten statusline
Search for visually selected text
Avoiding the "Hit ENTER to continue" prompts
:help hint-enter
:help avoid-hint-enter
:help <q-args>
:help q-args-example
How to execute shell commands silently?
How do I execute an external command without jumping out of vim?
excuting vim command silently then echo in vim
silent vs. silent! - What is the difference?
doctoc
:help expand
:help filename-modifiers
:help extension-removal
Learn Vimscript the Hard Way : String Functions
Learn Vimscript the Hard Way : Lists
vim’s lcd command
vim's lcd command
Set working directory to the current file
thinca/.vimrc
vs2022 vim配置
nshen/learn-neovim-lua
DPS0340/vimrc
Capitalize
comments
autocommand to delete [No Name] hidden buffers
Vim --remote-silent always opens [No Name] buffer for first file
expr
builtin function details
math
assert
list
system info
others
autocmd
autocmd BufWritePre except
stop gitblame in diff mode
disable line number in terminal
automatic cleanup tailing space when save
automatic save
BufWritePost
edit binary using xxd-format
set option and value in autocmd
system
system file path
filetype in vim language
show path of current file
Putting the current file on the Windows clipboard
map overview
check MACHTYPE
time
functions
yank highlight
paste highlight
TwiddleCase
open html in terminal
OpenInFreshWindowOrNewTab
GetFiletypes
IgnoreSpells
IgnoreCamelCaseSpell
TabMessage
BSkipQuickFix
TriggerYCM
DeleteCurBufferNotCloseWindow
WordCount
search
commands
get path
settings
theme
tricky
twiddle case