Skip to content

rvaccone/capo.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Capo.nvim

Every terminal answers to you
About · Installation · Configuration · Default Keymaps · How It Works · Contributing

capo.nvim demo

About

Capo.nvim runs your terminals like a crew. Each one holds a number, one through nine. Call a number and that terminal steps forward. Call a number nobody holds and someone new gets brought in. You never cycle through terminals hoping to recognize one.

You also never name them. Hesitate on the prefix and the card comes up: every terminal, what it is running right now, and where it works. The labels are read live from the processes, so they are always the truth. You do not keep the books. The books keep themselves.

Capo knows the difference between a shell that is waiting and a program that is working. Esc dismisses an idle terminal. Esc inside a running program goes to the program, where it belongs. That one distinction is what makes it comfortable to keep an agent like Claude Code in terminal one and leave it there.

And when a terminal you tucked away finishes a long job, you hear about it. Once, quietly, with the job's name. Nothing finishes unnoticed.

Capo requires Neovim 0.10+ and ps.

Installation

Using lazy.nvim (recommended):

{
    "rvaccone/capo.nvim",
    ---@type CapoConfig
    opts = {},
}

Configuration

The defaults:

opts = {
    terminals = {
        max = 9,        -- how many terminals can exist at once
        persist = true, -- remember the roster per project
    },
    float = {
        width = 0.85,   -- fraction of the editor
        height = 0.8,
        border = "rounded",
    },
    card = {
        delay_ms = 150, -- hesitation before the card appears
    },
    watch = {
        enabled = true,   -- announce hidden work that finishes
        min_seconds = 20, -- shorter jobs end silently
    },
    keymaps = {
        prefix = "<leader>t",
        toggle = "t",
        new = "n",
        kill = "d",
        clear = "c",
    },
    shell = nil,      -- defaults to your 'shell'
    notify = true,    -- informational notices; warnings always show
}

Configuration is validated before anything is applied. A typo errors at startup instead of silently doing nothing.

Default Keymaps

Keymap Action
<leader>t1-9 Focus that terminal, spawning it if it is missing
<leader>tt Reopen the last terminal, or dismiss the visible
<leader>tn Spawn a terminal at the lowest free number
<leader>td Kill the current terminal
<leader>tc Forget every terminal and the stored roster
<Esc> Dismiss an idle terminal; a busy one receives it

Hesitate after <leader>t and the card appears while capo waits for your key. There are also commands: :Capo list, :Capo kill {n} and :Capo clear.

How It Works

The card. One line per terminal: its number, its foreground process, and the directory it works in. A dot marks the one you visited last. A tilde marks a remembered terminal that is not currently running; its label is the last job it held, shown dim because it is a memory, not a fact.

Killing. Nobody gets killed in the middle of a job by accident. Ask once and capo tells you what is still running. Ask again within a few seconds and it is done. The same goes for clearing: if anyone on the roster is still working, the first ask names them and the second ask goes through. :Capo kill! {n} and :Capo clear! skip the question.

The watch. While terminals are alive, capo glances at the process table every few seconds. When a job that ran past watch.min_seconds ends in a terminal you are not looking at, you get one notice with the job's name and how long it took. Quick commands come and go without a word.

Persistence. The roster is kept per project under stdpath("data")/capo. Come back tomorrow and the numbers still mean what they meant: each address remembers its directory and its last job. The processes themselves are gone, that is how processes are, and capo does not pretend otherwise. A remembered terminal comes back to life when you call its number, in its old directory, with nothing run on your behalf.

Highlights

The card uses default links, so it follows your colorscheme and keeps transparency.

Group Default Purpose
CapoCard NormalFloat Card background
CapoCardBorder FloatBorder Card border
CapoCardDim Comment Remembered (cold) terminals
CapoCardBold bold The number you would type

Contributing

Issues and pull requests are welcome. Run make test before sending changes.

About

Every terminal answers to you

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors