Vim cheatsheet

2024-06-03

Vim has soul. It is that chisel you inherited from your grandpa that you keep using. It fits well in your grip and is comfortable, even though it lacks the soft rubber that the new ones in the store have. It’s a tool with its own history.1

I’ve been using Vim since I started with Linux, and it quickly became one of the tools that drew me to the platform. As a terminal-based text editor derived from vi, which dates back to 1977, Vim (or vi) is typically pre-installed on Unix systems, making it a common encounter for anyone working with Unix terminals.

While I currently use Neovim, the core principles remain the same. Once you become proficient with the basic movements, Vim’s verbs, and modes, the keybindings become second nature. However, reaching this level of proficiency requires a solid initial understanding. More importantly, I choose Vim not only for its efficiency but also because it makes programming and text editing genuinely enjoyable.

Down the years I’ve noted some of the most used vim motions and commands I’ve been using.

movements#

%       # go to other end of parenthesis
*       # next match the current instance under the cursor( replaces the search string, thus n N work)
#       # previous match of the current instance under the cursor
+       # beginning of the next line, non-whitespace
-       #  beginning of the previous line
(       #  beginning of sentence/ previous
)       # end of sentence
{       # go to the beginning of current paragraph
}       # go to the beginning of next paragraph
g_      # go to the last non-whitespace character


f[.]    #searches linewise and to repeat that linewise search use a semicolon ;  
        #comma , does the backward searching.

F[.]    #searches linewise in backward direction.

:marks  #m[..]  marks and '[..] to go to that marked position

linewise#

[n0]G/gg  : go to that line
      same as :[n0]<Enter>

:jumps    
[no.]Ctrl-o/i   # jump no.     to the previous/next(depending on >(location 0)) spot

C-o             # go back to where you came from
C-i             # go forward to where you came from

gi              # go to the last edit/insert position
g;              # jump to the last change
g,              # jump back through the change list

page#

^E          # the text moves upward in the screen, doesn't change the current cursor line.
H/M/L       # go to the topmost/middle/lowest line/part of the screen contents.
Ctrl-d/u    # move half page down/up
C-f/b       # one page down/up
zt          # put this line on top
zb          # put this line on bottom

File operations#

:g/^/m 0      # reverse all lines in file

==            # indent the line as of line above
gg=G          # Reindent the whole file

sort#

:sort         # Sorts the line 
:sort!        # Sort in descending order
:sort i       # Ignore case while sorting
:sort u       # Remove duplicate lines
:sort! ui     # Combining above options

state changes#

u               # undo 
Ctrl-r          # Redo 

:earlier [n]m   #  go back to n minutes earlier
:later [n]m     # revert back the earlier changes

blocks and tags#

ca/i[(/)[{}]]      #allows changes around,inside parenthesis/blocks

da/i[....]         #deletes around/inside parenthesis/blocks

"[]yi/a[blocks]    #to yank the content inside/around of blocks

cit, dit, dat,cat  #allows changing and deleting in and aroung html like tags.

"[]ya/is           #yanks around and inside sentence 

repeat something#

30i/I/a/A   #horizontally
3o/O        #vertically     

case changing#

visual mode is easier

~           #change the case of the character
g~w         #change the case of the word
g~~         #change the case of the entire line
gu/Uw       #change the case of the word to either uppercase/lowercase

visual mode#

gv         #selects the visual text again

viw/W      #selects the word no matter where the cursor is
yiw/W   

vap        #visually select a paragraph
vip        #visually select inside paragraph 

vi/a[block]    #visual mode the content in/around blocks.
vi/at          #visual mode the content in/around tags.


:w [file_name]        #writes the selected content to a new file.

U/u                   #changes the case to uppercase/lowercase

:center/right/left    #align the visually selected text again.

# o to toggle to top and bottom of the visually selected area

# programming
press v and % sign to visually select the whole content/function, ex {..}

/^#               # search every line starting with #

appending/inserting things#

CTRL-V to enter visual block mode 
$ to move the cursor to the end of the line 
A to append , I to prepend
enter your text 
ESC

column of increasing numbers#

