Skip to content

Commit

Permalink
feat(preview): improved version of preview_hunk_inline()
Browse files Browse the repository at this point in the history
(experimental)

Uses a second buffer and a floating window in order to display syntax
highlighting in the deleted lines.

Need to set `_inline2 = true` in `setup()` to enable.
  • Loading branch information
lewis6991 committed Apr 28, 2023
1 parent 5d84067 commit 97e044b
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 3 deletions.
5 changes: 5 additions & 0 deletions doc/gitsigns.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,11 @@ GitSignsDeleteVirtLnInLine
Used for word diff regions in lines shown by inline `preview_hunk_inline()` or `show_deleted()`.

Fallbacks: `GitSignsDeleteLnInline`
*hl-GitSignsVirtLnum*
GitSignsVirtLnum
Used for line numbers in inline hunks previews.

Fallbacks: `GitSignsDeleteVirtLn`

==============================================================================
COMMAND *gitsigns-command*
Expand Down
10 changes: 9 additions & 1 deletion lua/gitsigns/actions.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions lua/gitsigns/config.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions lua/gitsigns/current_line_blame.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions lua/gitsigns/highlight.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

96 changes: 96 additions & 0 deletions lua/gitsigns/manager.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion teal/gitsigns/actions.tl
Original file line number Diff line number Diff line change
Expand Up @@ -763,13 +763,21 @@ M.preview_hunk_inline = function()

clear_preview_inline(bufnr)

local winid: integer
manager.show_added(bufnr, ns_inline, hunk)
manager.show_deleted(bufnr, ns_inline, hunk)
if config._inline2 then
winid = manager.show_deleted_in_float(bufnr, ns_inline, hunk)
else
manager.show_deleted(bufnr, ns_inline, hunk)
end

api.nvim_create_autocmd({ 'CursorMoved', 'InsertEnter' }, {
buffer = bufnr,
desc = 'Clear gitsigns inline preview',
callback = function()
if winid then
pcall(api.nvim_win_close, winid, true)
end
clear_preview_inline(bufnr)
end,
once = true
Expand Down
9 changes: 9 additions & 0 deletions teal/gitsigns/config.tl
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ local record M
_refresh_staged_on_update: boolean
_blame_cache: boolean
_threaded_diff: boolean
_inline2: boolean
_extmark_signs: boolean

_git_version: string
Expand Down Expand Up @@ -767,6 +768,14 @@ M.schema = {
]]
},

_inline2 = {
type = 'boolean',
default = false,
description = [[
Enable enhanced version of preview_hunk_inline()
]]
},

_extmark_signs = {
type = 'boolean',
default = false,
Expand Down
4 changes: 4 additions & 0 deletions teal/gitsigns/highlight.tl
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ M.hls = {
desc = "Used for word diff regions in lines shown by inline `preview_hunk_inline()` or `show_deleted()`."
}},

{GitSignsVirtLnum = {'GitSignsDeleteVirtLn',
desc = 'Used for line numbers in inline hunks previews.'
}},

}

local function is_hl_set(hl_name: string): boolean
Expand Down
96 changes: 96 additions & 0 deletions teal/gitsigns/manager.tl
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,102 @@ function M.show_deleted(bufnr: integer, nsd: integer, hunk: Hunk)
})
end

function M.show_deleted_in_float(bufnr: integer, nsd: integer, hunk: Hunk): integer
local virt_lines = {}
for i = 1, hunk.removed.count do
virt_lines[i] = { { '', 'Normal' } }
end

local topdelete = hunk.added.start == 0 and hunk.type == 'delete'
local virt_lines_above = hunk.type ~= 'delete' or topdelete

local row = topdelete and 0 or hunk.added.start - 1
api.nvim_buf_set_extmark(bufnr, nsd, row, -1, {
virt_lines = virt_lines,
-- TODO(lewis6991): Note virt_lines_above doesn't work on row 0 neovim/neovim#16166
virt_lines_above = virt_lines_above
})

