Skip to content

Commit b1dfd15

Browse files
TheLeoPechasnovski
andcommitted
fix(surround): make tree-sitter surrounding work with col=0 TS ranges
Resolve #2013 Co-authored-by: Evgeni Chasnovski <[email protected]>
1 parent cc706eb commit b1dfd15

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

lua/mini/surround.lua

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,11 +1039,20 @@ MiniSurround.gen_spec.input.treesitter = function(captures, opts)
10391039
-- `row1-col1-byte1-row2-col2-byte2` (i.e. "range six") format.
10401040
local ts_range_to_region = function(r)
10411041
-- The `master` branch of 'nvim-treesitter' can return "range four" format
1042-
-- if it uses custom directives, like `#make-range!`. Due ot the fact that
1042+
-- if it uses custom directives, like `#make-range!`. Due to the fact that
10431043
-- it doesn't fully mock the `TSNode:range()` method to return "range six".
10441044
-- TODO: Remove after 'nvim-treesitter' `master` branch support is dropped.
10451045
local offset = #r == 4 and -1 or 0
1046-
return { from = { line = r[1] + 1, col = r[2] + 1 }, to = { line = r[4 + offset] + 1, col = r[5 + offset] } }
1046+
local res = { from = { line = r[1] + 1, col = r[2] + 1 }, to = { line = r[4 + offset] + 1, col = r[5 + offset] } }
1047+
1048+
-- NOTE: Adjust "row-exclusive, col-0" range that means "all previous row
1049+
-- including the newline character"
1050+
if res.to.col == 0 then
1051+
res.to.line = res.to.line - 1
1052+
res.to.col = vim.fn.col({ res.to.line, '$' })
1053+
end
1054+
1055+
return res
10471056
end
10481057

10491058
return function()

tests/test_surround.lua

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,19 @@ T['gen_spec']['input']['treesitter()']['works with quantified captures'] = funct
397397
validate(21, 'function M.a(u, vv<www>)')
398398
end
399399

400+
T['gen_spec']['input']['treesitter()']['works with row-exclusive, col-0 end range'] = function()
401+
if child.fn.has('nvim-0.10') == 0 then
402+
MiniTest.skip('`Query:iter_matches()` returning several nodes requires Neovim>=0.10')
403+
end
404+
405+
child.lua([[MiniSurround.config.custom_surroundings = {
406+
c = { input = MiniSurround.gen_spec.input.treesitter({ outer = '@chunk.outer', inner = '@chunk.inner' }) }
407+
}]])
408+
409+
local lines = get_lines()
410+
validate_find(lines, { 4, 0 }, { { 11, 2 }, { 13, 7 }, { 1, 0 }, { 2, 0 } }, type_keys, 'sf', 'c')
411+
end
412+
400413
T['gen_spec']['input']['treesitter()']['respects plugin options'] = function()
401414
local lines = get_lines()
402415

0 commit comments

Comments
 (0)