Merge pull request #18 from oug-t/feat/fugitive-support

feat: add integration with vim-fugitive
This commit is contained in:
Tommy Guo 2026-02-06 17:06:57 -05:00 committed by GitHub
commit 45df5cdc86
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 20 deletions

View File

@ -1,4 +1,5 @@
<a id="readme-top"></a>
<h1 align="center"><code>difi</code></h1>
<p align="center"><em>Review and refine Git diffs before you push</em></p>
@ -14,7 +15,7 @@
## Why difi?
**git diff** shows changes. **difi** helps you *review* them.
**git diff** shows changes. **difi** helps you _review_ them.
- ⚡️ **Instant** — Built in Go. Launches immediately with no daemon or indexing.
- 🎨 **Structured** — A clean file tree and focused diffs for fast mental parsing.
@ -41,11 +42,13 @@ go install github.com/oug-t/difi/cmd/difi@latest
#### AUR (Arch Linux)
**Binary (pre-built):**
```bash
pikaur -S difi-bin
```
**Build from source:**
```bash
pikaur -S difi
```
@ -81,7 +84,27 @@ difi
<p align="right">(<a href="#readme-top">back to top</a>)</p>
## Neovim Integration
## Integrations
#### vim-fugitive
- **The "Unix philosophy" approach:** Uses the industry-standard Git wrapper to provide a robust, side-by-side editing experience.
- **Side-by-Side Editing:** Instantly opens a vertical split (:Gvdiffsplit!) against the index.
- **Merge Conflicts:** Automatically detects conflicts and opens a 3-way merge view for resolution.
- **Config**: Add the line below to if using **lazy.nvim**.
```lua
{
"tpope/vim-fugitive",
cmd = { "Gvdiffsplit", "Git" }, -- Add this line
}
```
<p align="left">
<img src="https://img.shields.io/badge/Supports-vim--fugitive-4d4d4d?style=for-the-badge&logo=vim&logoColor=white" alt="Supports vim-fugitive" />
</p>
#### difi.nvim
Get the ultimate review experience with **[difi.nvim](https://github.com/oug-t/difi.nvim)**.
@ -105,7 +128,9 @@ To use `difi` as a native git command (e.g., `git difi`), add it as an alias in
```bash
git config --global alias.difi '!difi'
```
Now you can run it directly from git:
```bash
git difi
```
@ -121,6 +146,7 @@ go run cmd/difi/main.go
```
Contributions are especially welcome in:
- diff.nvim rendering edge cases
- UI polish and accessibility
- Windows support
@ -143,13 +169,3 @@ Contributions are especially welcome in:
---
<p align="center"> Made with ❤️ by <a href="https://github.com/oug-t">oug-t</a> </p>

View File

@ -3,6 +3,8 @@ package ui
import (
"fmt"
"math"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
@ -225,13 +227,14 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
}
if m.selectedPath != "" {
if i, ok := m.fileList.SelectedItem().(tree.TreeItem); ok && !i.IsDir {
// proceed
line := 0
if m.focus == FocusDiff {
line = git.CalculateFileLine(m.diffContent, m.diffCursor)
} else {
return m, nil
line = git.CalculateFileLine(m.diffContent, 0)
}
return m, openFugitive(m.selectedPath, line)
}
fallthrough
case "e":
if m.selectedPath != "" {
@ -246,7 +249,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
line = git.CalculateFileLine(m.diffContent, 0)
}
m.inputBuffer = ""
return m, git.OpenEditorCmd(m.selectedPath, line, m.targetBranch)
return m, openFugitive(m.selectedPath, line)
}
case "z":
@ -370,6 +373,17 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, tea.Batch(cmds...)
}
func openFugitive(path string, line int) tea.Cmd {
lineArg := fmt.Sprintf("+%d", line)
c := exec.Command("nvim", lineArg, "-c", "Gvdiffsplit!", path)
c.Stdin = os.Stdin
c.Stdout = os.Stdout
c.Stderr = os.Stderr
return tea.ExecProcess(c, func(err error) tea.Msg {
return git.EditorFinishedMsg{}
})
}
func (m *Model) centerDiffCursor() {
halfScreen := m.diffViewport.Height / 2
targetOffset := m.diffCursor - halfScreen
@ -578,7 +592,7 @@ func (m Model) renderHelpDrawer() string {
)
col4 := lipgloss.JoinVertical(lipgloss.Left,
HelpTextStyle.Render("H/M/L Move Cursor"),
HelpTextStyle.Render("e Edit File"),
HelpTextStyle.Render("e Edit File"),
)
return HelpDrawerStyle.Copy().
@ -661,8 +675,6 @@ func (m Model) renderEmptyState(w, h int, statusMsg string) string {
guides,
)
// Use lipgloss.Place to center the content in the available space
// This automatically handles vertical and horizontal centering.
return lipgloss.Place(w, h, lipgloss.Center, lipgloss.Center, content)
}