My (Neo)Vim Cheatsheet

I’ve been learning to use neovim for almost 3 weeks now and it has been fun, coming from VSCode I guess I was spoiled by the feature rich IDE/text editor, however there is beauty in the simplicity keyboard oriented (Neo)vim text editor

I’ve been trying to get all the useful keyboard shortcuts and commands I’ve found in a single place and I though this could be helpful for other noobs like me, fosstodon community was helpful and shared their Tips n’ Tricks as well.

The Cheatsheet

This list is by no means a complete compendium but it is what I’ve found most useful and basic

  • To enter NORMAL mode press Esc
  • To enter INSERT mode type i (cursor position) or I (beginning of the current line)

From NORMAL mode:

  • To enter VISUAL mode type v
  • To enter VISUAL LINE mode type V
  • To enter VISUAL BLOCK mode press Ctrl + v
  • To append text type a (cursor position) or A (end of the current line)
  • To navigate the document left, down, up and right press h, j, k, l respectively (or use the arrow keys)
  • To go to the top and end of the document, type gg and G respectively
  • To move to the beginning and end of the line type 0 and $ respectively
  • To move forward or backward one word press w and b respectively
  • To insert a line below or above the current line type o and O respectively
  • To undo type u, to redo press Ctrl + r
  • To repeat an action press .
  • To move between last opened files press Ctrl + i (newer) Ctrl + o (older)
  • To swap lines type ddp
  • To swap two characters type xp
  • To remove the current character type x
  • To replace the current character type r<character>
  • To correct a word (from the cursor position) type cw
  • To correct a word (regardless of the cursor position) type ciw
  • To scroll down the document so that only the last line is visible type Ctrl + f
  • To search the document type /<search term>
  • To go to next and previous tabs type gt and gT
  • To switch between splits press Ctrl + w <movement keys> or Ctrl + w + w
  • To start recording a macro press q<letter>, then execute actions/commands and pres q to stop recording
  • To execute a macro type @<letter>, to execute the macro again type @@
  • To enter COMMAND mode type :

From COMMAND mode:

  • To close a file typeq
  • To close a file discarding any changes type q!
  • To close the text editor and all opened files type qa
  • To save your changes to a file type w
  • To save your changes and quit all open tabs wqa
  • To read the help documentation about a topic type help <topic string>
  • To read the help documentation about commands associated to a key type help <key>
  • To open a new tab type tabnew <optional file>
  • To switch between opened tabs type tabprevious and tabnext respectively
  • To open a new horizontal split type split <optional file>
  • To open a new vertical split type vsplit <optional file>
  • To search and replace globally type %s/<regex or search term>/<replace term>/g<optional nc for confirmation>
  • To “open a terminal” type term

From VISUAL LINE mode:

  • To reflow text type gq

Additional resources:

My current configuration

I thought that just for fun I’d share my init.vim (as of now, since I am still tweaking it) in case someone finds it useful:

" Author: Lopeztel
" Description: Lopeztel's nvim config
" Last Modified: February 20, 2021

" Startify
let g:startify_custom_header= [
\ '                      _                         _       _                      ', 
\ '                     | |    ___  _ __   ___ ___| |_ ___| |                     ',
\ '                     | |   / _ \| ._ \ / _ \_  / __/ _ \ |                     ',
\ '                     | |__| (_) | |_) |  __// /| ||  __/ |                     ',
\ '                     |_____\___/| .__/ \___/___|\__\___|_|                     ',
\ '                                |_|                                            ',
\ '                                                                               ',
\ ]
call plug#begin('~/.vim/plugged')

Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'arcticicestudio/nord-vim'
Plug 'vim-airline/vim-airline'
Plug 'tpope/vim-fugitive'
Plug 'tpope/vim-rhubarb'
Plug 'junegunn/gv.vim'
Plug 'honza/vim-snippets'
Plug 'junegunn/fzf'
Plug 'junegunn/fzf.vim'
Plug 'mhinz/vim-startify'
Plug 'godlygeek/tabular'
Plug 'plasticboy/vim-markdown'
Plug 'rhysd/vim-clang-format'
Plug 'preservim/nerdcommenter'
" Plug 'liuchengxu/vim-which-key'

call plug#end()

" Set colorscheme
colorscheme nord

" vim-airline settings
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#formatter = 'unique_tail'
let g:airline_powerline_fonts = 1
" let g:Powerline_symbols = 'fancy'

" Map the leader key to SPACE
let mapleader="\<SPACE>"

" set line numbers 
set number
" More natural splits
set splitbelow          " Horizontal split below current.
set splitright          " Vertical split to right of current.

" Set spell check to English
 autocmd FileType markdown setlocal spell spelllang=en_us

" Configuration for vim-markdown
let g:vim_markdown_folding_disabled = 1
let g:vim_markdown_math = 1
let g:vim_markdown_toml_frontmatter = 1
let g:vim_markdown_frontmatter = 1
let g:vim_markdown_strikethrough = 1
let g:vim_markdown_autowrite = 1
let g:vim_markdown_edit_url_in = 'tab'
let g:vim_markdown_follow_anchor = 1

" TextEdit might fail if hidden is not set.
set hidden

" Some servers have issues with backup files, see #649.
set nobackup
set nowritebackup

" Give more space for displaying messages.
set cmdheight=2

" Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable
" delays and poor user experience.
set updatetime=300

" Don't pass messages to |ins-completion-menu|.
set shortmess+=c

" Always show the signcolumn, otherwise it would shift the text each time
" diagnostics appear/become resolved.
if has("patch-8.1.1564")
  " Recently vim can merge signcolumn and number column into one
  set signcolumn=number
  set signcolumn=yes

" Use tab for trigger completion with characters ahead and navigate.
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
" other plugin before putting this into your config.
inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'

" Use <c-space> to trigger completion.
if has('nvim')
  inoremap <silent><expr> <c-space> coc#refresh()
  inoremap <silent><expr> <c-@> coc#refresh()

" Make <CR> auto-select the first completion item and notify coc.nvim to
" format on enter, <cr> could be remapped by other vim plugin
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
                              \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"

" Use `[g` and `]g` to navigate diagnostics
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)

" GoTo code navigation.
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

" Use K to show documentation in preview window.
nnoremap <silent> K :call <SID>show_documentation()<CR>

function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  elseif (coc#rpc#ready())
    call CocActionAsync('doHover')
    execute '!' . &keywordprg . " " . expand('<cword>')

" Highlight the symbol and its references when holding the cursor.
autocmd CursorHold * silent call CocActionAsync('highlight')

" Symbol renaming.
nmap <leader>rn <Plug>(coc-rename)

" Formatting selected code.
xmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>f  <Plug>(coc-format-selected)

augroup mygroup
  " Setup formatexpr specified filetype(s).
  autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
  " Update signature help on jump placeholder.
  autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end

" Applying codeAction to the selected region.
" Example: `<leader>aap` for current paragraph
xmap <leader>a  <Plug>(coc-codeaction-selected)
nmap <leader>a  <Plug>(coc-codeaction-selected)

" Remap keys for applying codeAction to the current buffer.
nmap <leader>ac  <Plug>(coc-codeaction)
" Apply AutoFix to problem on the current line.
nmap <leader>qf  <Plug>(coc-fix-current)

" Map function and class text objects
" NOTE: Requires 'textDocument.documentSymbol' support from the language server.
xmap if <Plug>(coc-funcobj-i)
omap if <Plug>(coc-funcobj-i)
xmap af <Plug>(coc-funcobj-a)
omap af <Plug>(coc-funcobj-a)
xmap ic <Plug>(coc-classobj-i)
omap ic <Plug>(coc-classobj-i)
xmap ac <Plug>(coc-classobj-a)
omap ac <Plug>(coc-classobj-a)

" Remap <C-f> and <C-b> for scroll float windows/popups.
if has('nvim-0.4.0') || has('patch-8.2.0750')
  nnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
  nnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
  inoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<Right>"
  inoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<Left>"
  vnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
  vnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"

" Use CTRL-S for selections ranges.
" Requires 'textDocument/selectionRange' support of language server.
nmap <silent> <C-s> <Plug>(coc-range-select)
xmap <silent> <C-s> <Plug>(coc-range-select)

" Add `:Format` command to format current buffer.
command! -nargs=0 Format :call CocAction('format')

" Add `:Fold` command to fold current buffer.
command! -nargs=? Fold :call     CocAction('fold', <f-args>)

" Add `:OR` command for organize imports of the current buffer.
command! -nargs=0 OR   :call     CocAction('runCommand', 'editor.action.organizeImport')

" Add (Neo)Vim's native statusline support.
" NOTE: Please see `:h coc-status` for integrations with external plugins that
" provide custom statusline: lightline.vim, vim-airline.
set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}

" Mappings for CoCList
" Show all diagnostics.
nnoremap <silent><nowait> <space>a  :<C-u>CocList diagnostics<cr>
" Manage extensions.
nnoremap <silent><nowait> <space>e  :<C-u>CocList extensions<cr>
" Show commands.
nnoremap <silent><nowait> <space>c  :<C-u>CocList commands<cr>
" Find symbol of current document.
nnoremap <silent><nowait> <space>o  :<C-u>CocList outline<cr>
" Search workspace symbols.
nnoremap <silent><nowait> <space>s  :<C-u>CocList -I symbols<cr>
" Do default action for next item.
nnoremap <silent><nowait> <space>j  :<C-u>CocNext<CR>
" Do default action for previous item.
nnoremap <silent><nowait> <space>k  :<C-u>CocPrev<CR>
" Resume latest coc list.
nnoremap <silent><nowait> <space>p  :<C-u>CocListResume<CR>

