Back to ezstack

Neovim
Plugin

A native Lua plugin for ezstack. Browse your stacks in a styled buffer, jump between worktrees with Telescope, see your stack in the statusline, and run the full :Ezs command suite — all without leaving Neovim.

$ { "KulkarniKaustubh/ezstack", subdir = "neovim-plugin" }
View on GitHub
Stack Viewer

Your stack, in a buffer

Run :Ezs to open the stack viewer in a split. It's a non-modifiable buffer that renders every stack with PR state, CI status, and review info — with a focused keymap for everything you'd want to do.

1

A native, styled buffer

The viewer is a normal Neovim buffer — cursor position is preserved on refresh, and it plays nicely with windows, tabs, and your colorscheme.

" :Ezs opens the viewer
 Stack: my-feature [a1b2c3d]                      root: main
 ─────────────────────────────────────────────────────────────────
 > ├── feature-1     PR #100 [OPEN]    CI: 3/3     +120 -8   (→ main)
   ├── feature-2     PR #101 [DRAFT]   CI: pending +50 -2    (→ feature-1)
   └── feature-3     [no PR]                                  (→ feature-1)
2

Keymaps for everything

Every common operation is one keystroke away inside the viewer. Press ? for the help popup.

<CR>  # goto worktree
o     # open PR in browser
r     # refresh                  R  rename stack
n     # new branch               d  delete branch under cursor
p     # push branch              P  push entire stack
s     # sync (terminal)          c  continue an in-progress sync
u     # update PR                D  diff against parent
a     # open agent               A  build feature with agent
?     # help                     q  close viewer
3

Auto-refresh

The viewer refreshes after every CLI mutation through the User EzstackChanged autocommand. With vim-fugitive installed, it also refreshes on FugitiveChanged.

" Hook your own logic into refreshes
autocmd User EzstackChanged echom "stack updated"
autocmd User EzstackGoto    echom "switched worktree"
:Ezs Command

Full stack control from the command line

The plugin exposes a single :Ezs user command with subcommand and flag completion. Everything the CLI can do, you can do without leaving Neovim.

1

Branch & sync operations

Create branches, navigate the stack, sync, push, and reparent. Sync and commit run in a Neovim terminal split so you can resolve conflicts in place.

:Ezs new feature-1 main         # create stacked branch
:Ezs goto feature-1              # switch worktree (tcd)
:Ezs up / :Ezs down             # move along the stack
:Ezs sync -s                     # sync entire stack
:Ezs sync --continue             # resume after conflicts
:Ezs push -s                     # push every branch in the stack
:Ezs reparent feature-2 main     # move branch to a new parent
:Ezs delete feature-3            # delete branch + worktree
2

Pull request operations

Create, update, merge, and toggle draft for the current branch's PR. :Ezs pr stack updates the navigation table in every PR description in the stack.

:Ezs pr create "Part 1: scaffold"
:Ezs pr update                   # push + refresh PR
:Ezs pr draft                    # toggle draft / ready
:Ezs pr merge                    # prompts for method
:Ezs pr stack                    # refresh stack tables
:Ezs pr open                     # open in browser
3

AI agent integration

Launch the ezstack AI agent or build a feature as stacked PRs — from inside Neovim. View, edit, and reset prompts across all three layers (shipped, custom, repo).

:Ezs agent                            # branch- or stack-scoped agent
:Ezs agent feature "add JWT auth"
:Ezs agent prompt                     # view shipped prompts
:Ezs agent prompt edit work          # edit custom layer in nvim
:Ezs agent prompt edit repo feature  # edit repo layer
:Ezs agent prompt reset work
Telescope Extension

Fuzzy-find any branch in any stack

If you have telescope.nvim installed, the bundled extension gives you fuzzy pickers for branches and stacks. When Telescope isn't available, :Ezs goto falls back to vim.ui.select.

1

Branches picker

Browse every branch across every stack with PR and CI info inline. Jump straight to a worktree, or run actions on the entry under your cursor.

:Telescope ezstack branches

<CR>    # goto worktree
<C-o>   # open PR in browser
<C-d>   # delete branch
<C-p>   # push branch
2

Stacks picker

Browse stacks at the top level. Open a stack in the viewer, or rename it inline.

:Telescope ezstack stacks

<CR>    # open stack viewer
<C-r>   # rename stack
3

Statusline component

Drop the current branch and stack into your statusline. Results are cached (default: 5s) so it never hammers the CLI.

-- lualine example
require("lualine").setup({
  sections = {
    lualine_b = {
      "branch",
      { function() return require("ezstack").statusline() end },
    },
  },
})

-- renders:  feature-1 | my-feature [a1b2c3d]

Installation

Requires Neovim 0.10+ and the ezs CLI on your $PATH. Telescope and fugitive are optional but recommended.

lazy.nvim

Lazy-load the plugin on first :Ezs with a single spec entry. :Ezs is also registered eagerly when the plugin is on the runtimepath, so it works without an explicit setup() call.

{
  "KulkarniKaustubh/ezstack",
  subdir = "neovim-plugin",
  cmd    = { "Ezs" },
  keys   = { { "<leader>ez", "<cmd>Ezs<cr>" } },
  config = function()
    require("ezstack").setup()
    require("telescope").load_extension("ezstack")
  end,
}

packer.nvim

Use the rtp field to point Packer at the neovim-plugin/ subdirectory of the repo.

use {
  "KulkarniKaustubh/ezstack",
  rtp    = "neovim-plugin",
  config = function()
    require("ezstack").setup()
  end,
}

Configuration

Pass these to require("ezstack").setup({ ... }).

Option Default Description
cli_path "ezs" Path to the ezs binary. Auto-discovered from common bin dirs if missing on $PATH.
auto_refresh true Refresh the viewer on FugitiveChanged and EzstackChanged.
viewer_position "botright" Split position for the stack viewer.
viewer_height 15 Stack viewer window height.
statusline_cache_ttl 5000 Statusline cache TTL in milliseconds.
goto_strategy "tcd" Worktree switch strategy: "tcd" (tab-local), "cd" (global), "lcd" (window).
goto_close_buffers false Close unmodified buffers from the previous worktree on goto.
goto_open_explorer true Open your file explorer at the new worktree root after goto.
Source on GitHub