After spending all of last year learning Vim and Neovim, I thought I’d share some items from my cheat sheet that make me really productive in Neovim.
Motions, Windows, & Editing
Previous curly: [{
Next curly: ]}
Previous method beginning: [m
Next method beginning: ]m
Previous method ending: [M
Next method ending: ]M
Change tab: gt
Change pane: Ctrl+VIM_KEY
Rotate windows: Ctrl+W R
Resize width: Ctrl+W < or >
Resize equally: Ctrl+W =
Resize horizontal: Ctrl+W — or +
Ctrl + w _ — Make window larger vertically
Ctrl + w | — Make window larger horizontally
Ctrl + x — swap vertical splits
Ctrl + w + — VIM_KEY to move window
Ctrl+W T split buffer into new tab
C — change to end of line
cc — remove and edit line
D — delete to end of line
dap — delete contiguous lines of code and whitespace
dip — delete contiguous lines of code only
~ — Capitalize visual selection
ZZ — save and close buffer
ZQ — close buffer without saving
Delete when in insert mode
Ctrl+h — Delete previous char
Ctrl+w — Previous word
Ctrl+u — Entire line (except indent)
Indent / backdent when in insert mode
Ctrl+t — Indent the current line
Ctrl+d — Backdent the current line
Center screen: zz
Macros
start — qw
end — q
apply — 3@w
Ctrl + r then “ — search with what was in paste buffer
Ctrl+i / Ctrl+o — go through jump list
Marks (capital letter for across buffers)
set mark: mA
jump to mark: ‘A
jump to mark column: `A
o — when in visual selection to jump to beginning or end
:vimgrep /asdf/ % — search for asdf in current file
:vimgrep /asdf/ **/*.rb — search for asdf in current directory
Ctrl+v — go into visual block selection mode
let @+=@% copy current filename
Keymappings
-- Exit insert mode without hitting Esc
vim.keymap.set("i", "jj", "<Esc>", { desc = "Esc" })
-- Make Y behave like C or D
vim.keymap.set("n", "Y", "y$")
-- close buffer
vim.keymap.set("n", "<leader>q", "<cmd>bd<CR>", { desc = "Close Buffer" })
-- Close buffer without closing split
vim.keymap.set("n", "<leader>w", "<cmd>bp|bd #<CR>", { desc = "Close Buffer; Retain Split" })
-- Navigate between quickfix items
vim.keymap.set("n", "<leader>h", "<cmd>cnext<CR>zz", { desc = "Forward qfixlist" })
vim.keymap.set("n", "<leader>;", "<cmd>cprev<CR>zz", { desc = "Backward qfixlist" })
-- Navigate between location list items
vim.keymap.set("n", "<leader>k", "<cmd>lnext<CR>zz", { desc = "Forward location list" })
vim.keymap.set("n", "<leader>j", "<cmd>lprev<CR>zz", { desc = "Backward location list" })
-- Dismiss Noice Message
vim.keymap.set("n", "<leader>nd", "<cmd>NoiceDismiss<CR>", {desc = "Dismiss Noice Message"})
-- Resize with arrows
vim.keymap.set("n", "<C-S-Down>", ":resize +2<CR>", { desc = "Resize Horizontal Split Down" })
vim.keymap.set("n", "<C-S-Up>", ":resize -2<CR>", { desc = "Resize Horizontal Split Up" })
vim.keymap.set("n", "<C-Left>", ":vertical resize -2<CR>", { desc = "Resize Vertical Split Down" })
vim.keymap.set("n", "<C-Right>", ":vertical resize +2<CR>", { desc = "Resize Vertical Split Up" })
-- Visual --
-- Stay in indent mode
vim.keymap.set("v", "<", "<gv")
vim.keymap.set("v", ">", ">gv")
-- Move block
vim.keymap.set("v", "J", ":m '>+1<CR>gv=gv", { desc = "Move Block Down" })
vim.keymap.set("v", "K", ":m '<-2<CR>gv=gv", { desc = "Move Block Up" })
-- Search for highlighted text in buffer
vim.keymap.set("v", "//", 'y/<C-R>"<CR>', { desc = "Search for highlighted text" })
-- Exit terminal mode shortcut
vim.keymap.set("t", "<C-t>", "<C-\\><C-n>")
-- Autocommands
vim.api.nvim_create_augroup("custom_buffer", { clear = true })
-- start terminal in insert mode
vim.api.nvim_create_autocmd("TermOpen", {
desc = "Auto enter insert mode when opening a terminal",
group = "custom_buffer",
pattern = "*",
callback = function()
-- Wait briefly just in case we immediately switch out of the buffer (e.g. Neotest)
vim.defer_fn(function()
if vim.api.nvim_buf_get_option(0, 'buftype') == 'terminal' then
vim.cmd([[startinsert]])
end
end, 100)
end,
})
-- highlight yanks
vim.api.nvim_create_autocmd("TextYankPost", {
group = "custom_buffer",
pattern = "*",
callback = function() vim.highlight.on_yank { timeout = 200 } end
})
Plugins
Vim-unimpaired
[ + space — Add line above
] + space — add line Below
[ + q — Next item in quickfixlist
[ + q — Previous item in quickfixlist
Telescope
Extensions
require("telescope").load_extension("neoclip")
require("telescope").load_extension("fzf")
require("telescope").load_extension("ui-select")
vim.g.zoxide_use_select = true
require("telescope").load_extension("undo")
require("telescope").load_extension("advanced_git_search")
require("telescope").load_extension("live_grep_args")
Keymaps
vim.keymap.set('n', '<leader>ff', builtin.find_files, { desc = "Find Files"})
vim.keymap.set('n', '<leader>fg', "<cmd>lua require('telescope').extensions.live_grep_args.live_grep_args()<CR>", { desc = "Live Grep"})
vim.keymap.set('n', '<leader>fc', '<cmd>lua require("telescope.builtin").live_grep({ glob_pattern = "!{spec,test}"})<CR>', { desc = "Live Grep Code"})
vim.keymap.set('n', '<leader>fb', builtin.buffers, { desc = "Find Buffers"})
vim.keymap.set('n', '<leader>fh', builtin.help_tags, { desc = "Find Help Tags"})
vim.keymap.set('n', '<leader>fs', builtin.lsp_document_symbols, { desc = "Find Symbols"})
vim.keymap.set('n', '<leader>fi', '<cmd>AdvancedGitSearch<CR>', { desc = "AdvancedGitSearch"})
vim.keymap.set('n', '<leader>fo', builtin.oldfiles, { desc = "Find Old Files"})
vim.keymap.set('n', '<leader>fw', builtin.grep_string, { desc = "Find Word under Cursor"})
vim.keymap.set('n', '<leader>gc', builtin.git_commits, { desc = "Search Git Commits"})
vim.keymap.set('n', '<leader>gb', builtin.git_bcommits, { desc = "Search Git Commits for Buffer"})
Nvim-ufo (code folding)
vim.o.foldcolumn = '1' -- '0' is not bad
vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value
vim.o.foldlevelstart = 99
vim.o.foldenable = true
vim.keymap.set('n', 'zR', require('ufo').openAllFolds, { desc = "Open all folds" })
vim.keymap.set('n', 'zM', require('ufo').closeAllFolds, { desc = "Close all folds" })
vim.keymap.set('n', 'zK', function()
local winid = require('ufo').peekFoldedLinesUnderCursor()
if not winid then
vim.lsp.buf.hover()
end
end, { desc = "Peek Fold" })
require('ufo').setup({
provider_selector = function(bufnr, filetype, buftype)
return { 'lsp', 'indent' }
end
})
Conclusion
Check out my configuration if you want to see what I use today!
Here are a few other Neovim articles you should check out:
If you or your company are interested in having someone conduct technical interviews then please DM me on Twitter (@Exosyphon) or visit my website. If you enjoy topics like this then you might also like my Youtube channel. Have a great day!