feat: cleanup ci tests
This commit is contained in:
parent
0c76e5efcb
commit
1dd62373b6
3 changed files with 172 additions and 36 deletions
|
|
@ -140,6 +140,47 @@ local function highlight_treesitter(bufnr, ns, hunk, code_lines)
|
||||||
return extmark_count
|
return extmark_count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@alias fugitive-ts.SyntaxQueryFn fun(line: integer, col: integer): integer, string
|
||||||
|
|
||||||
|
---@param query_fn fugitive-ts.SyntaxQueryFn
|
||||||
|
---@param code_lines string[]
|
||||||
|
---@return {line: integer, col_start: integer, col_end: integer, hl_name: string}[]
|
||||||
|
function M.coalesce_syntax_spans(query_fn, code_lines)
|
||||||
|
local spans = {}
|
||||||
|
for i, line in ipairs(code_lines) do
|
||||||
|
local col = 1
|
||||||
|
local line_len = #line
|
||||||
|
|
||||||
|
while col <= line_len do
|
||||||
|
local syn_id, hl_name = query_fn(i, col)
|
||||||
|
if syn_id == 0 then
|
||||||
|
col = col + 1
|
||||||
|
else
|
||||||
|
local span_start = col
|
||||||
|
|
||||||
|
col = col + 1
|
||||||
|
while col <= line_len do
|
||||||
|
local next_id, next_name = query_fn(i, col)
|
||||||
|
if next_id == 0 or next_name ~= hl_name then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
col = col + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if hl_name ~= '' then
|
||||||
|
table.insert(spans, {
|
||||||
|
line = i,
|
||||||
|
col_start = span_start,
|
||||||
|
col_end = col,
|
||||||
|
hl_name = hl_name,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return spans
|
||||||
|
end
|
||||||
|
|
||||||
---@param bufnr integer
|
---@param bufnr integer
|
||||||
---@param ns integer
|
---@param ns integer
|
||||||
---@param hunk fugitive-ts.Hunk
|
---@param hunk fugitive-ts.Hunk
|
||||||
|
|
@ -159,53 +200,39 @@ local function highlight_vim_syntax(bufnr, ns, hunk, code_lines)
|
||||||
vim.api.nvim_buf_set_lines(scratch, 0, -1, false, code_lines)
|
vim.api.nvim_buf_set_lines(scratch, 0, -1, false, code_lines)
|
||||||
vim.api.nvim_set_option_value('bufhidden', 'wipe', { buf = scratch })
|
vim.api.nvim_set_option_value('bufhidden', 'wipe', { buf = scratch })
|
||||||
|
|
||||||
local extmark_count = 0
|
local spans = {}
|
||||||
|
|
||||||
vim.api.nvim_buf_call(scratch, function()
|
vim.api.nvim_buf_call(scratch, function()
|
||||||
vim.cmd('setlocal syntax=' .. ft)
|
vim.cmd('setlocal syntax=' .. ft)
|
||||||
vim.cmd('redraw')
|
vim.cmd('redraw')
|
||||||
|
|
||||||
for i, line in ipairs(code_lines) do
|
---@param line integer
|
||||||
local col = 1
|
---@param col integer
|
||||||
local line_len = #line
|
---@return integer, string
|
||||||
|
local function query_fn(line, col)
|
||||||
while col <= line_len do
|
local syn_id = vim.fn.synID(line, col, 1)
|
||||||
local syn_id = vim.fn.synID(i, col, 1)
|
if syn_id == 0 then
|
||||||
if syn_id == 0 then
|
return 0, ''
|
||||||
col = col + 1
|
|
||||||
else
|
|
||||||
local hl_name = vim.fn.synIDattr(vim.fn.synIDtrans(syn_id), 'name')
|
|
||||||
local span_start = col
|
|
||||||
|
|
||||||
col = col + 1
|
|
||||||
while col <= line_len do
|
|
||||||
local next_id = vim.fn.synID(i, col, 1)
|
|
||||||
if next_id == 0 then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
local next_name = vim.fn.synIDattr(vim.fn.synIDtrans(next_id), 'name')
|
|
||||||
if next_name ~= hl_name then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
col = col + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if hl_name ~= '' then
|
|
||||||
local buf_line = hunk.start_line + i - 1
|
|
||||||
pcall(vim.api.nvim_buf_set_extmark, bufnr, ns, buf_line, span_start, {
|
|
||||||
end_col = col,
|
|
||||||
hl_group = hl_name,
|
|
||||||
priority = 200,
|
|
||||||
})
|
|
||||||
extmark_count = extmark_count + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
return syn_id, vim.fn.synIDattr(vim.fn.synIDtrans(syn_id), 'name')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
spans = M.coalesce_syntax_spans(query_fn, code_lines)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
vim.api.nvim_buf_delete(scratch, { force = true })
|
vim.api.nvim_buf_delete(scratch, { force = true })
|
||||||
|
|
||||||
|
local extmark_count = 0
|
||||||
|
for _, span in ipairs(spans) do
|
||||||
|
local buf_line = hunk.start_line + span.line - 1
|
||||||
|
pcall(vim.api.nvim_buf_set_extmark, bufnr, ns, buf_line, span.col_start, {
|
||||||
|
end_col = span.col_end,
|
||||||
|
hl_group = span.hl_name,
|
||||||
|
priority = 200,
|
||||||
|
})
|
||||||
|
extmark_count = extmark_count + 1
|
||||||
|
end
|
||||||
|
|
||||||
return extmark_count
|
return extmark_count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -533,6 +533,19 @@ describe('highlight', function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('applies vim syntax extmarks when vim.enabled and no TS parser', function()
|
it('applies vim syntax extmarks when vim.enabled and no TS parser', function()
|
||||||
|
local orig_synID = vim.fn.synID
|
||||||
|
local orig_synIDtrans = vim.fn.synIDtrans
|
||||||
|
local orig_synIDattr = vim.fn.synIDattr
|
||||||
|
vim.fn.synID = function(_line, _col, _trans)
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
vim.fn.synIDtrans = function(id)
|
||||||
|
return id
|
||||||
|
end
|
||||||
|
vim.fn.synIDattr = function(_id, _what)
|
||||||
|
return 'Identifier'
|
||||||
|
end
|
||||||
|
|
||||||
local bufnr = create_buffer({
|
local bufnr = create_buffer({
|
||||||
'@@ -1,1 +1,2 @@',
|
'@@ -1,1 +1,2 @@',
|
||||||
' local x = 1',
|
' local x = 1',
|
||||||
|
|
@ -549,6 +562,10 @@ describe('highlight', function()
|
||||||
|
|
||||||
highlight.highlight_hunk(bufnr, ns, hunk, default_opts({ vim = { enabled = true } }))
|
highlight.highlight_hunk(bufnr, ns, hunk, default_opts({ vim = { enabled = true } }))
|
||||||
|
|
||||||
|
vim.fn.synID = orig_synID
|
||||||
|
vim.fn.synIDtrans = orig_synIDtrans
|
||||||
|
vim.fn.synIDattr = orig_synIDattr
|
||||||
|
|
||||||
local extmarks = get_extmarks(bufnr)
|
local extmarks = get_extmarks(bufnr)
|
||||||
local has_syntax_hl = false
|
local has_syntax_hl = false
|
||||||
for _, mark in ipairs(extmarks) do
|
for _, mark in ipairs(extmarks) do
|
||||||
|
|
@ -654,6 +671,19 @@ describe('highlight', function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('applies Normal blanking for vim fallback hunks', function()
|
it('applies Normal blanking for vim fallback hunks', function()
|
||||||
|
local orig_synID = vim.fn.synID
|
||||||
|
local orig_synIDtrans = vim.fn.synIDtrans
|
||||||
|
local orig_synIDattr = vim.fn.synIDattr
|
||||||
|
vim.fn.synID = function(_line, _col, _trans)
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
vim.fn.synIDtrans = function(id)
|
||||||
|
return id
|
||||||
|
end
|
||||||
|
vim.fn.synIDattr = function(_id, _what)
|
||||||
|
return 'Identifier'
|
||||||
|
end
|
||||||
|
|
||||||
local bufnr = create_buffer({
|
local bufnr = create_buffer({
|
||||||
'@@ -1,1 +1,2 @@',
|
'@@ -1,1 +1,2 @@',
|
||||||
' local x = 1',
|
' local x = 1',
|
||||||
|
|
@ -670,6 +700,10 @@ describe('highlight', function()
|
||||||
|
|
||||||
highlight.highlight_hunk(bufnr, ns, hunk, default_opts({ vim = { enabled = true } }))
|
highlight.highlight_hunk(bufnr, ns, hunk, default_opts({ vim = { enabled = true } }))
|
||||||
|
|
||||||
|
vim.fn.synID = orig_synID
|
||||||
|
vim.fn.synIDtrans = orig_synIDtrans
|
||||||
|
vim.fn.synIDattr = orig_synIDattr
|
||||||
|
|
||||||
local extmarks = get_extmarks(bufnr)
|
local extmarks = get_extmarks(bufnr)
|
||||||
local has_normal = false
|
local has_normal = false
|
||||||
for _, mark in ipairs(extmarks) do
|
for _, mark in ipairs(extmarks) do
|
||||||
|
|
@ -682,4 +716,57 @@ describe('highlight', function()
|
||||||
delete_buffer(bufnr)
|
delete_buffer(bufnr)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe('coalesce_syntax_spans', function()
|
||||||
|
it('coalesces adjacent chars with same hl group', function()
|
||||||
|
local function query_fn(_line, _col)
|
||||||
|
return 1, 'Keyword'
|
||||||
|
end
|
||||||
|
local spans = highlight.coalesce_syntax_spans(query_fn, { 'hello' })
|
||||||
|
assert.are.equal(1, #spans)
|
||||||
|
assert.are.equal(1, spans[1].col_start)
|
||||||
|
assert.are.equal(6, spans[1].col_end)
|
||||||
|
assert.are.equal('Keyword', spans[1].hl_name)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('splits spans at hl group boundaries', function()
|
||||||
|
local function query_fn(_line, col)
|
||||||
|
if col <= 3 then
|
||||||
|
return 1, 'Keyword'
|
||||||
|
end
|
||||||
|
return 2, 'String'
|
||||||
|
end
|
||||||
|
local spans = highlight.coalesce_syntax_spans(query_fn, { 'abcdef' })
|
||||||
|
assert.are.equal(2, #spans)
|
||||||
|
assert.are.equal('Keyword', spans[1].hl_name)
|
||||||
|
assert.are.equal(1, spans[1].col_start)
|
||||||
|
assert.are.equal(4, spans[1].col_end)
|
||||||
|
assert.are.equal('String', spans[2].hl_name)
|
||||||
|
assert.are.equal(4, spans[2].col_start)
|
||||||
|
assert.are.equal(7, spans[2].col_end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('skips syn_id 0 gaps', function()
|
||||||
|
local function query_fn(_line, col)
|
||||||
|
if col == 2 or col == 3 then
|
||||||
|
return 0, ''
|
||||||
|
end
|
||||||
|
return 1, 'Identifier'
|
||||||
|
end
|
||||||
|
local spans = highlight.coalesce_syntax_spans(query_fn, { 'abcd' })
|
||||||
|
assert.are.equal(2, #spans)
|
||||||
|
assert.are.equal(1, spans[1].col_start)
|
||||||
|
assert.are.equal(2, spans[1].col_end)
|
||||||
|
assert.are.equal(4, spans[2].col_start)
|
||||||
|
assert.are.equal(5, spans[2].col_end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('skips empty hl_name spans', function()
|
||||||
|
local function query_fn(_line, _col)
|
||||||
|
return 1, ''
|
||||||
|
end
|
||||||
|
local spans = highlight.coalesce_syntax_spans(query_fn, { 'abc' })
|
||||||
|
assert.are.equal(0, #spans)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,25 @@ describe('parser', function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('detects hunks across multiple files', function()
|
it('detects hunks across multiple files', function()
|
||||||
|
local orig_get_lang = vim.treesitter.language.get_lang
|
||||||
|
local orig_inspect = vim.treesitter.language.inspect
|
||||||
|
vim.treesitter.language.get_lang = function(ft)
|
||||||
|
local result = orig_get_lang(ft)
|
||||||
|
if result then
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
if ft == 'python' then
|
||||||
|
return 'python'
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
vim.treesitter.language.inspect = function(lang)
|
||||||
|
if lang == 'python' then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
return orig_inspect(lang)
|
||||||
|
end
|
||||||
|
|
||||||
local bufnr = create_buffer({
|
local bufnr = create_buffer({
|
||||||
'M lua/foo.lua',
|
'M lua/foo.lua',
|
||||||
'@@ -1,1 +1,2 @@',
|
'@@ -1,1 +1,2 @@',
|
||||||
|
|
@ -88,6 +107,9 @@ describe('parser', function()
|
||||||
})
|
})
|
||||||
local hunks = parser.parse_buffer(bufnr)
|
local hunks = parser.parse_buffer(bufnr)
|
||||||
|
|
||||||
|
vim.treesitter.language.get_lang = orig_get_lang
|
||||||
|
vim.treesitter.language.inspect = orig_inspect
|
||||||
|
|
||||||
assert.are.equal(2, #hunks)
|
assert.are.equal(2, #hunks)
|
||||||
assert.are.equal('lua/foo.lua', hunks[1].filename)
|
assert.are.equal('lua/foo.lua', hunks[1].filename)
|
||||||
assert.are.equal('lua', hunks[1].lang)
|
assert.are.equal('lua', hunks[1].lang)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue