Vim CLI Integration
Integrating Vim with external commands and tools.
Open at Line Number
Open file at specific line
nvim +262 file.adoc
Open at last line
nvim + file.adoc
Open at line from variable
nvim +$LINE file.adoc
Open at Pattern
Open at first match of pattern
nvim +/pattern file.adoc
Open at pattern (case insensitive)
nvim +/\\cpattern file.adoc
Open at function definition
nvim +/^def\ my_func file.py
Open at section header
nvim +/^===\ Phase\ 3 runbook.adoc
Execute Command on Open
Run command after opening
nvim +":set wrap" file.adoc
Multiple commands
nvim +"set wrap" +"set linebreak" file.adoc
Search and center
nvim +/pattern +"normal zz" file.adoc
Open Multiple Files
Open multiple files
nvim file1.adoc file2.adoc file3.adoc
Open in vertical split
nvim -O file1.adoc file2.adoc
Open in horizontal split
nvim -o file1.adoc file2.adoc
Open in tabs
nvim -p file1.adoc file2.adoc file3.adoc
Open from Pipe
Read stdin
grep -rn 'pattern' . | nvim -
Pipe and open at line
echo "content" | nvim -
Diff Mode
Open two files in diff mode
nvim -d file1.adoc file2.adoc
Three-way diff
nvim -d file1 file2 file3
Read Only
Open read-only
nvim -R file.adoc
View mode (like less)
nvim -M file.adoc
Session and State
Open with session
nvim -S session.vim
No vimrc (vanilla)
nvim -u NONE file.adoc
Minimal config
nvim -u ~/.vimrc-minimal file.adoc
Remote / Server
Start server
nvim --listen /tmp/nvim.sock
Connect to server
nvim --server /tmp/nvim.sock --remote file.adoc
Send keys to server
nvim --server /tmp/nvim.sock --remote-send ':w<CR>'
Integration Patterns
Open from grep result (fzf)
grep -rn 'pattern' . | fzf | cut -d: -f1-2 | xargs -I{} sh -c 'nvim +$(echo {} | cut -d: -f2) $(echo {} | cut -d: -f1)'
Open file at grep match (simpler)
file=$(grep -rln 'pattern' .); line=$(grep -rn 'pattern' . | head -1 | cut -d: -f2); nvim +$line $file
Edit from find
find . -name "*.adoc" -exec nvim {} +
Edit all matching files
nvim $(grep -rl 'pattern' .)
Quick Edits
Edit and exit
nvim +"normal itext" +wq file.adoc
Append line and exit
nvim +"normal Go new line" +wq file.adoc
Substitute and exit
nvim +"%s/old/new/g" +wq file.adoc
Useful Aliases
Add to shell config
alias v='nvim'
alias vl='nvim +$1' # v +LINE
alias vp='nvim +/$1' # v +/PATTERN
alias vd='nvim -d' # diff mode
alias vs='nvim -O' # vertical split
Replace Text Without Losing Clipboard
" THE PROBLEM:
" You yanked "newValue", want to replace "oldValue"
" But vim's default: delete "oldValue" → overwrites register!
" SOLUTION 1: Black hole register
yiw " Yank replacement word
/oldValue<CR> " Find target
"_ciw<Ctrl+R>0<Esc> " Black hole change, paste yank
n. " Repeat (find next, repeat change)
" SOLUTION 2: Visual mode paste
yiw " Yank replacement word
/oldValue<CR> " Find target
viw"0p " Visual replace from yank register
n. " Repeat
" SOLUTION 3: Substitution
yiw " Yank word (now in register 0)
:%s/oldValue/<Ctrl+R>0/g " Replace all with yanked text
" PRACTICAL: Replace variable name
/userName<CR> " Find first occurrence
* " Select word under cursor
ciwnewName<Esc> " Change to new name
:%s/<Ctrl+R>//newName/gc " Replace rest with confirm
Multi-Line Editing
" BLOCK VISUAL MODE (columns)
<Ctrl+V> " Enter block visual mode
jjj " Select 4 lines
I " Insert at start of each
# <Esc> " Insert "# " on all lines
" APPEND TO MULTIPLE LINES
<Ctrl+V>jjj$ " Select to end of each line
A " Append mode
;<Esc> " Append ";" to all lines
" DELETE COLUMN
<Ctrl+V>jjj " Select column
d " Delete column
" REPLACE COLUMN
<Ctrl+V>jjj " Select column
c " Change
new text<Esc> " Replace with new text
" INDENT MULTIPLE LINES
Vjjj " Visual select lines
> " Indent
< " Outdent
= " Auto-indent
" COMMENT BLOCK (alternative)
V} " Select paragraph
:s/^/# /<CR> " Prepend # to each line
" UNCOMMENT BLOCK
V} " Select paragraph
:s/^# //<CR> " Remove leading #
Text Manipulation
" SORT LINES
:%sort " Sort entire file
:'<,'>sort " Sort selection
:%sort! " Reverse sort
:%sort u " Sort and remove duplicates
:%sort n " Numeric sort
:%sort i " Case-insensitive sort
" JOIN LINES
J " Join current and next line
gJ " Join without space
3J " Join 3 lines
V}J " Join paragraph
" SPLIT LINES
" At specific character:
f,a<CR><Esc> " Split at comma
:%s/, /,\r/g " Split all at comma-space
" DUPLICATE LINE
yy p " Yank and paste
yyp " Same, compact
:t. " Copy current line below (ex command)
:t-1 " Copy current line above
" MOVE LINE
dd p " Delete and paste below
ddkP " Delete and paste above
:m+1 " Move line down
:m-2 " Move line up
" REVERSE LINES
:g/^/m0 " Reverse all lines in file
:'<,'>!tac " Reverse selection (Linux)
" CHANGE CASE
~ " Toggle case of char
g~iw " Toggle case of word
gUiw " Uppercase word
guiw " Lowercase word
gUU " Uppercase line
guu " Lowercase line
Code Editing
" DELETE FUNCTION BODY
di{ " Delete inside braces
" OR
]}di{ " Jump to closing brace, delete inside
" CHANGE FUNCTION PARAMETERS
f( " Jump to opening paren
ci( " Change inside parens
" WRAP IN PARENS/BRACKETS
viw " Select word
c()<Esc>P " Wrap in parens
" OR with surround plugin: ysiw)
" ADD RETURN STATEMENT
O " Open line above
return <Ctrl+R>"<Esc> " Insert return + last yank
" SWAP ARGUMENTS
f, " Find comma
l " Move past space
dwbP " Delete word, paste before
" INCREMENT/DECREMENT NUMBERS
<Ctrl+A> " Increment number under cursor
<Ctrl+X> " Decrement number
5<Ctrl+A> " Add 5
10<Ctrl+X> " Subtract 10
" ALIGN EQUALS
" Use :Tabularize plugin or:
:'<,'>!column -t -s'=' -o'='
" AUTO-INDENT
=i{ " Auto-indent inside braces
=ap " Auto-indent paragraph
gg=G " Auto-indent entire file
Search and Replace
" REPLACE WORD UNDER CURSOR
* " Search for word
ciw " Change it
newWord<Esc> " Type replacement
n. " Repeat (find next, change)
" REPLACE ALL INSTANCES
* " Search for word
:%s//newWord/g " Replace (empty pattern = last search)
" SEARCH IN SPECIFIC FILES
:args **/*.yaml " Load YAML files
:argdo %s/old/new/ge | update " Replace in all
" SEARCH WITH CONTEXT
/pattern " Search
:g//p " Print all matches
:g//z#.5 " Show with context (5 lines)
" SEARCH AND DELETE
/pattern<CR> " Find pattern
gn " Visual select match
d " Delete
n. " Find next, delete
" SEARCH MULTIPLE PATTERNS
/error\|warning\|fatal " Match any
/\v(error|warning|fatal) " Very magic version
" SEARCH IN SELECTION
/\%Vpattern " Search within last visual selection
" PRESERVE CURSOR POSITION
ma " Mark position
:%s/old/new/g " Do replacements
`a " Return to mark
File Operations in Vim
" OPEN FILE UNDER CURSOR
gf " Go to file
<Ctrl+W>f " Open in new split
<Ctrl+W>gf " Open in new tab
" CREATE NEW FILE
:e newfile.txt " Create/open file
:e %:h/newfile.txt " Create in same directory
" SPLIT OPERATIONS
:sp filename " Horizontal split
:vs filename " Vertical split
<Ctrl+W>v " Split current vertically
<Ctrl+W>s " Split current horizontally
" BUFFER OPERATIONS
:ls " List buffers
:b name " Switch to buffer
:bd " Delete buffer
:bn " Next buffer
:bp " Previous buffer
" TAB OPERATIONS
:tabnew filename " New tab
gt " Next tab
gT " Previous tab
:tabclose " Close tab
" SAVE OPERATIONS
:w " Write
:w! " Force write
:w filename " Write as
:wa " Write all buffers
:up " Update (write only if changed)
" READ FROM FILE/COMMAND
:r filename " Insert file contents
:r !command " Insert command output
:0r filename " Insert at start of file
Infrastructure Configuration Examples
" EDIT SSH CONFIG HOST BLOCK
/^Host vault " Find host block
{ " Jump to start of block
V}k " Select block (excluding next Host)
:s/old\.example\.com/new.example.com/g " Update domain
" YAML: ADD ATTRIBUTE TO ALL ITEMS
" Before:
" - name: server1
" - name: server2
:g/^- name:/a\ enabled: true " Add after each match
" YAML: UPDATE NESTED VALUE
/environment: " Find section
/PORT: " Find nested key
f:w " Move to value
ciw8443<Esc> " Change value
" EDIT HOSTS FILE
" Add new entry:
G " Go to end
o10.50.1.60 vault-01<Esc> " Add new line
" Comment out entry:
/old-server<CR> " Find
I# <Esc> " Comment
" UPDATE ALL OLD IPS
:%s/192\.168\.1\./10.50.1./g " Subnet change
" ASCIIDOC: CONVERT HARDCODED TO ATTRIBUTE
" Before: 10.50.1.60
" After: {vault-ip}
:%s/10\.50\.1\.60/{vault-ip}/g
:%s/10\.50\.1\.20/{ise-ip}/g
:%s/10\.50\.1\.90/{bind-ip}/g
" ASCIIDOC: ADD subs=attributes+ TO CODE BLOCKS
:g/\[source,/s/]$/,subs=attributes+]/
" EXTRACT HOSTS FROM CONFIG
:g/^\d\+\.\d\+\.\d\+\.\d\+/y A " Collect IP lines
:new | "ap " New buffer, paste
" VALIDATE CONFIG (external)
:w | !yamllint % " Write and lint YAML
:w | !python -m json.tool % " Validate JSON
Practical Macro Examples
" MACRO: ADD SEMICOLON TO LINES
qa " Record to 'a'
A;<Esc>j " Append semicolon, next line
q " Stop
50@a " Apply to 50 lines
" MACRO: CONVERT LIST TO YAML
" Input: server1
" server2
" Output: - server1
" - server2
qa
I- <Esc>j " Prepend "- ", next line
q
100@a " Apply to all
" MACRO: EXTRACT VALUE FROM JSON-LIKE
" Input: "key": "value",
" Output: value
qa
0f"l " Find first quote, move in
yi" " Yank inside quotes
dd " Delete line
P " Paste value
j " Next line
q
" MACRO: SWAP KEY=VALUE TO VALUE=KEY
qa
0 " Start of line
/=<CR> " Find equals
"ad^ " Delete key to register a
x " Delete equals
$p " Paste key at end
i=<Esc> " Insert equals
j
q
" MACRO: NUMBER LIST ITEMS
:let i=1<CR> " Initialize counter
qa
I<Ctrl+R>=i<CR>. <Esc> " Insert number
:let i+=1<CR> " Increment
j
q
Advanced Vim Techniques
" DIFF TWO BUFFERS
:vsp " Vertical split
:e other_file " Open other file
:windo diffthis " Diff mode
:diffoff " Exit diff mode
" RECORD WINDOW LAYOUT
:mksession session.vim " Save session
:source session.vim " Load session
" EXECUTE REGISTER AS COMMAND
@: " Repeat last command
:@a " Execute register 'a' as ex commands
" REDIRECT OUTPUT TO REGISTER
:redir @a " Start redirecting to 'a'
:ls " Command whose output to capture
:redir END " Stop redirecting
"ap " Paste captured output
" EXPRESSION IN INSERT MODE
<Ctrl+R>=5*42<CR> " Insert calculation
<Ctrl+R>=strftime('%Y-%m-%d')<CR> " Insert date
<Ctrl+R>=system('hostname')<CR> " Insert command output
" QUICK FIX LIST (compiler errors, grep results)
:make " Run compiler
:copen " Open quickfix window
:cn " Next error
:cp " Previous error
:cdo s/old/new/g | update " Fix all errors
" GREP AND EDIT
:grep pattern **/*.adoc " Search files
:copen " View results
:cdo s/old/new/g " Edit all matches
" FOLD OPERATIONS
zf} " Create fold to end of paragraph
zo " Open fold
zc " Close fold
zR " Open all folds
zM " Close all folds
Quick Workflow Cheatsheet
" DAILY EDITING PATTERNS
" 1. Open, edit, save
vim file.txt " Open
:w " Save
:wq or ZZ " Save and quit
:q! or ZQ " Quit without saving
" 2. Find and replace word
* " Find word under cursor
ciwnewword<Esc> " Change first occurrence
n. " Repeat for others
" 3. Comment multiple lines
<Ctrl+V>jjj " Block select
I# <Esc> " Insert comment
" 4. Delete lines matching pattern
:g/DEBUG/d " Delete debug lines
" 5. Reindent file
gg=G " Auto-indent all
" 6. Remove trailing whitespace
:%s/\s\+$//g
" 7. Sort imports
:1,/^$/sort " Sort until first blank line
" 8. Extract specific lines
:g/pattern/y A " Yank matches
:new | "ap " New buffer, paste
" 9. Diff current changes
:w !diff -u % - " Diff saved vs current
" 10. Quick documentation lookup
K " Look up word under cursor
Neovim-Specific Features
" TERMINAL MODE
:terminal " Open terminal
:split | terminal " Terminal in split
<Ctrl+\><Ctrl+N> " Exit terminal mode
:TermClose " Close terminal
" LSP FEATURES (with configured LSP)
gd " Go to definition
gr " Find references
K " Hover documentation
<leader>rn " Rename symbol
<leader>ca " Code actions
<leader>f " Format
" TREESITTER FEATURES
:TSHighlightCapturesUnderCursor " Debug highlights
:TSPlaygroundToggle " Syntax tree viewer
" FLOATING WINDOWS
:lua vim.lsp.buf.hover() " LSP hover in float
:help nvim_open_win " Create floating window
" TELESCOPE (fuzzy finder)
<leader>ff " Find files
<leader>fg " Live grep
<leader>fb " Find buffers
<leader>fh " Find help
" WHICH-KEY (keybinding helper)
" Press leader and wait - shows available bindings
" LUA CONFIG
:lua print(vim.inspect(vim.opt.tabstop)) " Inspect setting
:lua =vim.bo.filetype " Print filetype
:e ~/.config/nvim/init.lua " Edit config
:source % " Reload config