diff --git a/lua/git/cmd.lua b/lua/git/cmd.lua index a5bbe77..8026f4c 100644 --- a/lua/git/cmd.lua +++ b/lua/git/cmd.lua @@ -9,9 +9,7 @@ local M = {} ---@field ft string ---@field needs_ref boolean? ----Subcommands whose output goes to a buffer. Subcommands with their ----own dispatch (`commit`, `show`, `cat-file`) call `run_in_split` ----directly with a one-off conf. +---Subcommands whose output goes to a buffer. ---@type table local SPLIT_HANDLERS = { log = { ft = "git" }, diff --git a/lua/git/diff.lua b/lua/git/diff.lua index 3d8f52a..6c9504a 100644 --- a/lua/git/diff.lua +++ b/lua/git/diff.lua @@ -21,8 +21,8 @@ end ---The command path runs Vim's full `diff_win_options` setup, which sets ---an internal flag that prevents subsequently-created floats from ---inheriting `'diff' = 1` when opened from a focused diff pane. The raw ----option setter skips that setup, so floats (oil, fzf-lua, etc) end up ----joining the tabpage's diff group and corrupting its render. +---option setter skips that setup, so floats end up joining the +---tabpage's diff group and corrupting its render. ---@param win integer ---@param enabled boolean local function set_diff(win, enabled) @@ -32,19 +32,15 @@ local function set_diff(win, enabled) end ---Render two buffers as a diff pair. The right buffer takes the current ----window; the left opens in a leftabove split (vertical or horizontal ----per `vertical`). Both windows enter Vim's diff mode via `:diffsplit`'s ----built-in setup. Drops a `'` jumplist mark before reassigning the ----current window. +---window. The left opens in a leftabove split (vertical or horizontal +---per `vertical`). Drops a `'` jumplist mark first so `''` jumps back. ---@param left integer ---@param right integer ---@param vertical boolean function M.open(left, right, vertical) - -- Read the name first: if `left` is the current window's buffer - -- and has `bufhidden=wipe` (a freshly-loaded `git://` URI), the - -- `nvim_set_current_buf(right)` below wipes it, and a later name - -- lookup would fail. `:diffsplit` re-bufadds + reloads from the - -- name, so the wipe-then-recreate sequence is fine. + -- Read the name first: an empty placeholder has `bufhidden=wipe`, + -- so `nvim_set_current_buf(right)` below wipes `left` before a + -- name lookup could see it. `:diffsplit` re-creates from the name. local left_name = vim.api.nvim_buf_get_name(left) vim.cmd.normal({ "m'", bang = true }) vim.api.nvim_set_current_buf(right) @@ -57,9 +53,8 @@ end ---group and re-establishes a fresh one. `nvim_win_set_buf` swaps the ---buffer pointer without invalidating cached diff state, and ---`:diffupdate` alone doesn't reliably force a recompute when no buffer ----contents have actually changed. Sides with `name` set get renamed + ----filetype-refreshed (used to relabel a fresh `empty_buf` placeholder ----as `[absent] `, or to re-run ft detection on a `git://` buffer). +---contents have actually changed. Sides with `name` set are renamed +---and re-run filetype detection. ---@param left_win integer ---@param right_win integer ---@param pair ow.Git.DiffPair @@ -77,10 +72,8 @@ function M.update_pair(left_win, right_win, pair) set_diff(right_win, true) end ----Open two buffers as a diff. `a_left` decides which one goes in the ----leftabove slot (where `M.open` parks the cursor). Caller picks per ----its own rule (writable-on-left for routine flows, anchor-on-left ----when neither side is writable, etc). +---Open two buffers as a diff. `a_left` puts `buf_a` in the leftabove +---slot (where `M.open` parks the cursor). ---@param buf_a integer ---@param buf_b integer ---@param a_left boolean @@ -94,19 +87,18 @@ local function place_pair(buf_a, buf_b, a_left, vertical) end ---Dispatch for `M.split` when the current buffer is a `git://` ----URI. Placement is "writable on the left" via `place_pair`. +---URI. Placement is writable-on-the-left via `place_pair`. --- ---gd/gh: pair cur with the worktree file at the URI's path. --- ----gD/gH: pair cur with the next layer toward HEAD — +---gD/gH: pair cur with the next layer toward HEAD. --- * stage 0 -> `HEAD:

` --- * stage 2 (ours) <-> stage 3 (theirs) ---- * stage 1 (base) -> bail; ambiguous (suggest `:Gdiffsplit `) +--- * stage 1 (base) -> bail (ambiguous, suggest `:Gdiffsplit `) --- * any other ref -> `:0:

` --- ----A `` containing `:` (from `:Gdiffsplit`) short-circuits all the ----above and pairs cur with that revspec literally. This is the escape ----hatch the merge-base warning points at. +---A `` containing `:` (from `:Gdiffsplit`) short-circuits the +---above and pairs cur with that revspec literally. ---@param opts ow.Git.SplitOpts ---@param cur_buf integer ---@param cur_revspec string @@ -119,11 +111,10 @@ local function uri_split(opts, cur_buf, cur_revspec) end local cur = util.parse_revspec(cur_revspec) if not cur.path then - util.warning("git URI has no path; cannot diff against worktree") + util.warning("git URI has no path, cannot diff against worktree") return end - -- `git.object` is lazy-required to break the load-time cycle. - -- It requires `git.diff` itself for `empty_buf`. + -- Lazy-required to break the load-time cycle with `git.object`. local object = require("git.object") local cur_writable = cur.stage == 0 @@ -153,7 +144,7 @@ local function uri_split(opts, cur_buf, cur_revspec) end if cur.stage == 1 then - util.warning("gD on merge base is ambiguous; use :Gdiffsplit ") + util.warning("gD on merge base is ambiguous, use :Gdiffsplit ") return end @@ -184,7 +175,7 @@ local function uri_split(opts, cur_buf, cur_revspec) end ---@class ow.Git.SplitOpts ----@field revspec string '' for the smart-default routing (index vs worktree); a plain ref like `'HEAD'` to compare `:` against the current path; or a full revspec containing `:` (e.g. `':2:foo'`, `'HEAD~1:other.lua'`) used as-is. +---@field revspec string `''` for smart-default routing (index vs worktree). A plain ref like `'HEAD'` compares `:` against the current path. A full revspec containing `:` (e.g. `':2:foo'`, `'HEAD~1:other.lua'`) is used as-is. ---@field vertical boolean ---@param opts ow.Git.SplitOpts @@ -216,9 +207,6 @@ function M.split(opts) return end - -- A `` containing `:` is treated as a full revspec; - -- otherwise the worktree-relative path is appended (the common - -- keymap form). local revspec if opts.revspec == "" then revspec = ":0:" .. rel diff --git a/lua/git/object.lua b/lua/git/object.lua index a713806..f1736c4 100644 --- a/lua/git/object.lua +++ b/lua/git/object.lua @@ -48,7 +48,7 @@ local function diff_section() end -- Header lines (mode/index/oldfile/newfile/etc) sit between the - -- `diff --git` line and the first `@@` hunk; cap the read at 20 to + -- `diff --git` line and the first `@@` hunk. Cap the read at 20 to -- bound work even for unusual diff headers. local header = vim.api.nvim_buf_get_lines(0, diff_lnum, diff_lnum + 20, false) @@ -135,18 +135,12 @@ local function attach_index_writer(buf, worktree, path) }) end ----Pre-fetched content keyed by bufnr. Set by `buf_for(_, _, content)` ----and consumed by the next `read_uri` dispatch on that buffer. Lets ----callers fold validation + content fetch + buffer load into one ----`cat-file` call instead of preflighting separately. +---Pre-fetched content keyed by bufnr, consumed once by `read_uri`. ---@type table local pending_content = {} ----Return a buffer holding the content addressed by a git revspec. The ----URI is `git://` and BufReadCmd routes through `M.read_uri`, ----which loads via `git cat-file -p`. If `content` is given, primes a ----cache so the BufReadCmd handler reuses it instead of running another ----`cat-file -p`. +---Return a `git://` URI buffer. Pass `content` to prime +---`read_uri`'s cache and skip its `cat-file -p` fetch. ---@param worktree string ---@param revspec string any revspec git understands (e.g. `HEAD:foo`, `:foo`, `:1:foo`, ``, `:foo`) ---@param content string? @@ -161,11 +155,10 @@ function M.buf_for(worktree, revspec, content) return buf end ----BufReadCmd handler for `git://` URIs. Loads content via ----`git cat-file -p `. Worktree comes from `vim.b[buf] ----.git_worktree` if set, else from cwd. Stage-0 index entries (revspec ----form `:`) are made writable via `attach_index_writer` so `:w` ----updates the index. Other revspecs are read-only. +---BufReadCmd handler for `git://` URIs. Worktree comes from +---`b:git_worktree` if set, else from cwd. Stage-0 index entries +---(`:`) are made writable so `:w` updates the index. Other +---revspecs are read-only. ---@param buf integer function M.read_uri(buf) local name = vim.api.nvim_buf_get_name(buf) @@ -202,9 +195,9 @@ function M.read_uri(buf) -- Bare-ref objects that dereference to a commit (commits, stashes, -- annotated tags pointing at a commit, lightweight tags) get their - -- `diff-tree -p` patch appended so the buffer is navigable: the + -- `diff-tree -p` patch appended so the buffer is navigable. The -- `` parser walks `diff --git` blocks. `^{commit}` is git's - -- standard "deref to commit" suffix; rev-parse fails for non-commit + -- standard "deref to commit" suffix. rev-parse fails for non-commit -- objects (trees, blobs, tags pointing at non-commits) so they -- naturally skip the append. `-m --first-parent` collapses merges -- and stashes into one diff per file (vs `diff --cc` combined @@ -238,8 +231,7 @@ function M.read_uri(buf) vim.api.nvim_buf_set_lines(buf, 0, -1, false, util.split_lines(stdout)) end - -- `b:git_ref` anchors ``-driven navigation in this buffer. Set - -- here once per load instead of having every caller do it. + -- `b:git_ref` anchors ``-driven navigation in this buffer. local ref_sha = repo.rev_parse(worktree, revspec, true) if ref_sha then vim.b[buf].git_ref = ref_sha @@ -278,8 +270,8 @@ function M.read_uri(buf) -- BufReadCmd suppresses the normal BufReadPost dispatch, so -- modeline parsing doesn't run unless we fire it ourselves. The - -- modeline can still override the filetype set above; standard Vim - -- precedence. + -- modeline can still override the filetype set above (standard Vim + -- precedence). vim.api.nvim_exec_autocmds("BufReadPost", { buffer = buf }) end @@ -312,7 +304,7 @@ end ---@param section ow.Git.DiffSection local function open_section(ctx, section) if not section.pre_blob or not section.post_blob then - util.warning("no index line; cannot determine blob SHAs") + util.warning("no index line, cannot determine blob SHAs") return end local parent = ctx.parent_ref or "0" @@ -330,13 +322,8 @@ end ---@field split (false|"above"|"below"|"left"|"right")? forwarded to `util.place_buf`. Default opens a new horizontal split. ---Open any git object. Accepts a bare ref (commit / tree / blob / tag ----sha, branch, tag name, `stash@{N}`, etc.) or `:` ----form. Resolves the revspec to a sha so the URI stays stable if the ----ref later moves, primes the `read_uri` cache with the `cat-file -p` ----output (one subprocess instead of two — preflight + load), then goes ----through the unified URI pipeline. `read_uri` then appends the ----`diff-tree -p` patch for any revspec that dereferences to a commit ----(commits, stashes, annotated tags pointing at commits). +---sha, branch, tag name, `stash@{N}`, etc.) or `:`. +---Resolves to a sha so the URI stays stable if the ref later moves. ---@param worktree string ---@param ref string ---@param opts ow.Git.OpenObjectOpts? @@ -370,9 +357,6 @@ function M.open_under_cursor() local line = vim.api.nvim_get_current_line() - -- Cat-file header navigation: `parent ` (commit), `tree ` - -- (commit / tag), `object ` (tag's referent) all reference - -- another git object. local sha = line:match("^commit (%x+)$") or line:match("^parent (%x+)$") or line:match("^tree (%x+)$") @@ -382,12 +366,8 @@ function M.open_under_cursor() return true end - -- Tree-entry navigation: ` \t`. Blobs are - -- routed by path so the URI carries the entry name and filetype - -- detection picks it up. Subtrees navigate by sha so the resulting - -- buffer's `git_ref` is the subtree's own sha (correct anchor for - -- relative path navigation within it). Other types (submodule - -- commit refs, tags) also navigate by sha. + -- Blobs navigate by path so the URI carries the entry name (filetype + -- detection wants the extension). Other types navigate by sha. local entry_type, entry_sha, entry_name = line:match("^%d+ (%w+) (%x+)\t(.+)$") if entry_sha then diff --git a/lua/git/repo.lua b/lua/git/repo.lua index ddf3e0b..a7a8111 100644 --- a/lua/git/repo.lua +++ b/lua/git/repo.lua @@ -121,7 +121,7 @@ end function Repo:stop_watcher() -- Stop the libuv watcher first so no further fs-events can trigger - -- self:refresh(); only then tear down the debounce handle. The reverse + -- self:refresh(). Only then tear down the debounce handle. The reverse -- order leaves a window where an in-flight watcher callback would call -- a closed debounce timer. if self.watcher then @@ -150,7 +150,7 @@ end ---@param repo ow.Git.Repo local function do_refresh(repo) -- `--branch` adds the `## branch...upstream [ahead/behind]` line that - -- the sidebar parses; the per-buffer indicator only needs the XY + + -- the sidebar parses. The per-buffer indicator only needs the XY + -- path lines, so it ignores `##` lines below. Running with `--branch` -- lets the sidebar reuse this single subprocess via the GitRefresh -- data payload instead of spawning its own. diff --git a/lua/git/sidebar.lua b/lua/git/sidebar.lua index 8c795df..d5f6f9a 100644 --- a/lua/git/sidebar.lua +++ b/lua/git/sidebar.lua @@ -19,8 +19,8 @@ local SIDEBAR_WIDTH = 50 ---@field section string ---@field path string ---@field orig string? ----@field x string porcelain v1 column 1 (always set; may be a literal space) ----@field y string porcelain v1 column 2 (always set; may be a literal space) +---@field x string porcelain v1 column 1 (always set, may be a literal space) +---@field y string porcelain v1 column 2 (always set, may be a literal space) ---@class ow.Git.CommitEntry ---@field section string @@ -39,7 +39,7 @@ local SIDEBAR_WIDTH = 50 ---@field diff_right_win integer? ---@field user_aucmd integer? ---@field last_shown_key string? ----@field last_render_key string? fingerprint of the last rendered state +---@field last_render_key string? ---@type table local state = {} @@ -47,8 +47,7 @@ local state = {} local group = vim.api.nvim_create_augroup("ow.git.sidebar", { clear = false }) local ns = vim.api.nvim_create_namespace("ow.git.sidebar") ----Find the sidebar window in the current tabpage by filetype. Used as a ----fallback when we don't have a `SidebarState` handy (e.g. M.toggle). +---Find the sidebar window in the current tabpage by filetype. ---@return integer? win ---@return integer? bufnr local function find_sidebar() @@ -144,7 +143,7 @@ local function parse_branch_line(line) end ---Parse `git status --porcelain=v1 --branch` output into a (branch, groups) ----pair. `Unpushed` and `Unpulled` start empty here; ahead/behind commits are +---pair. `Unpushed` and `Unpulled` start empty here. Ahead/behind commits are ---filled in by a follow-up `git log` once we know the upstream is set. ---@param stdout string ---@return ow.Git.BranchInfo, table @@ -432,7 +431,7 @@ local function refresh(bufnr, prefetched_stdout) return end -- Any fs-event that triggered this refresh might have changed the - -- worktree under the diff buffers we last opened; invalidate the + -- worktree under the diff buffers we last opened. Invalidate the -- cache so the next view_entry recomputes panes. s.last_shown_key = nil local fp = fingerprint(branch, groups) @@ -635,10 +634,8 @@ local function entry_key(entry) return entry.section .. "|" .. entry.path .. "|" .. (entry.orig or "") end ----Split `target_win` and put its buffer into the new window. Matches the ----semantics of `:set_current_win(target); :rightbelow/leftabove vertical ----split` (the new window inherits the target's buffer; caller swaps it ----afterwards via `nvim_win_set_buf`). +---Split `target_win` to the given side. The new window inherits +---`target_win`'s buffer, which the caller swaps afterwards. ---@param target_win integer ---@param dir "left"|"right" ---@return integer @@ -697,7 +694,7 @@ local function view_entry(s, entry, focus_left) -- Invocation window is gone (closed or in another tabpage). -- Open the diff pair by splitting from the sidebar. winfixwidth -- keeps the sidebar at 50 when there are other windows to - -- absorb the split; if the sidebar is the only window in the + -- absorb the split. If the sidebar is the only window in the -- tab, the split has to take from the sidebar itself, so -- restore the width explicitly. right_win = vsplit_at(sidebar_win, "right") @@ -791,7 +788,7 @@ local function action_discard() end ---@cast entry ow.Git.FileEntry if entry.section == "Staged" then - util.warning("file has staged changes; unstage first with 'u'") + util.warning("file has staged changes, unstage first with 'u'") return end diff --git a/lua/git/util.lua b/lua/git/util.lua index 56477dd..eb777a0 100644 --- a/lua/git/util.lua +++ b/lua/git/util.lua @@ -17,8 +17,8 @@ function M.parse_uri(name) end ---@class ow.Git.ParsedRevspec ----@field stage 0|1|2|3? index stage when the revspec is `:` / `:0:` / `:N:`; nil otherwise ----@field path string? path component when the revspec carries one; nil for bare object refs +---@field stage 0|1|2|3? index stage when the revspec is `:` / `:0:` / `:N:`, nil otherwise +---@field path string? path component when the revspec carries one, nil for bare object refs ---Classify a `git://` revspec into its stage / path components. ---Recognised forms: @@ -48,9 +48,7 @@ end ---@field name string? ---@field bufhidden ("hide"|"wipe")? defaults to "wipe" ----Configure a fresh buffer as a read-only scratch and optionally name ----it. Shared by `empty_buf` and `new_scratch`; the public functions ----differ in whether they dedup-by-name or place the buffer in a window. +---Configure a fresh buffer as a read-only scratch and optionally name it. ---@param buf integer ---@param opts ow.Git.ScratchOpts local function setup_scratch(buf, opts) @@ -83,9 +81,9 @@ function M.empty_buf(opts) end ---Place a buffer in the current window or a new split per `split`. ----`false` replaces the current buffer (drops a `'` mark first so `''` ----jumps back); a direction string opens a leftabove split; nil falls ----back to a `splitbelow`-aware horizontal split. +---`false` replaces the current buffer, dropping a `'` mark first so +---`''` jumps back. A direction string opens a leftabove split. Nil +---falls back to a `splitbelow`-aware horizontal split. ---@param buf integer ---@param split (false|"above"|"below"|"left"|"right")? ---@return integer win