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) orI
(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) orA
(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
andG
respectively - To move to the beginning and end of the line type
0
and$
respectively - To move forward or backward one word press
w
andb
respectively - To insert a line below or above the current line type
o
andO
respectively - To undo type
u
, to redo pressCtrl + 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
andgT
- To switch between splits press
Ctrl + w <movement keys>
orCtrl + w + w
- To start recording a macro press
q<letter>
, then execute actions/commands and presq
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 type
q
- 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
andtabnext
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:
- Using Macros in Vim, by @Garrit
- Strategies to use a terminal alongside (Neo)Vim by @Garrit
- A great Vim Cheat Sheet
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
else
set signcolumn=yes
endif
" 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'
endfunction
" Use <c-space> to trigger completion.
if has('nvim')
inoremap <silent><expr> <c-space> coc#refresh()
else
inoremap <silent><expr> <c-@> coc#refresh()
endif
" 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')
else
execute '!' . &keywordprg . " " . expand('<cword>')
endif
endfunction
" 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
autocmd!
" 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>"
endif
" 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 #100DaysToOffload
Join 100DaysToOffload!
21 responses to “My (Neo)Vim Cheatsheet”
@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
@hejowhat glad you liked it, useful additions, thanks!
@lopeztel related: https://slashdev.space/posts/2021-02-24-vim-terminal-strategies
Strategies to use a terminal alongside (Neo)Vim
@garritfra @lopeztel Hi Garrit, just small correction to your post, vim doesn’t come with the :term command, or at least not older versions, but nvim does, so if you’re on an older system at least it’s likely that it won’t work.
@garritfra @lopeztel correction to my correction, that’s probably a bit outdated, it seems the new vim has it 😉
@sotolf @lopeztel Yep, :term was introduced in Vim 8.1, which is about a year or so old. 🙂
@garritfra @lopeztel Yeah, I think neovim has had it for a longer time, it’s good for them both that vim has started working more on features than what it was earlier. I moved over to neovim before the change for my main machine, so I was not quite updated on what vim had as a feature, and tested it on a older ubuntu server, which didn’t have it :p
@garritfra @lopeztel I just got mind blown with the :term command 🤯
@garritfra this is such a nice addition, I’ll need to edit my original post to add it
@sotolf @garritfra it’s actually quite cool, also works in windows (why on earth you would do that beats me but it’s there).I guess I could use it for git …. oh wait, windows messes up my file permissions…
@cybernomad @lopeztel literally me a few hours ago.😂
@lopeztel @garritfra if you have to work on windows why not use vim in wsl? that has been no problems for me this far.
@sotolf @garritfra I tried but everything is useless when I have to ssh into a server to do things (sshfs didn’t help)
@lopeztel @sotolf > Why on earth would you do that?What, windows?(*Cricket noises*)
@lopeztel @garritfra I ssh into servers and work in their vims on the server without problems, what is it with vim over ssh that doesn’t work for you?
@lopeztel @ndanes I’ll likely copy that entire list if that’s okay with you
@brandon @ndanes by all means, go ahead
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 youintegrate 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 theprocess, simply issue the
fg
command and Vims process resumes in theforeground.
Conclusion
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
@lopeztels
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
Likes
Reposts
Mentions