SkillAgentSearch skills...

Codediff.nvim

A Neovim plugin that provides VSCode-style diff rendering with two-tier highlighting (line + character level) in side-by-side and inline layouts, using VSCode's algorithm implemented in C.

Install / Use

/learn @esmuellert/Codediff.nvim
About this skill

Quality Score

0/100

Supported Platforms

GitHub Copilot

README

codediff.nvim

Downloads

A Neovim plugin that provides VSCode-style diff rendering with two-tier highlighting, supporting both side-by-side and inline (unified) layouts.

<div align="center">

VSCode-style diff view showing side-by-side comparison with two-tier highlighting

</div> <div align="center">

https://github.com/user-attachments/assets/64c41f01-dffe-4318-bce4-16eec8de356e

Demo: Quick walkthrough of diff features

</div>

Features

  • Two-tier highlighting system:
    • Light backgrounds for entire modified lines (green for insertions, red for deletions)
    • Deep/dark character-level highlights showing exact changes within lines
  • Side-by-side diff view in a new tab with synchronized scrolling
  • Inline (unified) diff view — single-window layout with deleted lines as virtual overlays, with treesitter syntax highlighting
  • Toggle layout — switch between side-by-side and inline layout at runtime with t
  • Git integration: Compare between any git revision (HEAD, commits, branches, tags)
  • Same implementation as VSCode's diff engine, providing identical visual highlighting for most scenarios
  • Fast C-based diff computation using FFI with multi-core parallelization (OpenMP)
  • Async git operations - non-blocking file retrieval from git
  • Moved code detection — identifies blocks of code that moved within a file, with visual indicators (highlights, signs, annotations) matching VSCode's experimental showMoves feature (opt-in)

Installation

Prerequisites

  • Neovim >= 0.7.0 (for Lua FFI support; 0.10+ recommended for vim.system)
  • Git (for git diff features)
  • curl or wget (for automatic binary download) No compiler required! The plugin automatically downloads pre-built binaries from GitHub releases.

Using lazy.nvim

Minimal installation:

{
  "esmuellert/codediff.nvim",
  cmd = "CodeDiff",
}

Note: The plugin automatically adapts to your colorscheme's background (dark/light). It uses DiffAdd and DiffDelete for line-level diffs, and auto-adjusts brightness for character-level highlights (1.4x brighter for dark themes, 0.92x darker for light themes). See Highlight Groups for customization.

With custom configuration:

{
  "esmuellert/codediff.nvim",
  cmd = "CodeDiff",
  opts = {
    -- Highlight configuration
    highlights = {
      -- Line-level: accepts highlight group names or hex colors (e.g., "#2ea043")
      line_insert = "DiffAdd",      -- Line-level insertions
      line_delete = "DiffDelete",   -- Line-level deletions

      -- Character-level: accepts highlight group names or hex colors
      -- If specified, these override char_brightness calculation
      char_insert = nil,            -- Character-level insertions (nil = auto-derive)
      char_delete = nil,            -- Character-level deletions (nil = auto-derive)

      -- Brightness multiplier (only used when char_insert/char_delete are nil)
      -- nil = auto-detect based on background (1.4 for dark, 0.92 for light)
      char_brightness = nil,        -- Auto-adjust based on your colorscheme

      -- Conflict sign highlights (for merge conflict views)
      -- Accepts highlight group names or hex colors (e.g., "#f0883e")
      -- nil = use default fallback chain
      conflict_sign = nil,          -- Unresolved: DiagnosticSignWarn -> #f0883e
      conflict_sign_resolved = nil, -- Resolved: Comment -> #6e7681
      conflict_sign_accepted = nil, -- Accepted: GitSignsAdd -> DiagnosticSignOk -> #3fb950
      conflict_sign_rejected = nil, -- Rejected: GitSignsDelete -> DiagnosticSignError -> #f85149
    },

    -- Diff view behavior
    diff = {
      layout = "side-by-side",             -- Diff layout: "side-by-side" (two panes) or "inline" (single pane with virtual lines)
      disable_inlay_hints = true,         -- Disable inlay hints in diff windows for cleaner view
      max_computation_time_ms = 5000,     -- Maximum time for diff computation (VSCode default)
      ignore_trim_whitespace = false,     -- Ignore leading/trailing whitespace changes (like diffopt+=iwhite)
      hide_merge_artifacts = false,       -- Hide merge tool temp files (*.orig, *.BACKUP.*, *.BASE.*, *.LOCAL.*, *.REMOTE.*)
      original_position = "left",         -- Position of original (old) content: "left" or "right"
      conflict_ours_position = "right",   -- Position of ours (:2) in conflict view: "left" or "right"
      conflict_result_position = "bottom", -- "bottom" (default): result below diff panes or "center": result between diff panes (three columns)
      conflict_result_height = 30,         -- Height of result pane in bottom layout (% of total height)
      conflict_result_width_ratio = { 1, 1, 1 }, -- Width ratio for center layout panes {left, center, right} (e.g., {1, 2, 1} for wider result)
      cycle_next_hunk = true,             -- Wrap around when navigating hunks (]c/[c): false to stop at first/last
      cycle_next_file = true,             -- Wrap around when navigating files (]f/[f): false to stop at first/last
      jump_to_first_change = true,        -- Auto-scroll to first change when opening a diff: false to stay at same line
      highlight_priority = 100,           -- Priority for line-level diff highlights (increase to override LSP highlights)
      compute_moves = false,              -- Detect moved code blocks (opt-in, matches VSCode experimental.showMoves)
    },

    -- Explorer panel configuration
    explorer = {
      position = "left",  -- "left" or "bottom"
      width = 40,         -- Width when position is "left" (columns)
      height = 15,        -- Height when position is "bottom" (lines)
      indent_markers = true,  -- Show indent markers in tree view (│, ├, └)
      initial_focus = "explorer",  -- Initial focus: "explorer", "original", or "modified"
      icons = {
        folder_closed = "",  -- Nerd Font folder icon (customize as needed)
        folder_open = "",    -- Nerd Font folder-open icon
      },
      view_mode = "list",    -- "list" or "tree"
      flatten_dirs = true,   -- Flatten single-child directory chains in tree view
      file_filter = {
        ignore = { ".git/**", ".jj/**" },  -- Glob patterns to hide (e.g., {"*.lock", "dist/*"})
      },
      focus_on_select = false,  -- Jump to modified pane after selecting a file (default: stay in explorer)
      visible_groups = {       -- Which groups to show (can be toggled at runtime)
        staged = true,
        unstaged = true,
        conflicts = true,
      },
    },

    -- History panel configuration (for :CodeDiff history)
    history = {
      position = "bottom",  -- "left" or "bottom" (default: bottom)
      width = 40,           -- Width when position is "left" (columns)
      height = 15,          -- Height when position is "bottom" (lines)
      initial_focus = "history",  -- Initial focus: "history", "original", or "modified"
      view_mode = "list",   -- "list" or "tree" for files under commits
    },

    -- Keymaps in diff view
    keymaps = {
      view = {
        quit = "q",                    -- Close diff tab
        toggle_explorer = "<leader>b",  -- Toggle explorer visibility (explorer mode only)
        focus_explorer = "<leader>e",   -- Focus explorer panel (explorer mode only)
        next_hunk = "]c",   -- Jump to next change
        prev_hunk = "[c",   -- Jump to previous change
        next_file = "]f",   -- Next file in explorer/history mode
        prev_file = "[f",   -- Previous file in explorer/history mode
        diff_get = "do",    -- Get change from other buffer (like vimdiff)
        diff_put = "dp",    -- Put change to other buffer (like vimdiff)
        open_in_prev_tab = "gf", -- Open current buffer in previous tab (or create one before)
        close_on_open_in_prev_tab = false, -- Close codediff tab after gf opens file in previous tab
        toggle_stage = "-", -- Stage/unstage current file (works in explorer and diff buffers)
        stage_hunk = "<leader>hs",   -- Stage hunk under cursor to git index
        unstage_hunk = "<leader>hu", -- Unstage hunk under cursor from git index
        discard_hunk = "<leader>hr", -- Discard hunk under cursor (working tree only)
        hunk_textobject = "ih",      -- Textobject for hunk (vih to select, yih to yank, etc.)
        show_help = "g?",   -- Show floating window with available keymaps
        align_move = "gm", -- Temporarily align moved code blocks across panes
        toggle_layout = "t", -- Toggle between side-by-side and inline layout
      },
      explorer = {
        select = "<CR>",    -- Open diff for selected file
        hover = "K",        -- Show file diff preview
        refresh = "R",      -- Refresh git status
        toggle_view_mode = "i",  -- Toggle between 'list' and 'tree' views
        stage_all = "S",    -- Stage all files
        unstage_all = "U",  -- Unstage all files
        restore = "X",      -- Discard changes (restore file)
        toggle_changes = "gu",  -- Toggle Changes (unstaged) group visibility
        toggle_staged = "gs",   -- Toggle Staged Changes group visibility
        -- Fold keymaps (Vim-style)
        fold_open = "zo",           -- Open fold (expand current node)
        fold_open_recursive = "zO", -- Open fold recursively (expand all descendants)
        fold_close = "zc",          -- Close fold (collapse current node)
        fold_close_recursive = "zC", -- Close fold recursively (collapse all descendants)
        fold_toggle = "za",         -- Toggle fold (expand/collapse current node)
        fold_toggle_recursive = "zA", -- Toggle fold recursively
        fold_open_all = "zR",       -- Open all folds in tree
        fold_close_all = "zM",     

Related Skills

View on GitHub
GitHub Stars1.2k
CategoryDevelopment
Updated4h ago
Forks49

Languages

Lua

Security Score

100/100

Audited on Mar 26, 2026

No findings