mirror of
https://github.com/bernys/swarm.nvim.git
synced 2026-06-19 00:01:06 -06:00
Multi-cursor nvim plug
- Lua 100%
| doc | ||
| lua/swarm | ||
| plugin | ||
| LICENSE | ||
| README.md | ||
swarm.nvim
Features
| Feature | Description |
|---|---|
| Add cursor below / above | <C-Down> / <C-Up> |
| Add cursor at next match | <C-n> — like VM's <C-n> |
| Remove last cursor | <C-p> |
| Skip current match | <C-x> |
| Select all occurrences | <leader>A |
| Cursors on visual lines | <C-m> in visual mode |
| Exit | <Esc> |
| User commands | :MCAddDown, :MCAddUp, :MCAddWord, :MCSelectAll, :MCAddVisual, :MCRemoveLast, :MCSkip, :MCCancel |
All extra cursors are rendered with extmarks and follow buffer edits automatically. Typing in insert mode, backspace, and enter are replayed on every cursor.
Requirements
- Neovim ≥ 0.9 (uses
vim.on_key,nvim_buf_set_extmark,nvim_set_hl)
Installation
lazy.nvim
{
"bernys/swarm.nvim",
event = "VeryLazy",
config = function()
require("swarm").setup()
end,
}
packer.nvim
use {
"bernys/swarm.nvim",
config = function()
require("swarm").setup()
end,
}
Configuration
require("swarm").setup({
-- Set to false to define your own keymaps
default_mappings = true,
-- Highlight group for virtual cursors
highlight_cursor = "Swarm",
-- Highlight group for virtual selections
highlight_visual = "SwarmVisual",
})
Custom keymaps
require("swarm").setup({ default_mappings = false })
local s = require("swarm")
local opts = { noremap = true, silent = true }
vim.keymap.set({ "n", "x" }, "<C-n>", s.add_cursor_word, opts)
vim.keymap.set({ "n", "x" }, "<C-p>", s.remove_last_cursor, opts)
vim.keymap.set({ "n", "x" }, "<C-x>", s.skip_cursor, opts)
vim.keymap.set({ "n", "x" }, "<C-Down>", function() s.add_cursor("down") end, opts)
vim.keymap.set({ "n", "x" }, "<C-Up>", function() s.add_cursor("up") end, opts)
vim.keymap.set({ "n", "x" }, "<leader>A", s.select_all_word, opts)
vim.keymap.set("x", "<C-m>", s.add_cursors_visual, opts)
vim.keymap.set("n", "<Esc>", s.cancel, opts)
Workflow examples
Edit every occurrence of a word
- Place the cursor on the word.
- Press
<C-n>once — the current word is selected and cursor jumps to the next match. - Keep pressing
<C-n>to add more cursors. - Press
<leader>Ato select all occurrences at once. - Enter insert mode and type; all cursors edit simultaneously.
- Press
<Esc>to finish.
Edit every line in a visual block
- Select lines with
V(linewise visual). - Press
<C-m>— a cursor is placed at the same column on every selected line. - Type your edits.
- Press
<Esc>to finish.
Architecture
plugin/swarm.lua ← Neovim plugin entry point, default keymaps
lua/swarm/
init.lua ← Public API (add_cursor, cancel, …)
config.lua ← User configuration
state.lua ← Virtual cursor list + extmark management
utils.lua ← Buffer helpers (find occurrences, insert/delete)
input.lua ← on_key capture, keystroke replay to cursors
highlight.lua ← Default highlight groups
Highlight groups
| Group | Default | Usage |
|---|---|---|
Swarm |
purple block | Virtual cursor positions |
SwarmVisual |
subtle bg | Virtual visual selections |
SwarmMain |
cyan block | Real cursor while 'Swarm' is active |
Override in your colorscheme or after setup():
vim.api.nvim_set_hl(0, "Swarm", { bg = "#ff0000", fg = "#ffffff", bold = true })
Contributing
PRs welcome! Areas to improve:
- Visual-mode selections on virtual cursors
- Per-cursor registers/yanks
- Regex-based
:MCFindcommand - Dot-repeat (
.) support - Undo grouping across all cursors
A Lua-native multiple-cursors plugin for Neovim, inspired by mg979/vim-visual-multi.
License
MIT