Skip to content

Conversation

@barrettruth
Copy link
Owner

Adds du and dU keymaps to fugitive's :Git status buffer for opening unified diffs (single buffer with +/- lines) instead of side-by-side diffs.

Keymaps mirror fugitive's existing diff bindings:

  • du → horizontal split (like dd)
  • dU → vertical split (like dv)

Section-aware diffing:

  • Cursor on staged file → diffs index vs HEAD
  • Cursor on unstaged file → diffs working tree vs index
  • Cursor on hunk line → walks back to find parent file

Configurable via:

vim.g.diffs = {
  fugitive = {
    horizontal = 'du',  -- or false to disable
    vertical = 'dU',
  },
}

Closes #59

Adds functions for accessing git index content and working tree files:
- get_index_content() retrieves file from staging area via :0:path
- get_working_content() reads file directly from disk
- file_exists_in_index() checks if file is staged
- file_exists_at_revision() checks if file exists at given revision
Adds gdiff_file() which can diff any file path (not just current buffer)
with support for staged vs unstaged changes:
- staged=true diffs index against HEAD
- staged=false diffs working tree against index
- Falls back to HEAD if file not in index (for untracked comparison)
Adds du/dU keymaps to fugitive's :Git status buffer for opening unified
diffs instead of side-by-side diffs:
- du opens horizontal split (mirrors dd)
- dU opens vertical split (mirrors dv)

Parses status buffer lines to extract filename and detect section
(staged/unstaged/untracked). For staged files, diffs index vs HEAD.
For unstaged files, diffs working tree vs index.

Configurable via vim.g.diffs.fugitive.horizontal/vertical (set to
false to disable).
Tests for get_section_at_line() and get_file_at_line() covering:
- Section detection (staged, unstaged, untracked)
- File parsing (modified, added, deleted, renamed, untracked)
- Hunk line walk-back to parent file
- Files appearing in multiple sections
Section headers (Staged/Unstaged) now show all diffs in that section,
matching fugitive's behavior. Untracked files show as all-added diffs.
Deleted files show as all-removed diffs.

Also handles edge cases:
- Empty new/old content for deleted/new files
- Section header detection returns is_header flag
Parse both old and new filenames from rename lines (R old -> new).
When diffing staged renames, use old filename as base to correctly
show content changes rather than treating the file as entirely new.

Also adds comprehensive tests for filename edge cases:
- Double extensions, hyphens, underscores, dotfiles
- Deep nested paths, complex renames
- Documents known limitation with filenames containing ' -> '
@barrettruth barrettruth merged commit b5ec99f into main Feb 5, 2026
7 checks passed
@barrettruth barrettruth deleted the feat/fugitive-keymaps branch February 5, 2026 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fugitive: keymaps for unified diff in :Git status

1 participant