Skip to content

select_hunk only works in visual mode when linematch:n is in diffopt #1187

@mmirus

Description

@mmirus

Description

When diffopt contains linematch:n, Gitsign's select_hunk doesn't work correctly outside of visual mode. In other words, vih will work, but not cih or dih.

Neovim version

NVIM v0.10.3 Build type: RelWithDebInfo LuaJIT 2.1.1731601260

Operating system and version

Arch Linux

Expected behavior

select_hunk should work with operators such as cih and dih, even when diffopt includes linematch:n.

Actual behavior

When cih or dih are used, the hunk is visually selected:

gitsigns-select-hunk-diffopt.mp4

cih selects the hunk and leaves nvim displaying INSERT VISUAL LINE as the mode. Pressing escape once switches to just VISUAL LINE. Pressing escape a second time returns to normal mode.

dih selects the hunk and leaves nvim in visual line mode.

Minimal config

for name, url in pairs{
	gitsigns = 'https://github.com/lewis6991/gitsigns.nvim',
	-- ADD OTHER PLUGINS _NECESSARY_ TO REPRODUCE THE ISSUE
} do
local install_path = vim.fn.fnamemodify('gitsigns_issue/'..name, ':p')
if vim.fn.isdirectory(install_path) == 0 then
	vim.fn.system { 'git', 'clone', '--depth=1', url, install_path }
end
vim.opt.runtimepath:append(install_path)
end

require('gitsigns').setup{
	debug_mode = true, -- You must add this to enable debug messages
	-- ADD GITSIGNS CONFIG THAT IS _NECESSARY_ FOR REPRODUCING THE ISSUE
	on_attach = function(bufnr)
		local gitsigns = require('gitsigns')

		local function map(mode, l, r, opts)
			opts = opts or {}
			opts.buffer = bufnr
			vim.keymap.set(mode, l, r, opts)
		end

		-- Text object
		map({'o', 'x'}, 'ih', ':<C-U>Gitsigns select_hunk<CR>')
	end
}

-- ADD INIT.LUA SETTINGS THAT IS _NECESSARY_ FOR REPRODUCING THE ISSUE
vim.opt.diffopt:append("linematch:60")

Steps to reproduce

  1. mkdir gitsigns_issue
  2. cd gitsigns_issue
  3. Copy the minimal.lua into this folder
  4. git init
  5. touch file
  6. git add file
  7. git commit -m 'initial commit'
  8. echo "new hunk" >> file
  9. nvim --clean -u minimal.lua file
  10. press cih or dih

Gitsigns debug messages

