mirror of
https://github.com/amartincodes/multilinea.git
synced 2026-06-19 00:01:05 -06:00
Nvim plugin to enable multi cursor editing
- Lua 100%
|
|
||
|---|---|---|
| doc | ||
| lua/multilinea | ||
| plugin | ||
| .gitignore | ||
| CLAUDE.md | ||
| LICENSE | ||
| QUICKSTART.md | ||
| README.md | ||
| test_example.txt | ||
Multilinea.nvim
A powerful multi-cursor editing plugin for Neovim, inspired by VSCode's multi-cursor functionality. Built with LazyVim compatibility in mind.
Features
- 🎯 VSCode-style cursor addition - Press
<C-n>to add cursors at matches - ⬆️⬇️ Directional cursors - Add cursors above/below current position
- 🔍 Literal matching - Match char, visual selection, or linewise visual blocks (
V) - ✏️ Simultaneous editing - Type once, edit everywhere
- 🎨 Visual feedback - Clear cursor indicators using Neovim's extmarks
- ⚡ Lightweight - Pure Lua implementation with minimal dependencies
- 🔧 Fully customizable - Configure keybindings, highlights, and behavior
Installation
Using lazy.nvim (recommended)
-- In ~/.config/nvim/lua/plugins/multilinea.lua
return {
"amartincodes/multilinea.nvim",
event = "BufReadPost",
opts = {
-- Your configuration here (optional)
},
}
Using packer.nvim
use {
"amartincodes/multilinea.nvim",
config = function()
require("multilinea").setup()
end
}
Using vim-plug
Plug 'amartincodes/multilinea.nvim'
" In your init.vim
lua << EOF
require("multilinea").setup()
EOF
Usage
Basic Operations
-
Add cursor at next match (VSCode-style)
- Place cursor on a character, visually select text, or use linewise visual mode (
V) - Press
<C-n>to add cursor at the next occurrence - Keep pressing
<C-n>to add more cursors - Press
<Esc>to clear all cursors
- Place cursor on a character, visually select text, or use linewise visual mode (
-
Add cursors vertically
- Press
<C-j>to add cursor below - Press
<C-k>to add cursor above - Great for editing aligned columns
- Press
-
Add all matches
- Place cursor on a character, visually select text, or use linewise visual mode (
V) - Press
<leader>mato add cursors at all occurrences
- Place cursor on a character, visually select text, or use linewise visual mode (
-
Manual cursor placement
- Press
<leader>mcto add a cursor at current position - Move around and add more cursors where needed
- Press
Editing with Multiple Cursors
Once you have multiple cursors:
- Insert mode: Press
i,a,I,A,o, orOto start editing at all cursors - Normal mode: Most motions and operators work at all cursors:
w,b,e- word motions0,^,$- line motionsdd,D,x- delete operationsr{char}- replace character at all cursorsy,p- yank and paste
- Clear cursors: Press
<Esc>to exit multi-cursor mode
Example Workflow
-- Rename all occurrences of a variable
1. Place cursor on variable name
2. Press <C-n> multiple times (or <leader>ma for all)
3. Press 'ciw' to change inner word
4. Type the new name
5. Press <Esc> to apply to all cursors
Configuration
Default Configuration
require("multilinea").setup({
-- Keybindings (all customizable)
keymaps = {
add_cursor_next = "<C-n>", -- Add cursor at next match
add_cursor_below = "<C-j>", -- Add cursor below
add_cursor_above = "<C-k>", -- Add cursor above
add_all_matches = "<leader>ma", -- Add all matches
remove_cursor = "<M-x>", -- Remove current cursor
clear_cursors = "<Esc>", -- Clear all cursors
skip_match = "<leader>ms", -- Skip current match
add_cursor_here = "<leader>mc", -- Add cursor at position
},
-- Visual appearance
highlights = {
primary = "CursorLine",
secondary = "Visual",
},
-- Behavior
show_cursor_numbers = false, -- Show cursor index numbers
case_sensitive_search = false, -- Case sensitivity for matching
})
Custom Keybindings
require("multilinea").setup({
keymaps = {
add_cursor_next = "<C-d>", -- Use Ctrl-d like Sublime Text
add_all_matches = "<C-M-l>", -- Custom binding
clear_cursors = "<leader>mc", -- Use leader instead of Esc
},
})
Custom Highlights
require("multilinea").setup({
highlights = {
primary = "Search", -- Use Search highlight for primary cursor
secondary = "IncSearch", -- Use IncSearch for secondary cursors
},
})
Commands
Multilinea provides the following user commands:
:MultilineaAddCursor- Add cursor at current position:MultilineaAddNext- Add cursor at next match:MultilineaAddAll- Add cursors at all matches:MultilineaClear- Clear all cursors:MultilineaAddBelow- Add cursor below:MultilineaAddAbove- Add cursor above
API
Multilinea exposes a public API for integration with other plugins:
local multilinea = require("multilinea")
-- Add cursor programmatically
multilinea.api.add_cursor(row, col, is_primary)
-- Remove cursor
multilinea.api.remove_cursor(row, col)
-- Clear all cursors
multilinea.api.clear_all()
-- Get cursor positions
local cursors = multilinea.api.get_cursors()
-- Check if active
if multilinea.api.is_active() then
print("Multi-cursor mode active")
end
-- Get cursor count
local count = multilinea.api.get_count()
Health Check
Run :checkhealth multilinea to verify your installation.
Comparison with Other Plugins
| Feature | Multilinea | vim-visual-multi | multiple-cursors.nvim |
|---|---|---|---|
| Pure Lua | ✅ | ❌ | ✅ |
| Extmarks API | ✅ | ❌ | ✅ |
VSCode-style <C-n> |
✅ | ✅ | ✅ |
| LazyVim ready | ✅ | ⚠️ | ⚠️ |
| Lightweight | ✅ | ❌ | ✅ |
| Visual mode | ✅ (charwise + linewise) | ✅ | ✅ |
Roadmap
- Basic multi-cursor operations
- VSCode-style literal matching
- Directional cursor addition
- Insert mode editing
- Normal mode operations
- Blockwise visual mode support (
<C-v>) - Macro recording per cursor
- Advanced selection refinement
- Pattern-based cursor placement
- Split/join cursor operations
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Setup
# Clone the repository
git clone https://github.com/amartincodes/multilinea.nvim.git
cd multilinea.nvim
# Test in Neovim
nvim --cmd "set rtp+=."
License
MIT License - see LICENSE file for details.
Acknowledgments
Inspired by:
- vim-visual-multi
- multiple-cursors.nvim
- multicursor.nvim
- VSCode's multi-cursor functionality
Support
If you encounter issues or have questions:
- Check the documentation
- Search existing issues
- Create a new issue with:
- Neovim version (
:version) - Configuration
- Steps to reproduce
- Expected vs actual behavior
- Neovim version (
Made with ❤️ for the Neovim community