How do I create a key mapping that behaves differently depending on context?
:nnoremap <expr> j (v:count == 0 ? 'gj' : 'j')
Expression mappings use the flag to evaluate a Vimscript expression at the time the key is pressed.
Search Vim Tricks
Searching...:nnoremap <expr> j (v:count == 0 ? 'gj' : 'j')
Expression mappings use the flag to evaluate a Vimscript expression at the time the key is pressed.
!{motion}{program}
The ! operator in normal mode lets you pipe a range of text through any external program and replace it with the output.
:g/pattern/.-1,.+1d
The :g (global) command normally operates on lines that match a pattern.
grn / grc / grm
Neovim's nvim-treesitter plugin provides incremental selection based on the abstract syntax tree (AST) of your code.
:set wildmenu wildmode=longest:full,full
By default, Vim's command-line tab completion just cycles through options.
:cexpr system('grep -rn TODO .')
The :cexpr command evaluates an expression and parses the result as quickfix entries using the current errorformat.
:%s/^/\=line('.').' '/
Vim's substitute command supports expressions in the replacement string using \=.
<C-v>jjlU
Visual block mode lets you select rectangular regions of text, which means you can target a specific column and apply case changes only to that area.
=i{
When editing code with messy indentation — after a paste, a merge conflict, or a refactor — you often need to fix just one block rather than the entire file
:tab drop filename
When working with many tabs, you often want to open a file — but only if it is not already open somewhere.
:let @a = substitute(@a, 'old', 'new', 'g')
After recording a macro or yanking text into a named register, you may need to tweak it — fix a typo in a recorded macro, change a variable name in yanked tex
:s/^/\=line('.') - line("'<") + 1 . '. '/
When you need to quickly number a set of lines — such as TODO items, steps, or bullet points — you can use a visual selection combined with a substitution e
visual-mode #visual-mode #editing #ex-commands #formatting #substitute
:g/pattern/m 0
The :global command combined with :move lets you restructure a file by relocating all lines that match a pattern.
:packadd {package}
Vim ships with several useful packages in its opt/ directory that are not loaded by default.
:diffthis
You often have two files open side by side and want to compare them without leaving Vim or launching vimdiff.
:profile start profile.log
When Vim feels sluggish, the built-in :profile command lets you measure exactly how much time each script and function consumes.
:keeppattern s/old/new/g
When you run a :s or :g command, Vim updates the search register (@/) with the pattern you used.
<C-v>{char}
When you need to insert a literal tab character despite expandtab being set, or embed a control character like ^M (carriage return) into your text, in insert mo
editing #editing #insert-mode #special-characters #control-characters
:tag /pattern
When working with ctags, you typically jump to exact tag names with .
80i-<Esc>
Vim's insert commands accept a count prefix that repeats everything you type.