some useful key mappings in Neovim [uts-002F]
some useful key mappings in Neovim [uts-002F]
1. Introduction
1. Introduction
Here are some useful keys that I like using in NeoVim, some of them require corresponding plugins. I use - LunarVim - it has some pre-installed plugins - Task `prep-lvim` in my justfile is how I have installed LunarVim. Task `lvim` will syncrhonize the configurations, change the working directory and open LunarVim for a specified project. - my LunarVim configuration - LunarVim specific keys are marked with 🌕 - AstroVim - seems to be a better starting point - see astrocommunity for configuring plugin packs - I've ported plugins to use it except for forester - AstroVim specific keys are marked with 🌌 - LazyVim - it has some pre-installed plugins - similarly, see task `prep-lazyvim` and `lazyvim` in my justfile - LazyVim specific keys are marked with 💤 - NvChad - it's ~ 900 LOC lightweight configuration - see tasks `prep-chad` and `chad` in my justfile - NvChad specific keys are marked with 📦 - For all Vim flavors, the following apply: - shared configurations - shared plugins
2. Vital meta keys
2. Vital meta keys
2.1. some useful key mappings in Neovim › Esc
2.1. some useful key mappings in Neovim › Esc
The `Esc` key is used to escape to normal mode, to use Vim's powerful motions. It's the most frequently used key in Vim. - I have configured CapsLock to mean Esc - on Mac, go to `System Preferences > Keyboard > Modifier Keys > Caps Lock Key` - I have configured `jk` in insert mode to mean Esc - this is a common practice, but I don't seem to need it much
2.2. some useful key mappings in Neovim › Leader key
2.2. some useful key mappings in Neovim › Leader key
The leader key is used to trigger many key mappings in normal mode. The default leader key is a single space, represented by `<leader>` below. 🌕 The default local leader key is not set. I've configure it to be two consecutive spaces. `,` is also a common choice. 💤 The default local leader key is set to `\\`. I didn't change it. With plugin `whichkey` installed, `<leader>` and wait to see some useful mappings. Most frequently used key mappings is `<leader>` + one character. There are also many two-character mappings, with the first character indicating a category.
3. First aid
3. First aid
> To generate a truly random string, place a new user in front of Vim and ask them to exit Most of the time, one can use `Esc` + `:qa!` to force quit Vim, with potential loss of unsaved changes. In most plugin UIs, - it can be quit with a single `q`, or `Esc` + `:q`, when in despair, try also `Ctrl+c` - it will usually enter normal mode first, even in terminals, a single `i` is required to enter insert mode, to acually type something - it might provide visual hints on how to navigate, usually a single number or a character in brackets - `g?` or `?` might bring up help on key mappings. Recording is a powerful feature of Vim, but one can accidentally trigger it with an out-of-order `q`, so one simply need to remember to press `q` again to quit recording if seeing something like `recording @a` in the status bar. Other first aid key mappings or commands available: - `:map` to see all key mappings - `:help key-notation` - in case it's not immediately clear that - `C` means `Ctrl`, `S` means `Shift` - `M` means `Alt`/`Option` - `D` means `Cmd` on Mac - use `:Lazy` to check on plugins - use `:Mason` to check on LSPs - 🌕 - `<leader>+;` to open the dashboard for frequently used actions - `<leader>+Lr` to reload the config - `<leader>+li` to see LSP informations - 📦 - `<leader>+ch` to open cheatsheet - Theming - dropping into an unfamiliar theme is worth a first aid - `:colorscheme ` and tab to select a theme - 🌕 `<leader>+sp` to search/select and preview themes - my favorite is `railscasts` - 💤 defaults to `tokyonight` - 📦 defaults to `onedark`
4. Navigation
4. Navigation
- Resume session - `<leader>+rs` to resume the last session - `<leader>+rS` to select a session to resume - Explore and find files - `<leader>+e` to toggle file explorer on the left - `x` to cut, `c` to copy, `p` to paste - `a` to create a file, `d` to delete, `r` to rename - `H` to toggle hidden files, `I` to toggle git ignored files - `Y` to copy relative path, `gy` to copy absolute path - `s` to open in system file explorer - `g?` for help, `q` to quit, `R` to refresh - `hjkl` to move up/down, collapse/expand - it will automatically follow the current file - 💤 and 📦 use NeoTree - can't be toggled, need `q` to quit - `?` for help - 🌕 - `<leader>+sr` to fuzzy find recent files - `<leader>+sf` to fuzzy find files - `<leader>+st` to grep text in files - `<leader>+bf` to fuzzy find buffers - 💤 - `<leader>+fr` to fuzzy find recent files - `<leader>+ff` to fuzzy find files, or simply double space - `<leader>+/` to grep text in files - Manipulate buffers and windows - use `L` for going to next buffer, `H` for previous buffer - use `<C-hjkl>` to move between windows - use `-`/`=` to resizing, or with `C-` for vertical resizing - Jump between files - `gd`: go to definition - `Ctrl`+click also works, note that it's not cmd+click on mac - `gl`: show diagnostics under cursor - `<C+o>`: go back, `<C+i>`: go forward `:jum` to see the jump history - `gf`: go to file - `K` : hover, backspace to cancel hover - `Shift`+click on URL to open in browser - In-file outline - `<leader>+o` to toggle the outline on the right - I have configure it to autojump and autoexpand - Folding - the following needs to be run inside the fold - otherwist it will work on the upper level - `za` to toggle fold - `zA` to toggle all folds - `zO` or `zC` to open/close folds recursively - e.g. it's useful `zCV` then `<leader>+/` to toggle comment for a fold range
5. Editing
5. Editing
5.1. some useful key mappings in Neovim › Basics
5.1. some useful key mappings in Neovim › Basics
- Open file - `:e` to open a file, with tab completion, but it's better to use the fuzzy finder above - `:vs` to open a file (or the current buffer) on the right - `:sp` to open a file (or the current buffer) on the bottom - Save & quit - `:bd` (i.e. buffer delete) to close the current buffer/tab - won't close if there are unsaved changes, `:bd!` to force close - In VSCode Vim mode, should stick to `cmd+s` for saving, `cmd+w` for closing a tab - 💤 - `:w` or `Ctrl+s` to save - `<leader>+bd` to close a buffer with confirmation on unsaved changes - 🌕 prefer to use - `<leader>+w` to save - `<leader>+c` to close a buffer with confirmation on unsaved changes - `ZZ` to save and quit
5.2. some useful key mappings in Neovim › Motions
5.2. some useful key mappings in Neovim › Motions
- Repeatition - prefix with a number to repeat a motion multiple times, e.g. `3j`, `3w` for the impatient - `.` to repeat the last edit motion, but not move motions - Move motions - On Mac, combine with the touchpad to be even more efficient - `gg` for beginning, `G` for end - `zz` to center the current line, `zt` to top, `zb` to bottom - prefixing with a number works on the corresponding line - `w`/`b` to move forward/backward by word - `W`/`B` to move by space-separated words - `e` works like `w` but moves to the end of the word - `ge` works like `b` but moves to the end of the previous word - left `hj` are for left, down; right `kl` are for right, up - pointer finger on `j`, then muscle memory for `jkl` but `h` is a little difficult to reach - `0` to move to the beginning of the line - I don't like `^` and `$` because they are difficult to reach - but in the case of `d$`, it's worth it to reach for `$` - `f` + character to move to the next such character on the same line - `;` and `,` to move to next or previous - `t` works like `f` but moves to one character before, just like `i` for `a` - e.g. - `ct)` is useful for change until the next `)` - `vt)p` is useful for select until the next `)` and paste and replace - `F` and `T` work like `f` and `t` but move backward - `}` to the next paragraph - Edit motions - to enter INSERT mode - `i` for before the cursor - `I` to insert at non-whitespace beginning of the line - `0i` to insert at the beginning of the line - `a` for after the cursor - `A` to append at the end of the line - `c` (i.e. change) to replace by motion, e.g. `cw` to replace a word - `R` to replace by character - `u` to undo, surprisingly `Ctrl+r` to redo - Text objects - `i` for inside, `a` for around - works after the action, before the motion - e.g. `ciw` to *c*hange *i*nside the *w*ord - note that `cw` only changes the part of the word after the cursor, but `ciw` changes the whole word - `a` will affect the surrounding whitespace and punctuation - with `mini.ai` extending the text objects, we have more general way to discribe the text objects - `b` for brackets - `q` for quotes - `c` for class - `f` for function bodies - `a` for arguments - `?` to specify left and right delimiters interactively - Cut/copy/paste - `x` to immediately delete the character under the cursor - `d`+direction to delete a character in that direction - prefer to use number + `dj`/`dk` to delete multiple lines - `dw`/`dd` to delete a character/word/line - all the above will also cut the deleted text - `yw` to copy the current word, `yy` to copy the current line - `p` to paste after, `P` to paste before - for pasting into a pair of brackets/quotes etc., move to the opening one (e.g. use `Esc` + `b`), then `p` or `Cmd+v` - `yyp` to duplicate a line - `<leader>+s+R` to search the registers for cut/copied text - on Mac, `Cmd`+`c`/`v`/`x` also works despite which mode Vim is in - but it seems to be not working stably across difference instances of Vim, especially when inside various plugins - `y` usually guarantees the text is copied to the system clipboard, then use it in other applications
5.3. some useful key mappings in Neovim › Search & replace
5.3. some useful key mappings in Neovim › Search & replace
- Search
- `/` to search forward, `n`/`p` to go to next/previous match
- `?` to search backward
- `*` to search the word under the cursor
- remember to press `Enter` after typing the search term
- remember to treat the search as a regex
- i.e. to escape `\`, `()`, `[]`, `{}`, `^`, `$`, `*`, `+`, `?`, `|`, `.` etc.
- use `<leader>+h` to clear the search highlight
- `gn` to select the next match, `gN` to select the previous match
- repeating this would select *to* the following matches
- prefix with an operator to operate on the selected text
- Replace
- use `%s/before/after/g` to replace all occurrences, remember`%`, otherwise it will only look for the pattern in the current line
- `<leader>+ss` to toggle the search and replace panel
- `<localleader>+r` to replace all occurrences
- manually: use `gf` to go to each file, do edits, then `Ctrl+o` to go back and continue for the next file
5.4. some useful key mappings in Neovim › Visual selection
5.4. some useful key mappings in Neovim › Visual selection
- Select text
- use `V` to enter line visual mode
- this is the most frequently used visual mode, to select multiple lines
- lowercase `v` can be used for character visual mode, but I find it less useful
- `Ctrl+v` to enter block visual mode, i.e. select by column
- Indentation & comment
- use `<<`/`>>` to indent/unindent the current line
- use a single `<`/`>` to unindent/indent the selected text
- 🌕
- `<leader>+/` to toggle comment
- works for both current line and selected text
- 💤
- `gc` to toggle comment for selected text
- `gcc` to comment/uncomment a line
- Multiple-cursor editing (⧉)
- use `/xyz` + enter to search for `xyz`, then `cgn` to change it to something else, `Esc`, then
- use `.` to do the same for next occurrences
- use `n` to skip, and `u` to undo
- use `Ctrl+v` and direction keys (e.g. `j` or `5j`) to vertically select
- use `c` to change
- use `I` to prepend
- use `A` to append
- use `d` to delete
- type the new text, then `Esc`, then it will be applied to all lines of selection
- use `gv` to reselect the last selection
- Visual selection with mouse/touchpad
- motion-compatible selections
- dragging works like `v`
- triple click + scroll works like `V`
- `alt/option` + drag works like `Ctrl+v`
- select and
- ✅ delete by `d`/`x`
- ✅ cut/copy/paste
- ✅ comment/uncomment
- ❌ typing
- ✅ use one of `i`, `a`, `c` etc., then start typing
- ❌ indent/unindent with `Tab`/`Shift+Tab`
- ✅ indent/unindent with `<`/`>`
- vertical select and
- ✅ delete
- ✅ paste
- ❌ typing
- ✅ use one of `I`, `A`, `c`, then start typing
- Recording
- `qa` starts recording user's inputs, `q` quits recording, `@a` replays the recording, `a` could be any other letter
- it could serve as ad hoc key mappings
6. Diagnostic, quickfix and code actions
6. Diagnostic, quickfix and code actions
- Diagnostics - by default, diagnostics are shown as virtual text, I've disabled it for now - `<leader>+l` with `j`/`k` to move between diagnostics - `<leader>+ld` to show diagnostics in the current buffer - `<leader>lw` can search for diagnostics in workspace - `Trouble` can be used to show diagnostics in a separate panel - `<leader>+xx` to open the trouble panel at the bottom - use `<leader>+xX` to see only the current buffer's diagnostics - click on diagnostics to jump to the corresponding location - `<leader>+lq` to open the quickfix list - `<leader>+la` to open the code action list
7. Terminal
7. Terminal
It's very important to stay in the flow and Zen mode as much as possible. Split windows for terminals breaks the flow, so I prefer to use float terminals. - Float terminals - 🌕 `Ctrl+\`to toggle a float terminal - 🌕 number + `Ctrl`+backslash to toggle the n-th float terminal - 💤 same, but with `Ctrl+/` - it's insert mode on first launch - but usually enter normal mode when lost focus - Split terminals - `:term` to open a terminal - it's normal mode by default, `i` to start typing commands - `:sp term://zsh` to open a terminal running `zsh` at the bottom - 📦 - use `<leader>+h` to open a new horizontal split terminal - `:q` to hide terminal - `<leader>+pt` to pick hidden terminal - Working inside the terminal - `exit` will exit the terminal and close the window associated with it - `Ctrl`+`c` can be used for interrupting the terminal
8. Git & Github
8. Git & Github
- git - install and use `lazygit` - `<leader>+gg` to open lazygit, `q` to quit - on a file/directory - space to stage/unstage, `i` to ignore, `d` to discard - `c` to commit, `P` to push, `p` to pull - `r` on a commit to reword - in editor, `<leader>+gs` to stage the current hunk, `<leader>+gr` to revert the current hunk - usually lazygit is good enough, one can also use `:DiffviewOpen` to inspect diff and handle merge conflicts - Github Actions - `<leader>+ga` to open the Github Actions split window - deprecated: `<leader>+gh` because it conflicts with 💤 - `gj` to open the job under cursor, `gr` for the run, `gw` for the workflow file - `<leader>+gq` to close the split window - Octo - `:Octo <Tab>` to operate on issues and PRs - it's interesting but I've disabled it for now, in favor of using the web interface
9. Auto-completion
9. Auto-completion
- Auto-complete - with Github Copilot - `:Copilot setup` to authenticate etc. - `Tab` to accept suggestions - `Shift+Tab` to use the normal Tab - with `blink.cmp` - I've configure it to not triggered by default, in favor of Github Copilot - toggle by `Ctrl+q` - could also be triggerd by `down` in insert mode - up/down to cycle through suggestions, `Enter` to accept - the above is set up so all this key mapping are explicit, intuitive and won't interfere with `<Tab>` for Github Copilot - with `nvim-cmp` (deprecated) - `Tab` to cycle through suggestions from `cmp`, reverse cycle with `Shift+Tab` - continue to type to select a suggestion, this is better then hitting `Enter` - `Ctrl+e` to reject suggestions, and `Tab` to take suggestions from Github Copilot - LLM Chats - Github Copilot - `<leader>+aa` to toggle the chat, `<leader>+al` to clear chat history - `<leader>+a` + a character - for selected code block, **e**xplain, **r**eview, **o**ptimize, **R**efactor, **t**est - **d**ebug, **f**ix, co**m**mit log, **n**aming etc. - `?` to select the model - `C-s` to send the prompt - `:help copilot` to learn more - Aichat - `aichat` with a little setup at `~/Application Support/aichat/config.yaml` - `.` + tab to see available commands - Aider - it's great for multiple-file code generation - I've created a `aider` shim to run it in a virtual environment with preferred configurations - `/` + tab to see available commands - mostly it's a combination of `/add`, `/web` - use `/token` to check token usage, use `/clear`, `/drop` and check `/map` to save token usage - Code Companion - `<localleader>+a` to toggle the inline chat (works also for selection) - `<localleader>+z` to toggle the chat sidebar - Parrot - `<leader>+pr` to rewrite the selection - `<leader>+pp` to implement the selection - `<leader>+pn` to start a new chat, optionally with the selection - select and `:Prt` + `<Tab>` to select advanced prompts - `:PrtInfo` to inspect configurations - `:PrtModel` to select the model - I've configured it to use a buffer to input the prompt, escape twice to send it - it seems unable to stop generation sometimes, use `:PrtChatStop` to stop - Avante (deprecated for now) - `<leader>+aa` to open the chat, use `a` to accept individual suggestions, or `A` to accept all - select code and `<leader>+ae` to modify code - it's interesting but I've disabled it for now, in favor of Github Copilot - Spellcheck - to use NeoVim's built-in spellcheck - use `:set spell` - `]s`/`[s` to move between misspelled words - `zg` marks a word as good, `zw` marks a word as wrong - `zug`/`zuw` to undo - `z=` to see suggestions
10. Useful plugins
10. Useful plugins
- Conform - formart on save using LSP default formatter - `<leader>+lf` to format the current file - showkeys - `<leader>+kk` to show keys screencaster on top-right corner - symbols - `<leader>+se` to fuzzy search symbols, e.g. emoji, LaTeX - Lean - set local leader to " " (tentative) - `<localleader>+i` to toggle Lean Infoview - `<localleader>+r` to restart Lean server for the current file - Forester - `<localleader>+c` to create a new tree and open it - `<localleader>+b` to browse and search trees by title - `gf` to go to the tree under the cursor
11. Further reading
11. Further reading
See the following articles for further inspirations: - useful tools and key mappings for TUI for related TUI key mappings. - Lucas on Vim bindings for discovering more key bindings - Vim cheat sheet for key mappings that apply to vanilla Vim. - VSCode Vim ROADMAP for key mappings that apply to (limited) VSCode Vim mode, but now I have switch to use the real NeoVim. - Keybinds overview for LunarVim key mappings. - zed-101-setup for configurations and key maps inspirations. - My Favorite Neovim Plugins - You don’t need more than one cursor in vim When I use VSCode, I would also use vscode-neovim which would connect to my real NeoVim instance that has some basic configurations here. Zed's Vim mode has many widely used enhancements built in, see also rationale here.