feat(nav_hunk): respect 'foldopen' when jumping

This commit is contained in:
Lewis Russell 2021-09-14 12:31:56 +01:00
parent cef4e6f26c
commit 7ce5ccc216
4 changed files with 84 additions and 63 deletions

View File

@ -102,8 +102,7 @@ setup({config}) *gitsigns.setup()*
Gitsigns. See |gitsigns-usage| for more details.
next_hunk({opts}) *gitsigns.next_hunk()*
Jump to the next hunk in the current buffer. Respects
|wrapscan|.
Jump to the next hunk in the current buffer.
Parameters: ~
{opts} table|nil Configuration table. Keys:
@ -113,17 +112,16 @@ next_hunk({opts}) *gitsigns.next_hunk(
• {navigation_message}: (boolean)
Whether to show navigation messages or not.
Looks at 'shortmess' for default behaviour.
• {foldopen}: (boolean)
Expand folds when navigating to a hunk which is
inside a fold. Defaults to `true` if 'foldopen'
contains `search`.
prev_hunk({opts}) *gitsigns.prev_hunk()*
Jump to the previous hunk in the current buffer. Respects
|wrapscan|.
Jump to the previous hunk in the current buffer.
Parameters: ~
{opts} table|nil Configuration table. Keys:
• {wrap}: (boolean)
Whether to loop around file or not. Defaults
to the value 'wrapscan'
See |gitsigns.next_hunk()|.
stage_hunk({range}) *gitsigns.stage_hunk()*
Stage the hunk at the cursor position, or all hunks in the

View File

@ -27,6 +27,7 @@ local NavHunkOpts = {}
local M = {}
@ -274,70 +275,78 @@ M.reset_buffer_index = void(function()
void(manager.update)(bufnr)
end)
local function nav_hunk(options)
local function process_nav_opts(opts)
if opts.navigation_message == nil then
opts.navigation_message = not vim.opt.shortmess:get().S
end
if opts.wrap == nil then
opts.wrap = vim.opt.wrapscan:get()
end
if opts.foldopen == nil then
opts.foldopen = vim.tbl_contains(vim.opt.foldopen:get(), 'search')
end
end
local function nav_hunk(opts)
process_nav_opts(opts)
local bcache = cache[current_buf()]
if not bcache then
return
end
local show_navigation_msg = not string.find(vim.o.shortmess, 'S')
if options.navigation_message ~= nil then
show_navigation_msg = options.navigation_message
end
local hunks = bcache.hunks
if not hunks or vim.tbl_isempty(hunks) then
if show_navigation_msg then
if opts.navigation_message then
vim.api.nvim_echo({ { 'No hunks', 'WarningMsg' } }, false, {})
end
return
end
local line = api.nvim_win_get_cursor(0)[1]
local wrap = vim.o.wrapscan
if options.wrap ~= nil then
wrap = options.wrap
end
local hunk, index = gs_hunks.find_nearest_hunk(line, hunks, options.forwards, wrap)
local hunk, index = gs_hunks.find_nearest_hunk(line, hunks, opts.forwards, opts.wrap)
if hunk == nil then
if show_navigation_msg then
if opts.navigation_message then
vim.api.nvim_echo({ { 'No more hunks', 'WarningMsg' } }, false, {})
end
return
end
local row = options.forwards and hunk.start or hunk.vend
local row = opts.forwards and hunk.start or hunk.vend
if row then
if row == 0 then
row = 1
end
api.nvim_win_set_cursor(0, { row, 0 })
if opts.foldopen then
vim.cmd('foldopen!')
end
if pcall(api.nvim_buf_get_var, 0, '_gitsigns_preview_open') then
vim.schedule(M.preview_hunk)
end
if index ~= nil and show_navigation_msg then
if index ~= nil and opts.navigation_message then
vim.api.nvim_echo({ { string.format('Hunk %d of %d', index, #hunks), 'None' } }, false, {})
end
end
end
M.next_hunk = function(options)
options = options or {}
options.forwards = true
nav_hunk(options)
M.next_hunk = function(opts)
opts = opts or {}
opts.forwards = true
nav_hunk(opts)
end
M.prev_hunk = function(options)
options = options or {}
options.forwards = false
nav_hunk(options)
M.prev_hunk = function(opts)
opts = opts or {}
opts.forwards = false
nav_hunk(opts)
end
local function highlight_hunk_lines(bufnr, offset, hunk_lines)

View File

@ -25,6 +25,7 @@ local record NavHunkOpts
forwards: boolean
wrap: boolean
navigation_message: boolean
foldopen: boolean
end
local record M
@ -274,70 +275,78 @@ M.reset_buffer_index = void(function()
void(manager.update)(bufnr)
end)
local function nav_hunk(options: NavHunkOpts)
local function process_nav_opts(opts: NavHunkOpts)
-- show navigation message
if opts.navigation_message == nil then
opts.navigation_message = not vim.opt.shortmess:get().S
end
-- wrap around
if opts.wrap == nil then
opts.wrap = vim.opt.wrapscan:get()
end
if opts.foldopen == nil then
opts.foldopen = vim.tbl_contains(vim.opt.foldopen:get(), 'search')
end
end
local function nav_hunk(opts: NavHunkOpts)
process_nav_opts(opts)
local bcache = cache[current_buf()]
if not bcache then
return
end
-- show navigation message
local show_navigation_msg = not string.find(vim.o.shortmess, 'S')
if options.navigation_message ~= nil then
show_navigation_msg = options.navigation_message
end
local hunks = bcache.hunks
if not hunks or vim.tbl_isempty(hunks) then
if show_navigation_msg then
if opts.navigation_message then
vim.api.nvim_echo({{'No hunks', 'WarningMsg'}}, false, {})
end
return
end
local line = api.nvim_win_get_cursor(0)[1]
-- wrap around
local wrap = vim.o.wrapscan
if options.wrap ~= nil then
wrap = options.wrap
end
local hunk, index = gs_hunks.find_nearest_hunk(line, hunks, options.forwards, wrap)
local hunk, index = gs_hunks.find_nearest_hunk(line, hunks, opts.forwards, opts.wrap)
if hunk == nil then
if show_navigation_msg then
if opts.navigation_message then
vim.api.nvim_echo({{'No more hunks', 'WarningMsg'}}, false, {})
end
return
end
local row = options.forwards and hunk.start or hunk.vend
local row = opts.forwards and hunk.start or hunk.vend
if row then
-- Handle topdelete
if row == 0 then
row = 1
end
api.nvim_win_set_cursor(0, {row, 0})
if opts.foldopen then
vim.cmd('foldopen!')
end
if pcall(api.nvim_buf_get_var, 0, '_gitsigns_preview_open') then
vim.schedule(M.preview_hunk)
end
if index ~= nil and show_navigation_msg then
if index ~= nil and opts.navigation_message then
vim.api.nvim_echo({{string.format('Hunk %d of %d', index, #hunks), 'None'}}, false, {})
end
end
end
M.next_hunk = function(options: NavHunkOpts)
options = options or {}
options.forwards = true
nav_hunk(options)
M.next_hunk = function(opts: NavHunkOpts)
opts = opts or {}
opts.forwards = true
nav_hunk(opts)
end
M.prev_hunk = function(options: NavHunkOpts)
options = options or {}
options.forwards = false
nav_hunk(options)
M.prev_hunk = function(opts: NavHunkOpts)
opts = opts or {}
opts.forwards = false
nav_hunk(opts)
end
local function highlight_hunk_lines(bufnr: integer, offset: integer, hunk_lines: {string})

View File

@ -247,9 +247,14 @@ global record vim
end
record opt
record diffopt
get: function(diffopt): {string}
record Opt<T>
get: function<T>(Opt<T>): T
end
diffopt: Opt<{string}>
foldopen: Opt<{string}>
shortmess: Opt<{string:boolean}>
wrapscan: Opt<boolean>
end
record lsp