feat(actions): true partial hunk staging

Resolves #338
This commit is contained in:
Lewis Russell 2021-11-21 18:23:18 +00:00
parent 0ffa5a082e
commit f362e54e11
14 changed files with 450 additions and 205 deletions

View File

@ -189,7 +189,7 @@ Stage/reset all hunks in buffer | :white_check_mark:
Undo staged hunks | :white_check_mark: | |
Word diff in buffer | :white_check_mark: | |
Word diff in hunk preview | :white_check_mark: | :white_check_mark: |
Stage partial hunks | | :white_check_mark: |
Stage partial hunks | :white_check_mark: | |
Hunk text object | :white_check_mark: | :white_check_mark: |
Diff against index or any commit | :white_check_mark: | :white_check_mark: |
Folding of unchanged text | | :white_check_mark: |

View File

@ -132,9 +132,11 @@ prev_hunk({opts}) *gitsigns.prev_hunk()*
See |gitsigns.next_hunk()|.
stage_hunk({range}) *gitsigns.stage_hunk()*
Stage the hunk at the cursor position, or all hunks in the
given range. If {range} is provided, all hunks that intersect
with the given range are staged.
Stage the hunk at the cursor position, or all lines in the
given range. If {range} is provided, all lines in the given
range are staged. This supports partial-hunks, meaning if a
range only includes a portion of a particular hunk, only the
lines within the range will be staged.
Attributes: ~
{async}
@ -144,8 +146,10 @@ stage_hunk({range}) *gitsigns.stage_hunk()*
up the line range from which you want to stage the hunks.
undo_stage_hunk() *gitsigns.undo_stage_hunk()*
Undo the last call of stage_hunk(). Note: only the calls to
stage_hunk() performed in the current session can be undone.
Undo the last call of stage_hunk().
Note: only the calls to stage_hunk() performed in the current
session can be undone.
Attributes: ~
{async}
@ -166,9 +170,10 @@ reset_buffer_index() *gitsigns.reset_buffer_index()*
reset_hunk({range}) *gitsigns.reset_hunk()*
Reset the lines of the hunk at the cursor position, or all
hunks in the given range, to what it is in Git's index. If
{range} is provided, all hunks that intersect with the given
range are reset.
lines in the given range. If {range} is provided, all lines in
the given range are reset. This supports partial-hunks,
meaning if a range only includes a portion of a particular
hunk, only the lines within the range will be reset.
Parameters:~
{range} table|nil List-like table of two integers making

6
lua/gitsigns.lua generated
View File

@ -394,8 +394,8 @@ M._run_func = function(range, func, ...)
local args = parse_args_to_lua(...)
if type(actions0[func]) == 'function' then
if range and range[1] ~= range[2] then
actions.user_range = range
if range and range[1] > 0 then
actions.user_range = { range[2], range[3] }
else
actions.user_range = nil
end
@ -439,7 +439,7 @@ local function setup_command()
'-nargs=+',
'-complete=customlist,v:lua.package.loaded.gitsigns._complete',
'Gitsigns',
'lua require("gitsigns")._run_func({<line1>, <line2>}, <f-args>)',
'lua require("gitsigns")._run_func({<range>, <line1>, <line2>}, <f-args>)',
}, ' '))
end

View File

