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+Backspace and Ctrl+Delete
  • optional Vim learning hints
  • conflict detection and diagnostics

Start here

  1. Install the plugin.
  2. Run :GuiKeymapDemo.
  3. Test the shortcuts in the scratch buffer.
  4. Open :GuiKeymapInfo if something does not behave as expected.

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:

  • Backspace
  • Delete

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+Backspace
  • Ctrl+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:

  1. saves pending changes
  2. runs :confirm wq

home_end

Enables Home and End mappings in normal, insert, and visual mode.

Behavior:

  • Home -> line start
  • End -> 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.

  • 0 disables display after zero uses
  • positive number limits how many times a hint can show
  • -1 means 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.

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

ShortcutModeBehaviorVim equivalent
Ctrl+Cnormalcopy lineyy
Ctrl+Cvisualcopy selectiony
Ctrl+Vnormalpastep
Ctrl+Vinsertpasteinsert paste
Ctrl+Xvisualcut selectiond
Ctrl+Anormalselect allggVG
Ctrl+Ainsertselect all<Esc>ggVG
Ctrl+Znormalundou
Ctrl+Zinsertundo<C-o>u
Ctrl+Ynormalredo<C-r>
Ctrl+Yinsertredo<C-o><C-r>
Ctrl+Snormalsave buffer:write
Ctrl+Sinsertsave buffer:write
Ctrl+Svisualsave buffer:write
Ctrl+Qnormalsave and close:confirm wq
Ctrl+Qinsertsave and close:confirm wq
Homenormalline start0
Homeinsertline start<C-o>0
Homevisualline start0
Endnormalline end$
Endinsertline end<C-o>$
Endvisualline end$
Ctrl+Backspacenormaldelete previous wordGUI-style previous-word delete
Ctrl+Backspaceinsertdelete previous wordGUI-style previous-word delete
Ctrl+Deletenormaldelete next wordGUI-style next-word delete
Ctrl+Deleteinsertdelete next wordGUI-style next-word delete

Delete-selection mappings

Visual mode:

  • Backspace
  • Delete

These use the black-hole register so clipboard contents are preserved.

Shift+Arrow selection

Normal mode

  • Shift+Left
  • Shift+Right
  • Shift+Up
  • Shift+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=nofile
  • bufhidden=wipe
  • swapfile=false
  • filetype=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+S for 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:

  1. saves pending changes
  2. 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 = true
  • hint_repeat is not exhausted
  • hint_persist did not carry forward an already-exhausted count

If needed, run:

:GuiKeymapHintReset

Mappings are skipped in LazyVim or AstroNvim

Check:

  • force_priority
  • enforce_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.