1.76 D dprintf: Deriving GitSignsAdd from Added
1.89 D derive: Deriving GitSignsChange from Changed
1.99 D derive: Deriving GitSignsDelete from Removed
2.09 D derive: Deriving GitSignsChangedelete from GitSignsChange
2.18 D derive: Deriving GitSignsTopdelete from GitSignsDelete
2.24 D derive: Deriving GitSignsUntracked from GitSignsAdd
2.31 D derive: Deriving GitSignsAddNr from GitSignsAdd
2.38 D derive: Deriving GitSignsChangeNr from GitSignsChange
2.48 D derive: Deriving GitSignsDeleteNr from GitSignsDelete
2.52 D derive: Deriving GitSignsChangedeleteNr from GitSignsChangeNr
2.60 D derive: Deriving GitSignsTopdeleteNr from GitSignsDeleteNr
2.70 D derive: Deriving GitSignsUntrackedNr from GitSignsAddNr
2.78 D derive: Deriving GitSignsAddLn from DiffAdd
2.86 D derive: Deriving GitSignsChangeLn from DiffChange
2.93 D derive: Deriving GitSignsChangedeleteLn from GitSignsChangeLn
2.97 D derive: Deriving GitSignsTopdeleteLn from GitSignsDeleteLn
3.01 D derive: Deriving GitSignsUntrackedLn from GitSignsAddLn
3.05 D derive: Deriving GitSignsAddCul from GitSignsAdd
3.10 D derive: Deriving GitSignsChangeCul from GitSignsChange
3.15 D derive: Deriving GitSignsDeleteCul from GitSignsDelete
3.19 D derive: Deriving GitSignsChangedeleteCul from GitSignsChangeCul
3.23 D derive: Deriving GitSignsTopdeleteCul from GitSignsDeleteCul
3.32 D derive: Deriving GitSignsUntrackedCul from GitSignsAddCul
3.41 D derive: Deriving GitSignsStagedAdd from GitSignsAdd
3.56 D derive: Deriving GitSignsStagedChange from GitSignsChange
3.61 D derive: Deriving GitSignsStagedDelete from GitSignsDelete
3.66 D derive: Deriving GitSignsStagedChangedelete from GitSignsChangedelete
3.70 D derive: Deriving GitSignsStagedTopdelete from GitSignsTopdelete
3.74 D derive: Deriving GitSignsStagedUntracked from GitSignsUntracked
3.80 D derive: Deriving GitSignsStagedAddNr from GitSignsAddNr
3.87 D derive: Deriving GitSignsStagedChangeNr from GitSignsChangeNr
3.91 D derive: Deriving GitSignsStagedDeleteNr from GitSignsDeleteNr
4.00 D derive: Deriving GitSignsStagedChangedeleteNr from GitSignsChangedeleteNr
4.04 D derive: Deriving GitSignsStagedTopdeleteNr from GitSignsTopdeleteNr
4.09 D derive: Deriving GitSignsStagedUntrackedNr from GitSignsUntrackedNr
4.13 D derive: Deriving GitSignsStagedAddLn from GitSignsAddLn
4.17 D derive: Deriving GitSignsStagedChangeLn from GitSignsChangeLn
4.23 D derive: Deriving GitSignsStagedChangedeleteLn from GitSignsChangedeleteLn
4.26 D derive: Could not derive GitSignsStagedTopdeleteLn
4.31 D derive: Deriving GitSignsStagedUntrackedLn from GitSignsUntrackedLn
4.35 D derive: Deriving GitSignsStagedAddCul from GitSignsAddCul
4.39 D derive: Deriving GitSignsStagedChangeCul from GitSignsChangeCul
4.44 D derive: Deriving GitSignsStagedDeleteCul from GitSignsDeleteCul
4.48 D derive: Deriving GitSignsStagedChangedeleteCul from GitSignsChangedeleteCul
4.52 D derive: Deriving GitSignsStagedTopdeleteCul from GitSignsTopdeleteCul
4.56 D derive: Deriving GitSignsStagedUntrackedCul from GitSignsUntrackedCul
4.61 D derive: Deriving GitSignsAddPreview from DiffAdd
4.66 D derive: Deriving GitSignsDeletePreview from DiffDelete
4.70 D derive: Deriving GitSignsCurrentLineBlame from NonText
4.75 D derive: Deriving GitSignsAddInline from TermCursor
4.80 D derive: Deriving GitSignsDeleteInline from TermCursor
4.85 D derive: Deriving GitSignsChangeInline from TermCursor
4.89 D derive: Deriving GitSignsAddLnInline from GitSignsAddInline
5.01 D derive: Deriving GitSignsChangeLnInline from GitSignsChangeInline
5.05 D derive: Deriving GitSignsDeleteLnInline from GitSignsDeleteInline
5.10 D derive: Deriving GitSignsDeleteVirtLn from DiffDelete
5.15 D derive: Deriving GitSignsDeleteVirtLnInLine from GitSignsDeleteLnInline
5.19 D derive: Deriving GitSignsVirtLnum from GitSignsDeleteVirtLn
15.76 D attach(1): Attaching (trigger=BufReadPost)
15.87 D run_job: git --version
22.32 D run_job: git --no-pager --no-optional-locks --literal-pathspecs -c gc.auto=0 rev-parse --show-toplevel --absolute-git-dir --abbrev-ref HEAD
23.94 D run_job: git --no-pager --no-optional-locks --literal-pathspecs -c gc.auto=0 --git-dir /home/mmirus/gitsigns_issue/.git config user.name
25.56 D run_job: git --no-pager --no-optional-locks --literal-pathspecs -c gc.auto=0 --git-dir /home/mmirus/gitsigns_issue/.git -c core.quotepath=off ls-files --stage --others --exclude-standard --eol /home/mmirus/gitsigns_issue/file
27.98 D watch_gitdir(1): Watching git dir
28.12 D run_job: git --no-pager --no-optional-locks --literal-pathspecs -c gc.auto=0 --git-dir /home/mmirus/gitsigns_issue/.git show e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
32.09 D run_job: git --no-pager --no-optional-locks --literal-pathspecs -c gc.auto=0 --git-dir /home/mmirus/gitsigns_issue/.git show HEAD:file
883.93 D cli.run: Running action 'select_hunk' with arguments {}
2795.52 D cli.run: Running action 'select_hunk' with arguments {}
7359.62 D cli.run: Running action 'debug_messages' with arguments {}
21194.20 D cli.run: Running action 'debug_messages' with arguments {}

Gitsigns cache

{ {
    bufnr = 1,
    compare_text = { "...",
      head = "",
      length = 1
    },
    compare_text_head = { "...",
      head = "",
      length = 1
    },
    file = "/home/mmirus/gitsigns_issue/file",
    force_next_update = false,
    git_obj = {
      encoding = "utf-8",
      file = "/home/mmirus/gitsigns_issue/file",
      i_crlf = false,
      mode_bits = "100644",
      object_name = "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
      relpath = "file",
      repo = {
        abbrev_head = "master",
        detached = false,
        gitdir = "/home/mmirus/gitsigns_issue/.git",
        toplevel = "/home/mmirus/gitsigns_issue",
        username = "Matt Mirus"
      },
      w_crlf = false
    },
    gitdir_watcher = <userdata 1>,
    hunks = { "...",
      head = {
        added = {
          count = 1,
          lines = { "new hunk" },
          start = 1
        },
        head = "@@ -0 +1,1 @@",
        removed = {
          count = 0,
          lines = {},
          start = 0
        },
        type = "add",
        vend = 1
      },
      length = 1
    },
    hunks_staged = { "...",
      length = 0
    },
    staged_diffs = { "...",
      length = 0
    }
  } }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions