Skip to content

axkirillov/unified.nvim

Repository files navigation

unified.nvim

A Neovim plugin for displaying inline unified diffs directly in your buffer.

image

Features

  • Inline Diffs: View git diffs directly in your buffer, without needing a separate window.
  • File Tree Explorer: A file tree explorer is displayed, showing all files that have been changed.
  • Git Gutter Signs: Gutter signs are used to indicate added, modified, and deleted lines.
  • Customizable: Configure the signs, highlights, and line symbols to your liking.
  • Auto-refresh: The diff view automatically refreshes as you make changes to the buffer.

Requirements

  • Neovim >= 0.5.0
  • Git
  • A Nerd Font installed and configured in your terminal/GUI is required to display file icons correctly in the file tree.

Installation

You can install unified.nvim using your favorite plugin manager.

{
  'axkirillov/unified.nvim',
  opts = {
    -- your configuration comes here
  }
}
use {
  'axkirillov/unified.nvim',
  config = function()
    require('unified').setup({
      -- your configuration comes here
    })
  end
}

Configuration

You can configure unified.nvim by passing a table to the setup() function. Here are the default settings:

require('unified').setup({
  signs = {
    add = "",
    delete = "",
    change = "",
  },
  highlights = {
    add = "DiffAdd",
    delete = "DiffDelete",
    change = "DiffChange",
  },
  line_symbols = {
    add = "+",
    delete = "-",
    change = "~",
  },
  auto_refresh = true, -- Whether to automatically refresh diff when buffer changes
})

Usage

  1. Open a file in a git repository.
  2. Make some changes to the file.
  3. Run the command :Unified to display the diff against HEAD and open the file tree.
  4. To close the diff view and file tree, run :Unified again.
  5. To show the diff against a specific commit, run :Unified <commit_ref>, for example :Unified HEAD~1.

File Tree Interaction

When the file tree is open, you can use the following keymaps:

  • j/k or <Down>/<Up>: Move the cursor down/up between file nodes.
  • l: Open the file under the cursor in the main window, displaying its diff.
  • q: Close the file tree window.
  • R: Refresh the file tree.
  • ?: Show a help dialog.

When the file tree opens, the first file is automatically opened in the main window.

The file tree displays the Git status of each file:

  • M: Modified
  • A: Added
  • D: Deleted
  • R: Renamed
  • C: Copied
  • ?: Untracked

Navigating Hunks

To navigate between hunks, you'll need to set your own keymaps:

vim.keymap.set('n', ']h', function() require('unified.navigation').next_hunk() end)
vim.keymap.set('n', '[h', function() require('unified.navigation').previous_hunk() end)

Toggle API

For programmatic control, you can use the toggle function:

vim.keymap.set('n', '<leader>ud', require('unified').toggle, { desc = 'Toggle unified diff' })

This toggles the diff view on/off, remembering the previous commit reference.

Hunk actions (API)

Unified provides a function-only API for hunk actions. Define your own keymaps or commands if desired.

Example keymaps:

local actions = require('unified.hunk_actions')
vim.keymap.set('n', 'gs', actions.stage_hunk,   { desc = 'Unified: Stage hunk' })
vim.keymap.set('n', 'gu', actions.unstage_hunk, { desc = 'Unified: Unstage hunk' })
vim.keymap.set('n', 'gr', actions.revert_hunk,  { desc = 'Unified: Revert hunk' })

Behavior notes:

  • Operates on the hunk under the cursor inside a regular file buffer (not in the unified file tree buffer).
  • Stage: applies a minimal single-hunk patch to the index.
  • Unstage: reverse-applies the hunk patch from the index.
  • Revert: reverse-applies the hunk patch to the working tree.
  • Binary patches are skipped with a user message.
  • After an action, the inline diff and file tree are refreshed automatically.

Commands

  • :Unified: Toggles the diff view. If closed, it shows the diff against HEAD. If open, it closes the view.
  • :Unified <commit_ref>: Shows the diff against the specified commit reference (e.g., a commit hash, branch name, or tag) and opens the file tree for that range.
  • :Unified reset: Removes all unified diff highlights and signs from the current buffer and closes the file tree window if it is open.

Development

Running Tests

To run all automated tests:

make tests

To run a specific test function:

make test TEST=test_file_name.test_function_name

License

MIT