Lightweight multiple-cursor plugin for Neovim (v0.1.3)
Find a file
Minh Khoi Do 1a7cce12a1
Merge pull request #3 from khoido2003/dependabot/github_actions/JohnnyMorganz/stylua-action-5
chore(deps): bump JohnnyMorganz/stylua-action from 4 to 5
2026-04-16 09:38:33 +07:00
.github chore(deps): bump JohnnyMorganz/stylua-action from 4 to 5 2026-04-06 15:58:03 +00:00
doc docs: update license and documentation 2026-01-10 15:34:42 +07:00
gallery feat: add overlay window, fix: multi-line editing sync, duplicate annotations 2026-01-13 13:31:30 +07:00
lua/multiple-cursor feat: add persistent colorscheme listener 2026-01-14 14:37:45 +07:00
plugin chore: format src code 2026-01-10 13:48:52 +07:00
.gitignore chore: add gitignore, CI workflow, changelog 2026-01-10 13:47:30 +07:00
CHANGELOG.md v0.1.3: Performance & stability improvements 2026-01-14 13:40:52 +07:00
LICENSE docs: update license and documentation 2026-01-10 15:34:42 +07:00
README.md fix: remove unused current Highlight 2026-01-14 13:22:11 +07:00
stylua.toml chore: add gitignore, CI workflow, changelog 2026-01-10 13:47:30 +07:00

multiple-cursor.nvim

A lightweight, powerful multi-cursor plugin for Neovim that feels like VS Code's multi-cursor implementation.

multiple-cursor.nvim showcase

Features

  • Position-Based Selection: Select or skip specific matches based on your cursor position.
  • Real-time Sync: Edits (insert, delete, change) are synchronized across all cursors instantly.
  • Smart Navigation: Ctrl+J / Ctrl+K to jump between matches quickly.
  • Auto-Jump: Automatically moves to the next unselected match after you select or skip one.
  • Preserved State: Keeps track of skipped matches so you can come back to them.

📦 Installation

Using lazy.nvim

{
  "khoido2003/multiple-cursor.nvim",
  keys = {
    { "<C-n>", "<cmd>MultipleCursorStart<cr>", desc = "Start Multiple Cursor" },
  },
  cmd = { "MultipleCursorStart", "MultipleCursorSelectAll" },
  config = function()
    require("multiple-cursor").setup()
  end,
}

Using packer.nvim

use {
  "khoido2003/multiple-cursor.nvim",
  config = function()
    require("multiple-cursor").setup()
  end,
}

Manual Installation

Clone to your Neovim packages directory:

git clone https://github.com/khoido2003/multiple-cursor.nvim ~/.local/share/nvim/site/pack/plugins/start/multiple-cursor

Keybindings

Key Action Description
<C-n> Add Cursor Adds a cursor to the match under cursor. Works in normal and visual mode.
<C-x> Skip / Remove Skips or removes the cursor from the match under your current position.
<C-j> Next Match Jump to the next match occurrence.
<C-k> Prev Match Jump to the previous match occurrence.
<C-a> Select All Selects all remaining matches in the buffer.
<C-u> Undo Cursor Remove the last added cursor.
c / i / I / A Edit Enter edit mode. Changes are synced to all selected cursors.
d Delete Delete all selected words.
<Esc> Exit Exit multi-cursor mode.

Operators (Vim-style)

Key Action Description
gy Yank All Yank all selected words to register.
g~ Toggle Case Toggle case of all selected words.
gu Lowercase Convert all selected words to lowercase.
gU Uppercase Convert all selected words to UPPERCASE.

Usage Workflow

  1. Place your cursor on a word you want to edit.
  2. Press <C-n> to start. The current word is selected and the cursor jumps to the next match.
  3. Use <C-j> / <C-k> to move between matches if needed.
  4. Press <C-n> to add more cursors, or <C-x> to skip a match.
  5. Press c (change), d (delete), or i (insert) to start editing. All selected instances will be updated simultaneously.
  6. Press <Esc> to finish.

Configuration

Default configuration:

require("multiple-cursor").setup({
  keymaps = {
    start_next = "<C-n>",
    skip = "<C-x>",
    next_match = "<C-j>",
    prev_match = "<C-k>",
    select_all = "<C-a>",
    exit = "<Esc>",
  },
  highlights = {
    cursor = "MultipleCursor",
    match = "MultipleCursorMatch",
    skipped = "MultipleCursorSkipped",
  },
  highlight_definitions = {
    cursor = { bg = "#00FA9A", fg = "#000000", bold = true }, -- Medium Spring Green (selected cursors)
    match = { bg = "#FFD700", fg = "#000000", bold = true }, -- Gold (unselected matches)
    skipped = { bg = "#FF6347", fg = "#000000", bold = true }, -- Tomato (skipped)
    overlay = { bg = "#E84A72", fg = "#ffffff", bold = true }, -- Rose Pink (Monokai-inspired)
  },
  -- Floating overlay window for selection count (easier to see)
  overlay = {
    enabled = true,                              -- Enable/disable the overlay
    position = "top-right",                      -- "top-left", "top-right", "bottom-left", "bottom-right"
    padding = { top = 1, right = 1, bottom = 1, left = 1 }, -- Padding from screen edges
  },
  match_whole_word = true,
  case_sensitive = true,
})