<C-v>GI0 <ESC>gvg<C-a>
<C-v> visual block mode (:help visual-block)
G is select to the bottom of the screen (:help G)
I starts insert mode on line 1 (:help v_b_I)
0  enter a literal zero and a literal space
<ESC> go back to normal mode
gv reselect the last visual selection (all of column 1) (:help gv)
g<C-a> increment sequentially all numbers in the selection (:help v_g_CTRL-A

[no.]^x  : decrease the numerical value by 1

Delete#

X       # delete the character before the cursor.
x       # deletes the character at the cursor.

dd      # deletes the whole line regardless of the cursor position.
D       # deletes to the end of line
C       # change to the end of the line  
**c applies where d applies except it puts us in insert mode

daw     # delete a word(cursor postion doesn't matter)
dap     # delete a paragraph
d{/}    # deletes one paragraph up/down

y,d/../e      #yank/delete till search pattern

pattern#

:g/pattern/d      #Delete all the lines matching the pattern
:g!/pattern/d     #reverse of above
:v/pattern/d  

:g/^#/d           #delete all the lines starting with #  g=>global d=>delete
:g/^\s*$/d        #deleting all lines that are empty or that contain whitespace only
:g!/^\s*#/d       #delete all the lines that are not comment

:v/error\|warn\|fail/d      # delete all lines except that contain error,warn or fail

:g/^\s*\/\/.*$/d


functions#

#Generating numbered lists
:put =range(1,10)
:28put =range(6,87)   #insert numbers after a particular line number.

#Generating IP address list
:for i in range(1,100) | put ='192.168.0.'.i | endfor

:TOhtml     #make a html file using current color scheme

registers#

"0p/P     #paste the last yanked text/line
"[a-z]yy  #using named registers to yank characters.
"ap/P     #to paste the content of the named registers

"Ayy      #append this content to the named a register, pasting as usual

:reg      #to look at the contents of all the registers
:reg ab   #only to view the contents of a & b registers.

Macros#

q[a/.]      to start recording the macro to register a

normalize cursor position, make necessary changes in the line,
escape it and press j/k for motion, type q to stop recording the macro.

@@          repeats the last macro used.
:reg [m]    to see the contents inside of macro_register.
@[a/.]      use that macro on current line.
[no]@[a/.]  repeats the macro on [no.] of lines.

q[A-Z]      to append to the previous macro recorded at [a-z]

:[s_no.],[e_no.] normal @[r_alphabet]     to apply macro to certain line ranges.

Dictionary, spelling#

:set spell      #to enable spell checking.
]s              moves from one misspelled word to another.
[s              moves to backward misspelled word.
[]/S            moves to real misspelled words, ignores regional dictionary/spelling.

z=          to see other spelling options for any word.
zg          adds word to the dictionary(g=good)
zug         undo adding words to the dictionary.
zw          add any(correct/not) word to the wrong dictionary.
zuw         undo adding any(correct/not) word to the wrong dictionary.

abbreviation#

#bp,  put it in vimrc 
:abbr          # shows all abbreviations
:abbr url pawanchhetri.com.np      
url!           #   to expand
:noabbr mws    # remove abbreviation 
:iabbrev TRR Thanks,<CR>Regards,<CR>pawanchhetri

External plugins#

vscode vim plugin#

{
    "vim.commandLineModeKeyBindings": [
        {
            "before": ["j", "j"],
            "after": ["<esc>"]
        }
    
    ],
  "vim.normalModeKeyBindingsNonRecursive": [
    
    ],
    "files.autoSave": "afterDelay",
    "window.menuBarVisibility": "toggle",
    "editor.minimap.enabled": false,
    "workbench.startupEditor": "newUntitledFile",
    "window.zoomLevel": 1,
    "editor.renderLineHighlight": "none",
}

vimium browser extension#

Insert your preferred key mappings here.
unmap d
map d removeTab
map u restoreTab
map K previousTab
map J nextTab
unmap <c-e>
unmap <c-y>

Excluded URLs and keys
https?://www.youtube.com/watch*    f

Custom search engines
w: https://www.wikipedia.org/w/index.php?title=Special:Search&search=%s Wikipedia
y: https://www.youtube.com/results?search_query=%s Youtube
d: https://duckduckgo.com/?q=%s DuckDuckGo
g: https://www.google.com/search?q=%s Google
r: https://www.reddit.com/search/?q=%s Reddit
f: https://www.facebook.com/search/people/?q=%s facebook people
t: https://twitter.com/search?q=%s&src=typed_query

Sessions#

:mksession!   #Vim records the current session in a Session.vim file in the current working directory.
:vim -S       #Restores the previously recorded session.

templates#

#Using file templates, for html, docker ... files
$ mkdir ~/.vim/templates
$ vi ~/.vim/templates/html.tpl

<html>
  <head>
    <title></title>
  </head>
  <body>
    <p>My content here.</p>
  </body>
</html>

#Add this to the .vimrc. to autoload this template every time new .html file is created
:autocmd BufNewFile *.html 0r ~/.vim/templates/html.tpl   

vimwiki#

Leader + ww    = open the vimwiki
Leader + wt    = open the vimwiki in new tab
Press enter on the wiki page text to create a link underneath
[[ link_name ]]    = creates a link
[[ link_name | display_name ]]  = display_name is dispalyed in the link name
Tab/ Shift-Tab     = move to link_name down/up 
Backspace to get back to index.wiki from link page

1./ a) / */ -     = creates list 

Todo lists
Ctrl + space = add a checkbox
Ctrl + space = toggle a checkbox
gl + spcae = remove a checkbox



VimwikiDiary
Leader + wi = open the diary in the wiki, sorts/maintains diary on diary.wiki page
Leader w Leader w = open/create the diary for today
Leader w Leader y = open/create the diary for yesterday
Leader w Leader m = open/create the diary for tomorrow

Extraa#

:set paste          # allows pasting w/o indentation mess

:h [^g/:command/topic]   # h is the short version of the help

z=    # opens up spell check dictionary

C-g  # show your location in the file and file status.

daw   # delete a word(cursor postion doesn't matter)
dap   # delete a paragraph

xp    # to paste it afterward to fix spelling/typing mistakes by swapping characters.

C-x C-f for completing file names too, as well as
C-x C-l for completing entire lines.

cgn jumps to the next search match and applies c to it, letting you change the next search match. You can then press . to automatically replace the next match, and the next, and the next.  
For small find and replaces I find it more convenient than using :s
search something first  type cgn make changes to it and then . to make changes to other matches one by one.


I find the ability to insert command output into my file very useful using "bang bang" (!!) in command mode really useful: !!command will put that commands output right at your cursor's location. You can even use a pipeline and it will put in the end of the pipe's output there. Something like: 
!!cut -d' ' -f2 filename|sort|uniq 
will work just fine. This has saved me time and let me avoid using temp files.

C-f   while on command modes : shows the recent command history as a vim page

:%s/old/new/gc  # substitute with prompt
&   = repeat last substitution, in the current line
g&  = repeat last substitution on all lines 



Seven habits of effective text editing: Bram Moolenaar


1

https://news.ycombinator.com/item?id=37082377