gitsuite.nvim · Project & repos · vimdoc
:help gitsuite
One :Git command tree for everything git
doc/gitsuite.txt — rendered from the plugin's own vimdoc
*gitsuite.txt* One :Git command tree for everything git *gitsuite.nvim* Author: Stefan Bartl Version: 0.1.0
CONTENTS
1. Introduction .............. |gitsuite-intro| 2. Requirements ............... |gitsuite-requirements| 3. Installation ............... |gitsuite-installation| 4. Commands .................... |gitsuite-commands| 5. Configuration ............... |gitsuite-config| 6. Adapters ..................... |gitsuite-adapters| 7. Events ....................... |gitsuite-events| 8. Statusline ................... |gitsuite-statusline| 9. Health check ................. |gitsuite-health|
1. INTRODUCTION
gitsuite.nvim collects every git-related user command this config used to spread across seven external plugins into one:Git <scope> <action>tree (see |gitsuite-commands|). It follows the filetree.nvim pattern: its own implementation where that pays off (merge-conflict resolution, blame, browse), and a thin adapter where an external plugin has already done years of edge-case work (gitsigns' hunk engine, neogit's staging UI, diffview, the reallazygitTUI run in a floating terminal). This is an alpha-stage, actively-growing plugin -- every subcommand listed in docs/BINDINGS.md is a real implementation, but the surface is not frozen yet: breaking changes are still possible.
2. REQUIREMENTS
- Neovim >= 0.10 -giton$PATH- StefanBartl/lib.nvim (hard dependency) - StefanBartl/diff.nvim (hard dependency, used by:Git diff */:Git hunk *) - StefanBartl/ui.nvim (hard dependency, used by:Git dashboard) See docs/requirements.md for the optional tools (gitsigns, diffview, neogit, lazygit, nvr, open.nvim, pickers.nvim) and exactly what each one backs versus what falls back without it.
3. INSTALLATION
{
"StefanBartl/gitsuite.nvim",
dependencies = { "StefanBartl/lib.nvim", "StefanBartl/diff.nvim", "StefanBartl/ui.nvim" },
cmd = "Git",
config = function(_, opts)
require("gitsuite").setup(opts)
end,
}
See docs/installation.md for packer.nvim, vim-plug and mini.deps variants.
4. COMMANDS
*:Git* :Git {scope} {action} [args] Compound command tree with<Tab>completion at every level. See docs/BINDINGS.md for the full, generated list of{scope} {action}pairs -- that file is generated from the same route tree that drives dispatch, so it never drifts from what:Git <Tab>actually offers.:Git ui lazygit [dir]opens lazygit for the repository containingdir(any directory inside its work tree) instead of the one of the current working directory; from Lua:require("gitsuite.features.ui").lazygit(dir). Adirthat does not exist or is not inside a git repository is reported, no float is opened. Blame without a buffer (for other plugins): `require("gitsuite.features.blame") .for_location(dir, path, lnum)returns{ line, sha, author, author_time, summary }for one line ofpath(relative todir`, or absolute); an uncommitted line has an all-zerosha. It blocks without a callback; with acb(entry, err)as fourth argument it runs asynchronously and returns a{ stop }handle. Failures (not a repo, untracked file, line past the end) arenil, err. *gitsuite-conflict*:Git conflict {ours|theirs|both|base|none}resolves the conflict under the cursor. Markers are matched by their exact length (<<<<<<<opens a conflict, and every other marker of it has as many characters): git writes a conflict nested in the base section -- the conflicting virtual ancestor of a criss-cross merge -- with longer markers, and theconflict-marker-sizegit attribute raises the length for a file. A line that is exactly=======can be text (the underline of a Markdown setext heading). In a merge-style conflict that makes the separator impossible to tell from the text: the region is still highlighted (markers and every candidate line only), found by:Git conflict next|prevand counted byhas_conflicts(). With more than one candidate, `:Git conflict ours|theirs|both|base|noneasks which=======` is the real one viavim.ui.select(a line-before/line-after preview per candidate) instead of guessing where our side ends -- the parser itself still never guesses, only the user does, with the buffer content in front of them. With exactly one candidate the *base* marker itself is what is ambiguous instead (two or more|||||||before it), which no separator choice can resolve -- that case still refuses with a message;*.md conflict-marker-size=10in.gitattributesavoids either case for the next merge. diff3/zdiff3 are otherwise affected only if the base section itself holds a=======-looking line (the|||||||marker otherwise tells the sides apart, and git keeps conflicts around an unchanged underline apart). *gitsuite-dashboard*:Git dashboard [dir] [--out=...] [--to=...]and `:Git dashboard update [dir]` are the one multi-repo exception -- every other scope above operates on the current buffer's repository,dashboardreads the git status of every repository indir/dashboard.base_dir($REPOS_DIR by default), or a configureddashboard.groupspage. Row/marked-set/whole- page push, pull and fetch (p/P/f/gp/gP/gf/gu), page navigation (<C-l>/<C-h>), and per-page path add/remove (a/x) -- moved here from reposcope.nvim's former:Reposcope dashboard/update. See docs/BINDINGS.md for the full key table, docs/configuration.md fordashboard.*, and docs/scope.md for why this one scope is different.
5. CONFIGURATION
require("gitsuite").setup({
features = { conflict = true, hunk = true, blame = true, diff = true,
browse = true, branch = true, ui = true, status = true },
commands = { git = "Git" },
keymaps = { blame_full = "<leader>gb", ui_lazygit = "<leader>lg" },
browse = { hosts = {} },
dashboard = { base_dir = "", extra_paths = {}, groups = {} },
progress_style = "auto",
})
Set akeymaps.*entry tofalseto disable that default mapping without disabling the underlying feature.dashboardhas nofeatures.dashboardflag -- the scope is always registered, see |gitsuite-dashboard|. See docs/configuration.md for every key explained individually.
6. ADAPTERS
Each feature family resolves its own backend independently throughgitsuite.adapter(gitsigns,diffview,neogit,lazygit,native).nativeneeds nothing butgititself and is always available inside a git repo; every other adapter is only available once its own plugin/binary is present -- an unavailable adapter is never an error by itself, only the family it would have served falling back further, or refusing with a clear message when nothing is left to fall back to.
7. EVENTS
gitsuite.nvim fires plainUserautocmd events after certain actions so a sister plugin can react without gitsuite knowing it exists (D-2: events, not a directrequire()from gitsuite into a consumer --gitsuite.eventsis the one place they are fired from). Subscribe the usual way:
vim.api.nvim_create_autocmd("User", {
pattern = "GitsuiteBranchSwitched",
callback = function(event) vim.print(event.data) end,
})
*GitsuiteBranchSwitched*GitsuiteBranchSwitched{ dir, branch }-- after `gitsuite.features.branch .switch()checks out a different branch.dir` is the repo root the checkout ran in,branchthe ref now checked out. *GitsuiteConflictsResolved*GitsuiteConflictsResolved{ bufnr }-- after `gitsuite.features.conflict .choose()` resolves the *last* remaining conflict region in a buffer, not on everychoose()call -- only once the buffer has none left. *GitsuiteStatusChanged*GitsuiteStatusChanged{ dir }-- after a hunk stage (single hunk or whole buffer) actually writes to the git index, fired from gitsigns' own completion callback rather than merely after the (async) action was requested. Not fired for a hunk reset: gitsigns' reset only rewrites the buffer's in-memory lines, never the index or the file on disk.
8. STATUSLINE
require("gitsuite.statusline").status(bufnr?)returns an ambient merge-conflict indicator for the current (or given) buffer, e.g."MERGE 2"--""when the buffer has no conflicts,features.conflictis off, orbufnris invalid. Cached per buffer bynvim_buf_get_changedtick, safe to call unconditionally on every statusline redraw -- no process runs in the render path.lualine_componentisstatusunder another name, forsections = { lualine_x = { require("gitsuite.statusline").lualine_component } }. ui.nvim ships a ready-made adapter,ui.statusline.modules.gitsuite_conflict(addgitsuite_conflictto yourorder). See docs/statusline.md for the full wiring (heirline, the native statusline) and why the cache is keyed bychangedtickrather than |GitsuiteConflictsResolved|.
9. HEALTH CHECK
:checkhealth gitsuitereports: - lib.nvim / diff.nvim presence (hard dependencies -- error if missing) -giton$PATH- each adapter's availability (info, not warn/error -- see |gitsuite-adapters|) - rejectedsetup()options, if any - the composer's own route-tree check for:Git