@ -77,28 +77,8 @@ local function get_cursor_hunk(bufnr, hunks)
return gs_hunks.find_hunk(lnum, hunks)
end
local function get_range_hunks(hunks, range)
local ret = {}
for _, hunk in ipairs(hunks) do
if range[1] == 1 and hunk.start == 0 and hunk.vend == 0 then
return { hunk }
end
if (range[2] >= hunk.start and range[1] <= hunk.vend) then
ret[#ret + 1] = hunk
end
end
return ret
end
M.stage_hunk = mk_repeatable(void(function(range)
range = range or M.user_range
local valid_range = false
local bufnr = current_buf()
local bcache = cache[bufnr]
if not bcache then
@ -110,29 +90,33 @@ M.stage_hunk = mk_repeatable(void(function(range)
return
end
local hunks = {}
local hunk
if range and range[1] ~= range[2] then
valid_range = true
if range then
table.sort(range)
hunks = get_range_hunks(bcache.hunks, range)
local top, bot = range[1], range[2]
hunk = gs_hunks.create_partial_hunk(bcache.hunks, top, bot)
hunk.added.lines = api.nvim_buf_get_lines(bufnr, top - 1, bot, false)
hunk.removed.lines = vim.list_slice(
bcache.compare_text,
hunk.removed.start,
hunk.removed.start + hunk.removed.count - 1)
else
hunks[1] = get_cursor_hunk(bufnr, bcache.hunks)
hunk = get_cursor_hunk(bufnr, bcache.hunks)
end
if #hunks == 0 then
if not hunk then
return
end
bcache.git_obj:stage_hunks(hunks)
bcache.git_obj:stage_hunks({ hunk })
for _, hunk in ipairs(hunks) do
table.insert(bcache.staged_diffs, hunk)
end
table.insert(bcache.staged_diffs, hunk)
bcache.compare_text = nil
local hunk_signs = gs_hunks.process_hunks(hunks)
local hunk_signs = gs_hunks.process_hunks({ hunk })
scheduler()
@ -152,34 +136,41 @@ end))
M.reset_hunk = mk_repeatable(function(range)
range = range or M.user_range
local bufnr = current_buf()
local hunks = {}
if range and range[1] ~= range[2] then
table.sort(range)
hunks = get_range_hunks(cache[bufnr].hunks, range)
else
hunks[1] = get_cursor_hunk(bufnr)
end
if #hunks == 0 then
local bcache = cache[bufnr]
if not bcache then
return
end
local offset = 0
local hunk
for _, hunk in ipairs(hunks) do
local lstart, lend
if hunk.type == 'delete' then
lstart = hunk.start
lend = hunk.start
else
lstart = hunk.start - 1
lend = hunk.start - 1 + hunk.added.count
end
local lines = hunk.removed.lines
api.nvim_buf_set_lines(bufnr, lstart + offset, lend + offset, false, lines)
offset = offset + (#lines - (lend - lstart))
if range then
table.sort(range)
local top, bot = range[1], range[2]
hunk = gs_hunks.create_partial_hunk(bcache.hunks, top, bot)
hunk.added.lines = api.nvim_buf_get_lines(bufnr, top - 1, bot, false)
hunk.removed.lines = vim.list_slice(
bcache.compare_text,
hunk.removed.start,
hunk.removed.start + hunk.removed.count - 1)
else
hunk = get_cursor_hunk(bufnr)
end
if not hunk then
return
end
local lstart, lend
if hunk.type == 'delete' then
lstart = hunk.start
lend = hunk.start
else
lstart = hunk.start - 1
lend = hunk.start - 1 + hunk.added.count
end
local lines = hunk.removed.lines
api.nvim_buf_set_lines(bufnr, lstart, lend, false, lines)
end)
M.reset_buffer = function()

View File

@ -29,10 +29,6 @@ function M.run_diff(fa, fb, diff_algo, indent_heuristic)
for _, r in ipairs(results) do
local rs, rc, as, ac = unpack(r)
local hunk = create_hunk(rs, rc, as, ac)
hunk.head = ('@@ -%d%s +%d%s @@'):format(
rs, rc > 0 and ',' .. rc or '',
as, ac > 0 and ',' .. ac or '')
if rc > 0 then
for i = rs, rs + rc - 1 do
hunk.removed.lines[#hunk.removed.lines + 1] = fa[i] or ''

45
lua/gitsigns/hunks.lua generated
View File

@ -44,6 +44,10 @@ function M.create_hunk(start_a, count_a, start_b, count_b)
start = added.start,
removed = removed,
added = added,
head = ('@@ -%d%s +%d%s @@'):format(
start_a, count_a > 0 and ',' .. count_a or '',
start_b, count_b > 0 and ',' .. count_b or ''),
}
if added.count == 0 then
@ -66,6 +70,47 @@ function M.create_hunk(start_a, count_a, start_b, count_b)
return hunk
end
function M.create_partial_hunk(hunks, top, bot)
local pretop, precount = top, bot - top + 1
for _, h in ipairs(hunks) do
local added_in_hunk = h.added.count - h.removed.count
local added_in_range = 0
if h.start >= top and h.vend <= bot then
added_in_range = added_in_hunk
else
local added_above_bot = math.max(0, bot + 1 - (h.start + h.removed.count))
local added_above_top = math.max(0, top - (h.start + h.removed.count))
if h.start >= top and h.start <= bot then
added_in_range = added_above_bot
elseif h.vend >= top and h.vend <= bot then
added_in_range = added_in_hunk - added_above_top
pretop = pretop - added_above_top
elseif h.start <= top and h.vend >= bot then
added_in_range = added_above_bot - added_above_top
pretop = pretop - added_above_top
end
if top > h.vend then
pretop = pretop - added_in_hunk
end
end
precount = precount - added_in_range
end
if precount == 0 then
pretop = pretop - 1
end
return M.create_hunk(pretop, precount, top, bot - top + 1)
end
function M.patch_lines(hunk)
local lines = {}
for _, l in ipairs(hunk.removed.lines) do

View File

@ -32,7 +32,7 @@ local record M
-- Internal, API unstable
_update_highlights : function()
_update_cwd_head : function()
_run_func : function(range: {integer, integer}, func: string, ...: any)
_run_func : function(range: {integer, integer, integer}, func: string, ...: any)
_complete : function(arglead: string, line: string): {string}
_attach_enable : function()
_attach_disable : function()
@ -387,15 +387,15 @@ local function parse_args_to_lua(...: string): {any}
return args
end
M._run_func = function(range: {integer, integer}, func: string, ...: string)
M._run_func = function(range: {integer, integer, integer}, func: string, ...: string)
local actions = require('gitsigns.actions')
local actions0 = actions as {string:function}
local args = parse_args_to_lua(...)
if type(actions0[func]) == 'function' then
if range and range[1] ~= range[2] then
actions.user_range = range
if range and range[1] > 0 then
actions.user_range = {range[2], range[3]}
else
actions.user_range = nil
end
@ -439,7 +439,7 @@ local function setup_command()
'-nargs=+',
'-complete=customlist,v:lua.package.loaded.gitsigns._complete',
'Gitsigns',
'lua require("gitsigns")._run_func({<line1>, <line2>}, <f-args>)'
'lua require("gitsigns")._run_func({<range>, <line1>, <line2>}, <f-args>)'
}, ' '))
end

View File

@ -77,28 +77,8 @@ local function get_cursor_hunk(bufnr: integer, hunks: {Hunk}): Hunk, integer
return gs_hunks.find_hunk(lnum, hunks)
end
---Find all hunks in a given range for a given buffer.
---@param bufnr
---@param hunks
---@param range
local function get_range_hunks(hunks: {Hunk}, range: {integer, integer}): {Hunk}
local ret: {Hunk} = {}
for _, hunk in ipairs(hunks) do
if range[1] == 1 and hunk.start == 0 and hunk.vend == 0 then
return {hunk}
end
if (range[2] >= hunk.start and range[1] <= hunk.vend) then
ret[#ret+1] = hunk
end
end
return ret
end
M.stage_hunk = mk_repeatable(void(function(range: {integer, integer})
range = range or M.user_range
local valid_range = false
local bufnr = current_buf()
local bcache = cache[bufnr]
if not bcache then
@ -110,29 +90,33 @@ M.stage_hunk = mk_repeatable(void(function(range: {integer, integer})
return
end
local hunks = {}
local hunk: Hunk
if range and range[1] ~= range[2] then
valid_range = true
if range then
table.sort(range)
hunks = get_range_hunks(bcache.hunks, range)
local top, bot = range[1], range[2]
hunk = gs_hunks.create_partial_hunk(bcache.hunks, top, bot)
hunk.added.lines = api.nvim_buf_get_lines(bufnr, top-1, bot, false)
hunk.removed.lines = vim.list_slice(
bcache.compare_text,
hunk.removed.start,
hunk.removed.start + hunk.removed.count - 1
)
else
hunks[1] = get_cursor_hunk(bufnr, bcache.hunks)
hunk = get_cursor_hunk(bufnr, bcache.hunks)
end
if #hunks == 0 then
if not hunk then
return
end
bcache.git_obj:stage_hunks(hunks)
bcache.git_obj:stage_hunks({hunk})
for _, hunk in ipairs(hunks) do
table.insert(bcache.staged_diffs, hunk)
end
table.insert(bcache.staged_diffs, hunk)
bcache.compare_text = nil -- Invalidate
local hunk_signs = gs_hunks.process_hunks(hunks)
local hunk_signs = gs_hunks.process_hunks({hunk})
scheduler()
@ -152,34 +136,41 @@ end))
M.reset_hunk = mk_repeatable(function(range: {integer, integer})
range = range or M.user_range
local bufnr = current_buf()
local hunks = {}
if range and range[1] ~= range[2] then
table.sort(range)
hunks = get_range_hunks(cache[bufnr].hunks, range)
else
hunks[1] = get_cursor_hunk(bufnr)
end
if #hunks == 0 then
local bcache = cache[bufnr]
if not bcache then
return
end
local offset = 0
local hunk: Hunk
for _, hunk in ipairs(hunks) do
local lstart, lend: integer, integer
if hunk.type == 'delete' then
lstart = hunk.start
lend = hunk.start
else
lstart = hunk.start - 1
lend = hunk.start - 1 + hunk.added.count
end
local lines = hunk.removed.lines
api.nvim_buf_set_lines(bufnr, lstart + offset, lend + offset, false, lines)
offset = offset + (#lines - (lend - lstart))
if range then
table.sort(range)
local top, bot = range[1], range[2]
hunk = gs_hunks.create_partial_hunk(bcache.hunks, top, bot)
hunk.added.lines = api.nvim_buf_get_lines(bufnr, top-1, bot, false)
hunk.removed.lines = vim.list_slice(
bcache.compare_text,
hunk.removed.start,
hunk.removed.start + hunk.removed.count - 1
)
else
hunk = get_cursor_hunk(bufnr)
end
if not hunk then
return
end
local lstart, lend: integer, integer
if hunk.type == 'delete' then
lstart = hunk.start
lend = hunk.start
else
lstart = hunk.start - 1
lend = hunk.start - 1 + hunk.added.count
end
local lines = hunk.removed.lines
api.nvim_buf_set_lines(bufnr, lstart, lend, false, lines)
end)
M.reset_buffer = function()

View File

@ -29,10 +29,6 @@ function M.run_diff(fa: {string}, fb: {string}, diff_algo: string, indent_heuris
for _, r in ipairs(results) do
local rs, rc, as, ac = unpack(r)
local hunk = create_hunk(rs, rc, as, ac)
hunk.head = ('@@ -%d%s +%d%s @@'):format(
rs, rc > 0 and ','..rc or '',
as, ac > 0 and ','..ac or ''
)
if rc > 0 then
for i = rs, rs+rc-1 do
hunk.removed.lines[#hunk.removed.lines+1] = fa[i] or ''

View File

@ -43,7 +43,11 @@ function M.create_hunk(start_a: integer, count_a: integer, start_b: integer, cou
local hunk: Hunk = {
start = added.start,
removed = removed,
added = added
added = added,
head = ('@@ -%d%s +%d%s @@'):format(
start_a, count_a > 0 and ',' .. count_a or '',
start_b, count_b > 0 and ',' .. count_b or ''
)
}
if added.count == 0 then
@ -66,6 +70,47 @@ function M.create_hunk(start_a: integer, count_a: integer, start_b: integer, cou
return hunk
end
function M.create_partial_hunk(hunks: {Hunk}, top: integer, bot: integer): Hunk
local pretop, precount = top, bot - top + 1
for _, h in ipairs(hunks) do
local added_in_hunk = h.added.count - h.removed.count
local added_in_range = 0
if h.start >= top and h.vend <= bot then
-- Range contains hunk
added_in_range = added_in_hunk
else
local added_above_bot = math.max(0, bot + 1 - (h.start + h.removed.count))
local added_above_top = math.max(0, top - (h.start + h.removed.count))
if h.start >= top and h.start <= bot then
-- Range top intersects hunk
added_in_range = added_above_bot
elseif h.vend >= top and h.vend <= bot then
-- Range bottom intersects hunk
added_in_range = added_in_hunk - added_above_top
pretop = pretop - added_above_top
elseif h.start <= top and h.vend >= bot then
-- Range within hunk
added_in_range = added_above_bot - added_above_top
pretop = pretop - added_above_top
end
if top > h.vend then
pretop = pretop - added_in_hunk
end
end
precount = precount - added_in_range
end
if precount == 0 then
pretop = pretop - 1
end
return M.create_hunk(pretop, precount, top, bot - top + 1)
end
function M.patch_lines(hunk: Hunk): {string}
local lines: {string} = {}
for _, l in ipairs(hunk.removed.lines) do

239
test/actions_spec.lua Normal file
View File

@ -0,0 +1,239 @@
local helpers = require('test.gs_helpers')
local setup_gitsigns = helpers.setup_gitsigns
local feed = helpers.feed
local test_file = helpers.test_file
local edit = helpers.edit
local command = helpers.command
local check = helpers.check
local exec_lua = helpers.exec_lua
local fn = helpers.funcs
local system = fn.system
local test_config = helpers.test_config
local cleanup = helpers.cleanup
local clear = helpers.clear
local setup_test_repo = helpers.setup_test_repo
local eq = helpers.eq
local expectf = helpers.expectf
local it = helpers.it(it)
local function expect_hunks(exp_hunks)
expectf(function()
local hunks = exec_lua"return require('gitsigns').get_hunks()"
if #exp_hunks~= #hunks then
local msg = {}
msg[#msg+1] = ''
msg[#msg+1] = string.format(
'Number of hunks do not match. Expected: %d, passed in: %d',
#exp_hunks, #hunks)
msg[#msg+1] = ''
msg[#msg+1] = 'Expected hunks:'
for _, h in ipairs(exp_hunks) do
msg[#msg+1] = h.head
end
msg[#msg+1] = ''
msg[#msg+1] = 'Passed in hunks:'
for _, h in ipairs(hunks) do
msg[#msg+1] = h.head
end
error(table.concat(msg, '\n'))
end
for i, hunk in ipairs(hunks) do
eq(exp_hunks[i], hunk.head)
end
end)
end
describe('actions', function()
local config
before_each(function()
clear()
-- Make gitisigns available
exec_lua('package.path = ...', package.path)
config = helpers.deepcopy(test_config)
command('cd '..system{"dirname", os.tmpname()})
setup_gitsigns(config)
end)
after_each(function()
-- cleanup()
end)
it('works with commands', function()
setup_test_repo()
edit(test_file)
feed("jjjccEDIT<esc>")
check {
status = {head='master', added=0, changed=1, removed=0},
signs = {changed=1}
}
command 'Gitsigns stage_hunk'
check {
status = {head='master', added=0, changed=0, removed=0},
signs = {}
}
command 'Gitsigns undo_stage_hunk'
check {
status = {head='master', added=0, changed=1, removed=0},
signs = {changed=1}
}
-- Add multiple edits
feed('ggccThat<esc>')
check {
status = {head='master', added=0, changed=2, removed=0},
signs = {changed=2}
}
command 'Gitsigns stage_buffer'
check {
status = {head='master', added=0, changed=0, removed=0},
signs = {}
}
command 'Gitsigns reset_buffer_index'
check {
status = {head='master', added=0, changed=2, removed=0},
signs = {changed=2}
}
command 'Gitsigns reset_hunk'
check {
status = {head='master', added=0, changed=1, removed=0},
signs = {changed=1}
}
end)
describe('staging partial hunks', function()
before_each(function()
setup_test_repo{test_file_text={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'}}
edit(test_file)
end)
local function set_lines(start, dend, lines)
exec_lua([[
local start, dend, lines = ...
vim.api.nvim_buf_set_lines(0, start, dend, false, lines)
]], start, dend, lines)
-- command('write')
end
describe('can stage add hunks', function()
before_each(function()
set_lines(2, 2, {'c1', 'c2', 'c3', 'c4'})
expect_hunks{ '@@ -2 +3,4 @@' }
end)
it('contained in range', function()
command[[1,7 Gitsigns stage_hunk]]
expect_hunks{ }
end)
it('containing range', function()
command[[4,5 Gitsigns stage_hunk]]
expect_hunks{
'@@ -2 +3,1 @@',
'@@ -4 +6,1 @@'
}
end)
it('from top range', function()
command[[1,4 Gitsigns stage_hunk]]
expect_hunks{ '@@ -4 +5,2 @@' }
end)
it('from bottom range', function()
command[[4,7 Gitsigns stage_hunk]]
expect_hunks{ '@@ -2 +3,1 @@' }
command[[Gitsigns reset_buffer_index]]
expect_hunks{ '@@ -2 +3,4 @@' }
command[[4,10 Gitsigns stage_hunk]]
expect_hunks{ '@@ -2 +3,1 @@' }
end)
end)
describe('can stage modified-add hunks', function()
before_each(function()
set_lines(2, 4, {'c1', 'c2', 'c3', 'c4', 'c5'})
expect_hunks{ '@@ -3,2 +3,5 @@' }
end)
it('from top range containing mod', function()
command[[2,3 Gitsigns stage_hunk]]
expect_hunks{ '@@ -4,1 +4,4 @@' }
end)
it('from top range containing mod-add', function()
command[[2,5 Gitsigns stage_hunk]]
expect_hunks{ '@@ -5 +6,2 @@' }
end)
it('from bottom range containing add', function()
command[[6,8 Gitsigns stage_hunk]]
expect_hunks{ '@@ -3,2 +3,3 @@' }
end)
it('containing range containing add', function()
command'write'
command[[5,6 Gitsigns stage_hunk]]
expect_hunks{
'@@ -3,2 +3,2 @@',
'@@ -6 +7,1 @@'
}
end)
end)
describe('can stage modified-remove hunks', function()
before_each(function()
set_lines(2, 7, {'c1', 'c2', 'c3'})
command('write')
expect_hunks{ '@@ -3,5 +3,3 @@' }
end)
it('from top range', function()
expect_hunks{ '@@ -3,5 +3,3 @@' }
command[[2,3 Gitsigns stage_hunk]]
expect_hunks{ '@@ -4,4 +4,2 @@' }
command[[2,3 Gitsigns reset_buffer_index]]
expect_hunks{ '@@ -3,5 +3,3 @@' }
command[[2,4 Gitsigns stage_hunk]]
expect_hunks{ '@@ -5,3 +5,1 @@' }
end)
it('from bottom range', function()
expect_hunks{ '@@ -3,5 +3,3 @@' }
command[[4,6 Gitsigns stage_hunk]]
expect_hunks{ '@@ -3,1 +3,1 @@' }
command[[2,3 Gitsigns reset_buffer_index]]
expect_hunks{ '@@ -3,5 +3,3 @@' }
command[[5,6 Gitsigns stage_hunk]]
expect_hunks{ '@@ -3,2 +3,2 @@' }
end)
end)
it('can stage remove hunks', function()
set_lines(2, 5, {})
expect_hunks{ '@@ -3,3 +2 @@' }
command[[2 Gitsigns stage_hunk]]
expect_hunks{}
end)
end)
end)

View File

@ -74,7 +74,7 @@ describe('gitsigns', function()
it('gitdir watcher works on a fresh repo', function()
screen:try_resize(20,6)
setup_test_repo(true)
setup_test_repo{no_add=true}
config.watch_gitdir = {interval = 5}
setup_gitsigns(config)
edit(test_file)
@ -248,7 +248,7 @@ describe('gitsigns', function()
describe('current line blame', function()
it('doesn\'t error on untracked files', function()
setup_test_repo(true)
setup_test_repo{no_add=true}
config.current_line_blame = true
setup_gitsigns(config)
edit(newfile)
@ -268,7 +268,7 @@ describe('gitsigns', function()
describe('on_attach()', function()
it('can prevent attaching to a buffer', function()
setup_test_repo(true)
setup_test_repo{no_add=true}
-- Functions can't be serialized over rpc so need to setup config
-- remotely
@ -351,71 +351,6 @@ describe('gitsigns', function()
end)
it('perform actions', function()
setup_gitsigns(config)
edit(test_file)
command("set signcolumn=yes")
feed("jjj")
feed("cc")
feed("EDIT<esc>")
check {
status = {head='master', added=0, changed=1, removed=0},
signs = {changed=1}
}
-- Stage
feed("mhs")
check {
status = {head='master', added=0, changed=0, removed=0},
signs = {}
}
-- Undo stage
feed("mhu")
check {
status = {head='master', added=0, changed=1, removed=0},
signs = {changed=1}
}
-- Add multiple edits
feed('gg')
feed('cc')
feed('That<esc>')
check {
status = {head='master', added=0, changed=2, removed=0},
signs = {changed=2}
}
-- Stage buffer
feed("mhS")
check {
status = {head='master', added=0, changed=0, removed=0},
signs = {}
}
-- Unstage buffer
feed("mhU")
check {
status = {head='master', added=0, changed=2, removed=0},
signs = {changed=2}
}
-- Reset
feed("mhr")
check {
status = {head='master', added=0, changed=1, removed=0},
signs = {changed=1}
}
end)
it('can enable numhl', function()
config.numhl = true
setup_gitsigns(config)

View File

@ -76,13 +76,14 @@ function M.setup_git()
M.git{'config', 'init.defaultBranch', 'master'}
end
function M.setup_test_repo(no_add)
function M.setup_test_repo(opts)
local text = opts and opts.test_file_text or test_file_text
M.cleanup()
system{"mkdir", M.scratch}
M.setup_git()
system{"touch", M.test_file}
M.write_to_file(M.test_file, test_file_text)
if not no_add then
M.write_to_file(M.test_file, text)
if not (opts and opts.no_add) then
M.git{"add", M.test_file}
M.git{"commit", "-m", "init commit"}
end

View File

@ -363,6 +363,7 @@ global record vim
in_fast_event: function(): boolean
list_extend: function({any}, {any}, integer, integer)
list_slice: function<T>({T}, integer, integer): {T}
record log
record levels
WARN: integer