" Coc-explorer
let g:coc_explorer_global_presets = {
\   '.vim': {
\     'root-uri': '~/.vim',
\   },
\   'tab': {
\     'position': 'tab',
\     'quit-on-open': v:true,
\   },
\   'floating': {
\     'position': 'floating',
\     'open-action-strategy': 'sourceWindow',
\   },
\   'floatingTop': {
\     'position': 'floating',
\     'floating-position': 'center-top',
\     'open-action-strategy': 'sourceWindow',
\   },
\   'floatingLeftside': {
\     'position': 'floating',
\     'floating-position': 'left-center',
\     'floating-width': 50,
\     'open-action-strategy': 'sourceWindow',
\   },
\   'floatingRightside': {
\     'position': 'floating',
\     'floating-position': 'right-center',
\     'floating-width': 50,
\     'open-action-strategy': 'sourceWindow',
\   },
\   'simplify': {
\     'file-child-template': '[selection | clip | 1] [indent][icon | 1] [filename omitCenter 1]'
\   }
\ }

nmap <space>e :CocCommand explorer<CR>
nmap <space>ef :CocCommand explorer --preset floating<CR>
autocmd BufEnter * if (winnr("$") == 1 && &filetype == 'coc-explorer') | q | endif

" clang-format configuration
let g:clang_format#style_options = {
            \ "AccessModifierOffset" : -4,
            \ "AllowShortIfStatementsOnASingleLine" : "true",
            \ "AlwaysBreakTemplateDeclarations" : "true",
            \ "Standard" : "C++11"}

" map to <Leader>cf in C++ code
autocmd FileType c,cpp,objc nnoremap <buffer><Leader>cf :<C-u>ClangFormat<CR>
autocmd FileType c,cpp,objc vnoremap <buffer><Leader>cf :ClangFormat<CR>
" Toggle auto formatting:
nmap <Leader>C :ClangFormatAutoToggle<CR>

" Nerd Commenter
" " Use compact syntax for prettified multi-line comments
let g:NERDCompactSexyComs = 1
" " Allow commenting and inverting empty lines (useful when commenting a region)
let g:NERDCommentEmptyLines = 1
" " Enable trimming of trailing whitespace when uncommenting
let g:NERDTrimTrailingWhitespace = 1
" " Enable NERDCommenterToggle to check all selected lines is commented or not
let g:NERDToggleCheckAllLines = 1
" " Add spaces after comment delimiters by default
let g:NERDSpaceDelims = 1

vmap <Leader>/ <plug>NERDCommenterToggle
nmap <Leader>/ <plug>NERDCommenterToggle

Day 51 of my 2020’s

Join 100DaysToOffload!

21 responses to “My (Neo)Vim Cheatsheet”

  1. @lopeztel Wasn’t aware of ctrl + f, great!Some suggestions:# Search term/search term (forwards)?search term (backwards)n to jump to the next resultN to jump to the previous# Jump within the windowH – topM – middleL – bottom# Change/delete/copy things between:cit – change content between tags <>di” – delete content between quotes “yi( – copy content within those brackets

  2. One thing that bothered me about vim for a long time, was the lack of a terminal
    directly in your editor. If I’m not using Vim, I’m most definetely using VSCode
    and its built-in Terminal. After searching the webs for possible solutions, I
    came across a couple of strategies to achive this.
    Executing single commands
    If you just want to issue a single command without spawning an entire shell,
    you can just use the :! command:
    :! printf "Hello Sailor"

    Vims builtin terminal
    I couldn’t believe my eyes when I read this, but Vim ships with a builtin
    terminal! Executing :term will spawn it in your current buffer. How you
    integrate it in your workflow is up to you. You could use tabs or open a
    horizontal buffer and spawn it there. I must say that it is rather clunky to
    use, since its literally a Vim buffer that forwards stdin and stdout to the
    buffer, but it’s there for you to use.
    Vim x Tmux
    Another great alternative is to set up Tmux with two windows, one for Vim and
    one for your terminal, and switch between them. This works great on a minimal
    system, but on MacOS for example, it is easier to simply use cmd+1 and cmd+2 to
    switch between two tabs of the Terminal application.
    Pausing and resuming Vim
    This one is my personal favorite. The idea comes from
    this stackoverflow answer.
    The plan is to pause the Vim process and resume it later. To pause Vim, you
    press <ctrl>-z. This sends the process in the background. Then, to resume the
    process, simply issue the fg command and Vims process resumes in the
    I’m sure there are many more strategies that could be added to this list. I’d be
    interested to hear how your setup works! If you liked these techniques, you
    might be interested in
    cheat sheet for Vim.
    This is post 014 of #100DaysToOffload.If you enjoyed this post, consider buying me a coffee! Got comments? Send me a Mail, or shoot me a message on Matrix.Written By: Garrit Franke


  • Nicholas :fedora:


  • Garrit's Notes

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Proud member of the 512kb club, blue team