gui-keymap.nvim
Use familiar GUI shortcuts in Neovim while learning native Vim commands.
Documentation
What this plugin does
gui-keymap.nvim adds a compatibility layer for users moving from GUI editors
such as VSCode, Sublime Text, or JetBrains IDEs.
It provides:
- copy, paste, cut, select all, undo, redo
- save and save-and-close shortcuts
- Home/End line movement
- Shift+Arrow selection
- word deletion with
Ctrl+BackspaceandCtrl+Delete - optional Vim learning hints
- conflict detection and diagnostics
Start here
- Install the plugin.
- Run
:GuiKeymapDemo. - Test the shortcuts in the scratch buffer.
- Open
:GuiKeymapInfoif something does not behave as expected.
Project links
- Repository: Only-Moon/gui-keymap.nvim
- README: GitHub README
Installation
Requirements
- Neovim
>= 0.8.0 - Classic Vim is not supported
lazy.nvim
{
"Only-Moon/gui-keymap.nvim",
opts = {},
}
packer.nvim
use({
"Only-Moon/gui-keymap.nvim",
config = function()
require("gui-keymap").setup({})
end,
})
vim-plug
Plug 'Only-Moon/gui-keymap.nvim'
Then:
require("gui-keymap").setup({})
Native packages
git clone https://github.com/Only-Moon/gui-keymap.nvim \
~/.local/share/nvim/site/pack/gui/start/gui-keymap.nvim
Then:
require("gui-keymap").setup({})
LuaRocks
luarocks install gui-keymap.nvim
Then:
require("gui-keymap").setup({})
First-run flow
If welcome notifications are enabled, the plugin shows a one-time onboarding message after a fresh install or after the plugin version changes.
Verify installation
Inside Neovim:
:GuiKeymapDemo
:GuiKeymapInfo
:checkhealth gui-keymap
Configuration Reference
Default configuration
require("gui-keymap").setup({
undo_redo = true,
clipboard = {
copy = true,
paste = true,
cut = true,
},
select_all = true,
delete_selection = true,
shift_selection = true,
word_delete = true,
save = true,
quit = true,
home_end = true,
yanky_integration = true,
hint_enabled = true,
hint_repeat = 3,
hint_persist = true,
which_key_integration = true,
enforce_on_startup = true,
force_priority = true,
show_welcome = true,
preserve_mode = true,
})
If you pass no options, these defaults are used automatically.
Option reference
undo_redo
Enables Ctrl+Z and Ctrl+Y mappings in normal and insert mode.
clipboard.copy
Enables GUI-style copy mappings:
- visual
Ctrl+C - normal
Ctrl+C
clipboard.paste
Enables GUI-style paste mappings:
- normal
Ctrl+V - insert
Ctrl+V
clipboard.cut
Enables GUI-style cut mapping in visual mode with Ctrl+X.
select_all
Enables Ctrl+A select-all behavior.
delete_selection
Enables visual-mode deletion using:
BackspaceDelete
These use the black-hole register to avoid overwriting clipboard content.
shift_selection
Enables GUI-style selection growth using Shift+Arrow keys in normal, visual, and insert mode.
This feature is terminal-sensitive. Some terminals emit fallback keycodes such
as <kL> or <kR> instead of literal Shift+Arrow sequences.
word_delete
Enables:
Ctrl+BackspaceCtrl+Delete
Mapped to GUI-style word deletion behavior that avoids polluting clipboard state.
save
Enables Ctrl+S to save the current buffer.
Modes:
- normal
- insert
- visual
quit
Enables Ctrl+Q to save and close the current file.
Behavior:
- saves pending changes
- runs
:confirm wq
home_end
Enables Home and End mappings in normal, insert, and visual mode.
Behavior:
Home-> line startEnd-> line end
yanky_integration
If yanky.nvim is installed, clipboard actions prefer Yanky-backed handlers.
If Yanky is not installed, gui-keymap falls back to Neovim register-based clipboard handling.
hint_enabled
Turns hints on or off globally.
hint_repeat
Controls how many times a hint can appear for a given shortcut.
0disables display after zero uses- positive number limits how many times a hint can show
-1means always show
hint_persist
Stores hint counters in Neovim’s state directory so the learning progress does not reset every time Neovim restarts.
which_key_integration
If which-key.nvim is available, active mappings are registered with
descriptions.
enforce_on_startup
Re-applies mappings during startup to handle lazy-loading races from plugin managers and distributions.
force_priority
When enabled, gui-keymap can replace conflicting default/editor mappings.
When disabled, conflicting mappings are skipped and reported in diagnostics.
show_welcome
Controls the welcome notification shown after first install or after plugin version changes.
preserve_mode
For compatible mappings, returns the user to their original mode after the mapped action finishes.
Recommended minimal setup
require("gui-keymap").setup({
show_welcome = true,
})
Conservative setup
require("gui-keymap").setup({
shift_selection = false,
force_priority = false,
hint_enabled = false,
})
Keymaps and Behavior
GUI shortcut table
| Shortcut | Mode | Behavior | Vim equivalent |
|---|---|---|---|
Ctrl+C | normal | copy line | yy |
Ctrl+C | visual | copy selection | y |
Ctrl+V | normal | paste | p |
Ctrl+V | insert | paste | insert paste |
Ctrl+X | visual | cut selection | d |
Ctrl+A | normal | select all | ggVG |
Ctrl+A | insert | select all | <Esc>ggVG |
Ctrl+Z | normal | undo | u |
Ctrl+Z | insert | undo | <C-o>u |
Ctrl+Y | normal | redo | <C-r> |
Ctrl+Y | insert | redo | <C-o><C-r> |
Ctrl+S | normal | save buffer | :write |
Ctrl+S | insert | save buffer | :write |
Ctrl+S | visual | save buffer | :write |
Ctrl+Q | normal | save and close | :confirm wq |
Ctrl+Q | insert | save and close | :confirm wq |
Home | normal | line start | 0 |
Home | insert | line start | <C-o>0 |
Home | visual | line start | 0 |
End | normal | line end | $ |
End | insert | line end | <C-o>$ |
End | visual | line end | $ |
Ctrl+Backspace | normal | delete previous word | GUI-style previous-word delete |
Ctrl+Backspace | insert | delete previous word | GUI-style previous-word delete |
Ctrl+Delete | normal | delete next word | GUI-style next-word delete |
Ctrl+Delete | insert | delete next word | GUI-style next-word delete |
Delete-selection mappings
Visual mode:
BackspaceDelete
These use the black-hole register so clipboard contents are preserved.
Shift+Arrow selection
Normal mode
Shift+LeftShift+RightShift+UpShift+Down
These start visual selection and move in the requested direction.
Visual mode
The same keys extend the current selection.
Insert mode
The same keys leave insert mode, enter visual selection, and move accordingly.
Clipboard behavior
Without Yanky
- copy, cut, and paste use Neovim register-based handling
- clipboard state is synchronized as safely as possible with
+and unnamed registers
With Yanky
- clipboard actions prefer Yanky handlers
- no hard dependency is created
- diagnostics show whether Yanky is installed, loaded, or only available for lazy load
Save and close behavior
Ctrl+S
Saves the current buffer with :update.
Ctrl+Q
Ctrl+Q is treated as a GUI-style save-and-close action and runs :confirm wq.
Mode preservation
If preserve_mode = true, compatible mappings return the user to the original
mode after the action.
Not every mapping preserves mode. Selection-starting mappings intentionally change mode because that is their behavior.
Commands and Diagnostics
User commands
:GuiKeymapDemo
Opens a scratch buffer for safe shortcut testing.
Buffer properties:
buftype=nofilebufhidden=wipeswapfile=falsefiletype=gui-keymap-demo
:GuiKeymapInfo
Opens a diagnostic report with:
- active mappings
- requested mappings
- skipped mappings
- disabled features
- raw conflicts
- conflict summary by feature
- fallback mappings
- terminal-sensitive mappings
- Yanky status
- which-key status
- hint status
:GuiKeymapList
Shows all active mappings registered by the plugin.
:GuiKeymapSkipped
Shows mappings that were requested but skipped because of conflicts.
:GuiKeymapExplain <key>
Explains one shortcut and shows the Vim equivalent.
Examples:
:GuiKeymapExplain <C-c>:GuiKeymapExplain <C-s>:GuiKeymapExplain <Home>
:GuiKeymapEnable
Re-enables gui-keymap mappings and refreshes them.
:GuiKeymapDisable
Removes gui-keymap mappings from the current session.
:GuiKeymapRefresh
Re-applies mappings without requiring a Neovim restart.
:GuiKeymapHintReset
Clears hint counters.
If persistent hints are enabled, this also removes the stored counter file from Neovim’s state directory.
Health check
Run:
:checkhealth gui-keymap
Health output covers:
- plugin loaded state
- configuration validity
- requested/applied/skipped counts
- mapping conflicts
- conflict summary by feature
- Yanky status
- which-key status
- fallback mappings
- terminal-sensitive mappings
- hint persistence state
Conflict reporting
The plugin does not only report raw key conflicts.
It also groups them by feature, so end users can quickly tell whether the problem is mostly in:
- clipboard
- shift selection
- home/end
- save/quit
- other feature groups
When diagnostics matter most
Use :GuiKeymapInfo or :checkhealth gui-keymap when:
- mappings do not apply in LazyVim or AstroNvim
- a terminal does not send Shift+Arrow correctly
- clipboard behavior differs from expectations
- another plugin is claiming the same keys
Troubleshooting
Ctrl+Y does not redo
Check:
:GuiKeymapInfo:checkhealth gui-keymap
Possible causes:
- another mapping already owns
Ctrl+Y - terminal or distribution remapped it
undo_redo = false
Ctrl+S does not save
Possible causes:
- another plugin already maps
Ctrl+S - your terminal intercepts
Ctrl+Sfor flow control
On some terminals, Ctrl+S and Ctrl+Q are affected by XON/XOFF flow
control. Disable that in your terminal if needed.
Ctrl+Q does not close as expected
The plugin treats Ctrl+Q as save-and-close, not a raw :quit.
Behavior:
- saves pending changes
- runs
:confirm wq
If a terminal intercepts Ctrl+Q, the key may never reach Neovim.
Shift+Arrow is inconsistent
This is the most terminal-sensitive feature in the plugin.
Check:
:GuiKeymapInfo:checkhealth gui-keymap
Look for:
- terminal-sensitive mappings
- fallback mappings such as
<kL>,<kR>,<kU>,<kD>
Some terminals, multiplexers, and WSL setups emit different keycodes.
Clipboard behavior is odd
Possible causes:
- no system clipboard support in Neovim
- terminal/OS clipboard limitations
- Yanky installed but not loaded yet
- another clipboard plugin intercepting the same keys
Check:
- Yanky status in
:GuiKeymapInfo - conflict summary in
:GuiKeymapInfo
Hints are not appearing
Check:
hint_enabled = truehint_repeatis not exhaustedhint_persistdid not carry forward an already-exhausted count
If needed, run:
:GuiKeymapHintReset
Mappings are skipped in LazyVim or AstroNvim
Check:
force_priorityenforce_on_startup:GuiKeymapSkipped:GuiKeymapInfo
If a distribution claims the same keys after startup, startup enforcement is what re-applies gui-keymap mappings.
:GuiKeymapInfo shows conflicts but I did not add mappings
Distributions and plugins often register defaults automatically.
That still counts as a real conflict.
Examples:
- built-in defaults
- distribution defaults
- which-key-related setup
- terminal fallback keys
- clipboard plugins
Hints did not reset after restart
If hint_persist = true, counters are stored across restarts.
Run:
:GuiKeymapHintReset
to clear them manually.
Pure Vim support
This plugin is Neovim-only.
It is not intended for classic Vim.