# Never Leaving the Editor for Git

*Hunk-level staging, a text object I forgot I had, and the line gitsigns.nav\_hunk quietly replaced.*

I used to tab out to a terminal for anything past `git status` and `git commit -m`. Staging specific chunks of a file meant `git add -p`, reading through hunks in a pager, answering y/n/s prompts. It worked, but it was a switch every time, and I stopped doing it more than I should have. gitsigns.nvim and diffview.nvim got rid of the switch entirely.

The part that actually changed my habits is the hunk as a first-class object. gitsigns gives you a text object for it:

```lua
map({ "o", "x" }, "ih", ":<C-U>Gitsigns select_hunk<CR>", { desc = "Select hunk" })
map("n", "<leader>ghs", gs.stage_hunk,      { desc = "Stage hunk" })
map("n", "<leader>ghr", gs.reset_hunk,      { desc = "Reset hunk" })
map("n", "<leader>ghp", gs.preview_hunk,    { desc = "Preview hunk" })
```

That `ih` mapping is doing the same job `iw` does for a word or `ip` does for a paragraph, just scoped to "the changed lines around the cursor." Once it's a text object, every operator in Vim works on it for free. `dih` deletes the hunk's changes back to the committed version: no reset\_hunk keymap needed, just an operator I already know applied to a new noun.

One thing that confused me recently: gitsigns renamed its navigation function. The old `next_hunk()` / `prev_hunk()` pair is deprecated upstream in favor of a single `nav_hunk()` that takes a direction:

```lua
map("n", "]h", function() gs.nav_hunk("next") end, { desc = "Next hunk" })
map("n", "[h", function() gs.nav_hunk("prev") end, { desc = "Prev hunk" })
```

Small API change, but it's the kind of thing that breaks a keymap if you copy an old config from a blog post (including, this one: check the gitsigns changelog before you trust anything I just wrote, APIs evolve).

For anything past a single hunk, diffview.nvim takes over — `<leader>gd` opens a full diff view of the working tree, `<leader>gH` opens file history for whatever buffer I'm in. It's not trying to replace a terminal git client, it's the two things I actually needed: "what changed" and "what changed over time," both without losing my cursor position in the file I was just editing.

None of this is special. It's the same git operations I'd run from a shell, just addressed as objects in the buffer instead of typed as separate commands. The workflow got shorter mostly by not making me leave.
