BIG DISCLAIMER: This is not a real plugin in the neovim sense of a plugin. It's just a way to integrate cursor-cli into the neovim editor. So whenever you read that it's a "plugin" , just read it as "terminal integration" (or something like that).
A Neovim plugin to integrate the Cursor AI agent CLI directly into your editor. Toggle a terminal running cursor agent
with a simple keybinding and send visual selections for AI assistance.
This was created using cursor 😊 in 20 minutes, it doesn't have to be perfect, just need something to run cursor agent like the agent inside cursor.
- 🚀 Toggle a vertical split terminal running
cursor agentwith<leader>ai - 🎛️ Manage multiple AI agent sessions simultaneously
- 🔍 Fuzzy finder with live preview (Telescope integration)
- ✏️ Rename and organize agent terminals for different tasks
- ⌨️ Full terminal mode support - manage agents without leaving the terminal
- 📝 Send visual selections and file paths to the Cursor agent
- 💾 Persistent terminal sessions (hide/show without restarting)
- ⚙️ Fully configurable (keybindings, split position, size, etc.)
- 🎯 Written in pure Lua
- Neovim >= 0.8.0
cursorCLI installed and available in your PATH
Using lazy.nvim
{
"felixcuello/neovim-cursor",
config = function()
require("neovim-cursor").setup()
end,
}Using packer.nvim
use {
"felixcuello/neovim-cursor",
config = function()
require("neovim-cursor").setup()
end,
}Using vim-plug
Plug 'felixcuello/neovim-cursor'
lua << EOF
require("neovim-cursor").setup()
EOF- Open/Toggle Agent: Press
<leader>aiin normal mode- First time: Creates your first agent terminal
- After that: Toggles (show/hide) the last active agent
- Create New Agent: Press
<leader>anto create additional agent terminals - Switch Agents: Press
<leader>atto open a fuzzy picker with live preview - Rename Agent: Press
<leader>arto rename the current agent terminal
Work with multiple AI agents simultaneously for different tasks:
| Keybinding | Action |
|---|---|
<leader>ai |
Smart toggle - create first agent or show last active |
<leader>an |
Create new agent terminal with custom prompt |
<leader>at |
Select agent from fuzzy picker (with live preview) |
<leader>ar |
Rename current agent terminal |
When you're inside an agent terminal, you can manage agents without leaving:
| Keybinding | Action |
|---|---|
<Esc> |
Exit terminal mode / hide agent window |
<C-n> |
Create new agent terminal |
<C-t> |
Select agent from fuzzy picker |
<C-r> |
Rename current agent terminal |
1. Press <leader>ai → Creates "Agent 1"
2. Ask: "Help me debug this authentication issue"
3. Press <C-n> → Prompt appears
4. Type: "Review my database schema"
5. Now you have two agents running!
6. Press <C-t> → Telescope shows both with live preview
7. Navigate and press Enter to switch
8. Press <C-r> → Rename to "Auth Debug" and "Schema Review"
Send code selections to your active agent:
- Select text in visual mode (v, V, or Ctrl-v)
- Press
<leader>ai - The plugin will:
- Toggle the agent terminal (show it)
- Send the file path with line range (e.g.,
@file.lua:10-20)
Example:
@/path/to/your/file.lua:10-15
The agent will have context about which file and lines you're referring to.
The plugin provides comprehensive commands for all operations:
:CursorAgent- Toggle agent terminal (smart toggle):CursorAgentNew [prompt]- Create new agent terminal with optional initial prompt:CursorAgentSelect- Open agent picker:CursorAgentRename [name]- Rename active agent (interactive if no argument):CursorAgentList- List all agent terminals with status
Note: To close an agent terminal, simply type
exitin the terminal or pressCtrl+D
:CursorAgentSend <text>- Send arbitrary text to active agent:CursorAgentVersion- Display plugin version
require("neovim-cursor").setup({
-- Multi-terminal keybindings (all configurable)
keybindings = {
toggle = "<leader>ai", -- Toggle agent window (show last active)
new = "<leader>an", -- Create new agent terminal
select = "<leader>at", -- Select agent terminal (fuzzy picker)
rename = "<leader>ar", -- Rename current agent terminal
},
-- Terminal naming configuration
terminal = {
default_name = "Agent", -- Default name prefix for terminals
auto_number = true, -- Auto-append numbers (Agent 1, Agent 2, etc.)
},
-- Terminal split configuration
split = {
position = "right", -- "right", "left", "top", "bottom"
size = 0.5, -- 50% of editor width/height (0.0-1.0)
},
-- CLI command to run
command = "cursor agent",
-- Terminal callbacks (optional)
term_opts = {
on_open = function()
-- Called when terminal opens
print("Cursor agent started")
end,
on_close = function(exit_code)
-- Called when terminal closes
print("Cursor agent exited with code: " .. exit_code)
end,
},
})require("neovim-cursor").setup({
keybindings = {
toggle = "<C-a>", -- Use Ctrl+a for toggle
new = "<C-n>", -- Use Ctrl+n for new terminal
select = "<C-s>", -- Use Ctrl+s for select
rename = "<leader>rn", -- Use <leader>rn for rename
},
})require("neovim-cursor").setup({
terminal = {
default_name = "AI Assistant", -- Custom prefix
auto_number = true, -- "AI Assistant 1", "AI Assistant 2", etc.
},
})require("neovim-cursor").setup({
split = {
position = "left",
size = 0.4,
},
})require("neovim-cursor").setup({
command = "cursor agent --model gpt-4",
})The old keybinding option is still supported for backward compatibility:
require("neovim-cursor").setup({
keybinding = "<leader>ai", -- Still works, sets the toggle keybinding
})You can access the terminal functions directly:
local cursor = require("neovim-cursor")
-- Access plugin version
print("Version: " .. cursor.version)
-- Toggle terminal
cursor.normal_mode_handler()
-- Create new terminal programmatically
cursor.new_terminal_handler()
-- Send text to active terminal
cursor.terminal.send_text("@myfile.lua\nExplain this code")
-- Check if terminal is running
local terminal_id = cursor.tabs.get_active()
if cursor.terminal.is_running(terminal_id) then
print("Terminal is running")
end
-- List all terminals
local terminals = cursor.tabs.list_terminals()
for _, term in ipairs(terminals) do
print(string.format("%s: %s", term.id, term.name))
end
-- Get terminal state (for debugging)
local state = cursor.tabs.get_state()
print(vim.inspect(state))local tabs = require("neovim-cursor.tabs")
-- Get active terminal ID
local active_id = tabs.get_active()
-- Get terminal metadata
local term = tabs.get_terminal(active_id)
print("Name: " .. term.name)
print("Created: " .. term.created_at)
-- Rename a terminal
tabs.rename_terminal(active_id, "New Name")
-- Delete a terminal
tabs.delete_terminal(active_id)
-- Check if any terminals exist
if tabs.has_terminals() then
print("Terminals count: " .. tabs.count())
endUse descriptive names to organize agents by task:
- "Backend API" - for backend code questions
- "Frontend UI" - for UI/UX implementation
- "Debug Session" - for troubleshooting
- "Code Review" - for reviewing pull requests
- "Documentation" - for writing docs
- Keep agents focused: Create separate agents for different contexts instead of mixing topics in one
- Use terminal mode shortcuts: Stay in terminal mode with
<C-n>,<C-t>,<C-r>for faster navigation - Leverage the preview: Use
<C-t>to preview conversations before switching - Name early: Rename agents as soon as you know their purpose with
<C-r>
For the best experience, install telescope.nvim. The picker will:
- Show live preview of agent conversations
- Support fuzzy searching by agent name
- Allow renaming directly from the picker with
<C-r>
Without Telescope, the plugin falls back to vim.ui.select (still functional, just less features).
- Ensure the
cursorCLI is installed and in your PATH - Try running
cursor agentmanually in your terminal to verify it works - Check for errors with
:messages
- Make sure
<leader>is set in your config (e.g.,vim.g.mapleader = " ") - Check for conflicting keybindings with
:verbose map <leader>ai
- Ensure you're pressing
<leader>aiwhile still in visual mode - The selection will be sent after the terminal opens/shows
Contributions are welcome! Please feel free to submit a Pull Request.
- Cursor - The AI-first code editor
- toggleterm.nvim - Terminal management for Neovim
- vim-floaterm - Floating terminal plugin