Home

Awesome

<img src="https://github.com/echasnovski/media/blob/main/mini.nvim/logo/logo_diff.png" style="width: 100%"> <!-- badges: start -->

GitHub license

<!-- badges: end -->

Work with diff hunks

See more details in Features and help file.


⦿ This is a part of mini.nvim library. Please use this link if you want to mention this module.

⦿ All contributions (issues, pull requests, discussions, etc.) are done inside of 'mini.nvim'.

⦿ See the repository page to learn about common design principles and configuration recipes.


If you want to help this project grow but don't know where to start, check out contributing guides of 'mini.nvim' or leave a Github star for 'mini.nvim' project and/or any its standalone Git repositories.

Demo

https://github.com/echasnovski/mini.nvim/assets/24854248/77849127-ee9f-430b-9eff-5a8a724c21ea

Features

What it doesn't do:

To read more information, see these tags in help file:

Overview

Diffs and hunks

The "diff" (short for "difference") is a result of computing how two text strings differ from one another. This is done on per line basis, i.e. the goal is to compute sequences of lines common to both files, interspersed with groups of differing lines (called "hunks").

Although computing diff is a general concept (used on its own, in Git, etc.), this module computes difference between current text in a buffer and some reference text which is kept up to date specifically for that buffer. For example, default reference text is computed as file content in Git index. This can be customized in config.source.

Life cycle

Notes:

Overlay

Along with basic visualization, there is a special view called "overlay". Although it is meant for temporary overview of diff details and can be manually toggled via MiniDiff.toggle_overlay(), text can be changed with overlay reacting accordingly.

It shows more diff details inside text area:

Mappings

This module provides mappings for common actions with diffs, like:

Examples:

Mappings for some functionality are assumed to be done manually. See tag *MiniDiff.operator()* in help file.

Buffer-local variables

Each enabled buffer has the following buffer-local variables which can be used in custom statusline to show an overview of hunks in current buffer:

Installation

This plugin can be installed as part of 'mini.nvim' library (recommended) or as a standalone Git repository.

There are two branches to install from:

Here are code snippets for some common installation methods (use only one):

<details> <summary>With <a href="https://github.com/echasnovski/mini.nvim/blob/main/readmes/mini-deps.md">mini.deps</a></summary> <table> <thead> <tr> <th>Github repo</th> <th>Branch</th> <th>Code snippet</th> </tr> </thead> <tbody> <tr> <td rowspan=2>'mini.nvim' library</td> <td>Main</td> <td rowspan=2><i>Follow recommended 'mini.deps' installation</i></td> </tr> <tr> <td>Stable</td> </tr> <tr> <td rowspan=2>Standalone plugin</td> <td>Main</td> <td><code>add('echasnovski/mini.diff')</code></td> </tr> <tr> <td>Stable</td> <td><code>add({ source = 'echasnovski/mini.diff', checkout = 'stable' })</code></td> </tr> </tbody> </table> </details> <details> <summary>With <a href="https://github.com/folke/lazy.nvim">folke/lazy.nvim</a></summary> <table> <thead> <tr> <th>Github repo</th> <th>Branch</th> <th>Code snippet</th> </tr> </thead> <tbody> <tr> <td rowspan=2>'mini.nvim' library</td> <td>Main</td> <td><code>{ 'echasnovski/mini.nvim', version = false },</code></td> </tr> <tr> <td>Stable</td> <td><code>{ 'echasnovski/mini.nvim', version = '*' },</code></td> </tr> <tr> <td rowspan=2>Standalone plugin</td> <td>Main</td> <td><code>{ 'echasnovski/mini.diff', version = false },</code></td> </tr> <tr> <td>Stable</td> <td><code>{ 'echasnovski/mini.diff', version = '*' },</code></td> </tr> </tbody> </table> </details> <details> <summary>With <a href="https://github.com/junegunn/vim-plug">junegunn/vim-plug</a></summary> <table> <thead> <tr> <th>Github repo</th> <th>Branch</th> <th>Code snippet</th> </tr> </thead> <tbody> <tr> <td rowspan=2>'mini.nvim' library</td> <td>Main</td> <td><code>Plug 'echasnovski/mini.nvim'</code></td> </tr> <tr> <td>Stable</td> <td><code>Plug 'echasnovski/mini.nvim', { 'branch': 'stable' }</code></td> </tr> <tr> <td rowspan=2>Standalone plugin</td> <td>Main</td> <td><code>Plug 'echasnovski/mini.diff'</code></td> </tr> <tr> <td>Stable</td> <td><code>Plug 'echasnovski/mini.diff', { 'branch': 'stable' }</code></td> </tr> </tbody> </table> </details> <br>

Important: don't forget to call require('mini.diff').setup() to enable its functionality.

Note: if you are on Windows, there might be problems with too long file paths (like error: unable to create file <some file name>: Filename too long). Try doing one of the following:

Default config

-- No need to copy this inside `setup()`. Will be used automatically.
{
  -- Options for how hunks are visualized
  view = {
    -- Visualization style. Possible values are 'sign' and 'number'.
    -- Default: 'number' if line numbers are enabled, 'sign' otherwise.
    style = vim.go.number and 'number' or 'sign',

    -- Signs used for hunks with 'sign' view
    signs = { add = '▒', change = '▒', delete = '▒' },

    -- Priority of used visualization extmarks
    priority = 199,
  },

  -- Source for how reference text is computed/updated/etc
  -- Uses content from Git index by default
  source = nil,

  -- Delays (in ms) defining asynchronous processes
  delay = {
    -- How much to wait before update following every text change
    text_change = 200,
  },

  -- Module mappings. Use `''` (empty string) to disable one.
  mappings = {
    -- Apply hunks inside a visual/operator region
    apply = 'gh',

    -- Reset hunks inside a visual/operator region
    reset = 'gH',

    -- Hunk range textobject to be used inside operator
    -- Works also in Visual mode if mapping differs from apply and reset
    textobject = 'gh',

    -- Go to hunk range in corresponding direction
    goto_first = '[H',
    goto_prev = '[h',
    goto_next = ']h',
    goto_last = ']H',
  },

  -- Various options
  options = {
    -- Diff algorithm. See `:h vim.diff()`.
    algorithm = 'histogram',

    -- Whether to use "indent heuristic". See `:h vim.diff()`.
    indent_heuristic = true,

    -- The amount of second-stage diff to align lines (in Neovim>=0.9)
    linematch = 60,

    -- Whether to wrap around edges during hunk navigation
    wrap_goto = false,
  },
}

Similar plugins