Vim & Neovim Essentials: The Keybindings You Actually Need

14 Aug 2026 • 6 min read

Vim looks like a puzzle box. It's really about eight keys and one config file.

Everyone’s first Vim story is the same: you open it by accident, type something, and now you’re trapped in a terminal that won’t let you leave. It’s a rite of passage. But once you learn the handful of commands that actually matter, that same “impossible” editor becomes the fastest thing on your keyboard.

This guide covers the keybindings you’ll use 95% of the time, plus a minimal init.lua to get Neovim feeling comfortable out of the box.

Modes, in One Paragraph

Vim has modes instead of menus. Normal mode is for moving around and running commands — it’s the default. Insert mode is for typing text, like a normal editor. Visual mode is for selecting text. You’ll spend most of your time bouncing between Normal and Insert.

Opening and Closing

Start Neovim from the terminal:

BASH
nvim filename.txt

From Normal mode, these are the exits:

Command What it does
:w Save
:q Quit
:wq or ZZ Save and quit
:q! Quit without saving

💡 Quick Check: After :wq, you should land back at your shell prompt with no error message. If you instead see E37: No write since last change, you tried to quit with unsaved edits — add the ! or save first.

Insert Mode

From Normal mode, any of these drop you into Insert mode:

Command What it does
i Insert before the cursor
a Insert after the cursor
I Insert at start of line
A Insert at end of line
o Open a new line below and insert
O Open a new line above and insert

Press Esc to leave Insert mode and go back to Normal mode. That single keystroke is the one habit that makes everything else click.

⚠️ Important Exception: o and O always insert a new line — they don’t just move your cursor. If you only want to move to the line above or below, use j/k in Normal mode instead.

Visual Mode: Selecting Text

Command What it does
v Character-wise visual select
V Line-wise visual select
Ctrl-v Block (column) visual select

Move the cursor with h j k l (or arrow keys) to extend the selection, then act on it — delete, yank, indent, whatever you need.

Copy, Cut, and Paste

Vim calls copy/cut “yank” and “delete,” and paste is “put.”

Command What it does
yy Yank (copy) the current line
dd Delete (cut) the current line
y (in visual mode) Yank the selection
d (in visual mode) Delete the selection
p Paste after the cursor / below the line
P Paste before the cursor / above the line

💡 Why This Matters: Every delete in Vim also copies to the same register dd uses, so dd then p is a quick way to move a line down. It looks like a coincidence the first time you notice it — it isn’t.

A Minimal init.lua

Neovim’s config lives at ~/.config/nvim/init.lua. This is enough to make it feel like a real editor without pulling in a plugin manager:

LUA
-- ~/.config/nvim/init.lua

-- Leader key (used as a prefix for custom shortcuts)
vim.g.mapleader = " "

-- Line numbers
vim.opt.number = true
vim.opt.relativenumber = true

-- Indentation
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.expandtab = true
vim.opt.smartindent = true

-- Search
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.incsearch = true

-- Quality of life
vim.opt.wrap = false
vim.opt.scrolloff = 8
vim.opt.termguicolors = true

-- Keymaps
vim.keymap.set("n", "<leader>w", ":w<CR>", { desc = "Save file" })
vim.keymap.set("n", "<leader>q", ":q<CR>", { desc = "Quit" })
vim.keymap.set("v", "<", "<gv", { desc = "Indent left, keep selection" })
vim.keymap.set("v", ">", ">gv", { desc = "Indent right, keep selection" })

Drop that in place and restart Neovim — no plugins required.

💡 Why This Works: relativenumber pairs with the movement keys from earlier — once line numbers show distance instead of absolute position, a command like 5dd (delete 5 lines) becomes something you can read off the screen instead of guessing.

Or: Install My Config From GitHub

If you’d rather skip typing out a config by hand, I keep a ready-to-use Neovim setup in my dotfiles repo . It’s built on lazy.nvim (a plugin manager) and is split into a few small files instead of one giant init.lua:

TEXT
.config/nvim/
├── init.lua              -- bootstraps lazy.nvim, loads everything else
└── lua/
    ├── options.lua        -- the vim.opt settings
    ├── keymaps.lua         -- leader key + keymaps
    ├── autocmds.lua        -- autocommands
    └── plugins/            -- one file per plugin (colorschemes, lualine, etc.)

The repo also holds my shell and Hyprland configs, so you only want the nvim folder out of it — not the whole thing.

1. Back up your current config, if you have one:

BASH
mv ~/.config/nvim ~/.config/nvim.bak

2. Clone just the nvim folder using a sparse checkout:

BASH
git clone --filter=blob:none --sparse https://github.com/darkrift-opt/dotfiles.git ~/dotfiles-tmp
cd ~/dotfiles-tmp
git sparse-checkout set .config/nvim
cp -r .config/nvim ~/.config/nvim
cd ~ && rm -rf ~/dotfiles-tmp

--filter=blob:none skips downloading file contents you don’t need, and sparse-checkout set .config/nvim checks out only that folder — so you’re not pulling the Hyprland or shell configs at all. (If your git version is older than 2.25, skip the sparse steps and just clone normally, then cp -r the nvim folder out — a bit more data, same result.)

💡 Why This Matters: A full clone would still work fine — cp -r ~/dotfiles-tmp/.config/nvim ~/.config/nvim gets the same result either way. Sparse checkout just avoids downloading configs for tools you may not even be using.

3. Launch Neovim:

BASH
nvim

The first launch will look busy — init.lua detects that lazy.nvim isn’t installed yet, clones it automatically, and then lazy.nvim installs every plugin listed under lua/plugins/. Just let it finish.

💡 Quick Check: Once the plugin install window closes, you should see a themed statusline at the bottom and no red error banners at the top. If you see module 'options' not found or similar, the lua/ folder didn’t come along with init.lua — recheck step 2.

A few things worth knowing about this config specifically:

  • Leader key is Space, same as the minimal config above.
  • Save/quit live under <leader>fs (save), <leader>qq (quit), and <leader>qs (save and quit) — not the plain <leader>w / <leader>q from the DIY version earlier.
  • Colorscheme is picked at the top of init.lua via vim.g.active_colorscheme. It ships with several themes already configured in lua/plugins/ (Tokyonight, Catppuccin, Oxocarbon, Carbonfox, Black Metal) — change that one line and restart to switch.

⚠️ Important Exception: This config expects the plugin folder structure to stay intact. If you only copy init.lua and skip the lua/ directory, Neovim will start but immediately error out looking for options, keymaps, and autocmds.

Cheat Sheet

Print this part.

Category Key Action
Modes Esc Back to Normal mode
i / a Insert before / after cursor
I / A Insert at start / end of line
o / O New line below / above
Movement h j k l Left, down, up, right
w / b Next / previous word
0 / $ Start / end of line
gg / G Top / bottom of file
Editing x Delete character
dd Delete line
yy Yank (copy) line
p / P Paste after / before
u Undo
Ctrl-r Redo
Visual v Visual (character)
V Visual (line)
Ctrl-v Visual (block)
File :w Save
:q Quit
:wq Save and quit
:q! Quit without saving

That’s the whole toolbox. Everything else — plugins, LSPs, fuzzy finders — is optional polish on top of these fundamentals.

Start searching

Enter keywords to search articles.