local cwin = api.nvim_get_current_win()
local bcache = cache[bufnr]
local pbufnr = api.nvim_create_buf(false, true)
local width = api.nvim_win_get_width(0)
api.nvim_buf_set_lines(pbufnr, 0, -1, false, bcache.compare_text)

local opts: vim.api.WinConfig = {
relative = 'win',
win = cwin,
width = width,
height = hunk.removed.count
}

if topdelete then
opts.row, opts.col = 0, 0
else
local bufpos_offset = virt_lines_above and 2 or 1
opts.bufpos = { hunk.added.start - bufpos_offset, 0 }
end

local winid = api.nvim_open_win(pbufnr, false, opts)

-- Align buffer text by accounting for differences in the statuscolumn
local textoff = vim.fn.getwininfo(api.nvim_get_current_win())[1].textoff
local ptextoff = vim.fn.getwininfo(winid)[1].textoff
local col_offset = textoff - ptextoff

if col_offset ~= 0 then
opts.width = opts.width - col_offset
if topdelete then
opts.col = col_offset
else
opts.bufpos[2] = col_offset
end
api.nvim_win_set_config(winid, opts)
end

vim.bo[pbufnr].filetype = vim.bo[bufnr].filetype
vim.bo[pbufnr].bufhidden = 'wipe'
vim.wo[winid].scrolloff = 0
vim.wo[winid].relativenumber = false

api.nvim_win_call(winid, function(): nil
-- Expand folds
vim.cmd('normal '..'zR')

-- Navigate to hunk
vim.cmd('normal '..tostring(hunk.removed.start)..'gg')
vim.cmd('normal '..vim.api.nvim_replace_termcodes('z<CR>', true, false, true))
end)

-- Apply highlights

for i = hunk.removed.start, hunk.removed.start + hunk.removed.count do
api.nvim_buf_set_extmark(pbufnr, nsd, i - 1, 0, {
hl_group = 'GitSignsDeleteVirtLn',
hl_eol = true,
end_row = i,
priority = 1000
})
end

local removed_regions =
require('gitsigns.diff_int').run_word_diff(hunk.removed.lines, hunk.added.lines)

for _, region in ipairs(removed_regions) do
local start_row = (hunk.removed.start - 1) + (region[1] - 1)
local start_col = region[3] - 1
local end_col = region[4] - 1
api.nvim_buf_set_extmark(pbufnr, nsd, start_row, start_col, {
hl_group = 'GitSignsDeleteVirtLnInline',
end_col = end_col,
end_row = start_row,
priority = 1001
})
end

return winid
end

function M.show_added(bufnr: integer, nsw: integer, hunk: Hunk)
local start_row = hunk.added.start - 1

Expand Down
2 changes: 2 additions & 0 deletions types/vim.d.tl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ local record M
{WinOption}
diff: boolean
signcolumn: string
scrolloff: integer
relativenumber: boolean
end

wo: WinOption
Expand Down
15 changes: 14 additions & 1 deletion types/vim/api.d.tl
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,20 @@ local record M
nvim_win_get_width: function(integer): integer
nvim_win_is_valid: function(number): boolean
nvim_win_set_buf: function(number, number)
nvim_win_set_config: function(number, {string:any})

record WinConfig
bufpos: {integer, integer}
virt_lines_above: boolean
width: integer
height: integer
relative: string
row: integer
col: integer
win: integer
end

nvim_win_set_config: function(number, WinConfig)

nvim_win_set_cursor: function(number, {number})
nvim_win_set_height: function(number, number)
nvim_win_set_option: function(number, string, any)
Expand Down
5 changes: 5 additions & 0 deletions types/vim/fn.d.tl
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ local record M

FugitiveReal: function(...: any): string
FugitiveParse: function(...: any): {string, string}

record WinInfo
textoff: integer
end
getwininfo: function(integer): {WinInfo}
end

return M

0 comments on commit 97e044b

Please sign in to comment.