(Range.from_cmd_args) more correct handling
All checks were successful
NeoVim tests / code-quality (push) Successful in 1m22s

This commit is contained in:
Jonathan Apodaca 2025-06-16 20:43:41 -06:00
parent 933c187148
commit 28714fb51b
3 changed files with 92 additions and 17 deletions

View File

@ -249,19 +249,22 @@ end
--- @param args unknown --- @param args unknown
--- @return u.Range|nil --- @return u.Range|nil
function Range.from_cmd_args(args) function Range.from_cmd_args(args)
--- @type 'v'|'V' if args.range == 0 then return nil end
local mode
--- @type nil|u.Pos local bufnr = vim.api.nvim_get_current_buf()
local start if args.range == 1 then
local stop return Range.new(Pos.new(bufnr, args.line1, 1), Pos.new(bufnr, args.line1, Pos.MAX_COL), 'V')
if args.range == 0 then end
return nil
else local is_visual = vim.fn.histget('cmd', -1):sub(1, 5) == [['<,'>]]
start = Pos.from_pos "'<" --- @type 'v'|'V'
stop = Pos.from_pos "'>" local mode = is_visual and vim.fn.visualmode() or 'V'
mode = stop:is_col_max() and 'V' or 'v'
if is_visual then
return Range.new(Pos.from_pos "'<", Pos.from_pos "'>", mode)
else
return Range.new(Pos.new(bufnr, args.line1, 1), Pos.new(bufnr, args.line2, Pos.MAX_COL), mode)
end end
return Range.new(start, stop, mode)
end end
function Range.find_nearest_brackets() function Range.find_nearest_brackets()

View File

@ -526,7 +526,8 @@ function TreeBuilder:nest(fn)
return self return self
end end
--- @param arr <T>[] --- @generic T
--- @param arr T[]
--- @param f fun(tb: u.renderer.TreeBuilder, item: T, idx: number): any --- @param f fun(tb: u.renderer.TreeBuilder, item: T, idx: number): any
function TreeBuilder:ipairs(arr, f) function TreeBuilder:ipairs(arr, f)
return self:nest(function(tb) return self:nest(function(tb)

View File

@ -318,18 +318,89 @@ describe('Range', function()
end) end)
end) end)
it('from_cmd_args', function() it('from_cmd_args: range=0', function()
local args = { range = 1 } local args = { range = 0 }
withbuf(
{ 'line one', 'and line two' },
function() assert.are.same(Range.from_cmd_args(args), nil) end
)
end)
it('from_cmd_args: range=1', function()
local args = { range = 1, line1 = 1 }
withbuf({ 'line one', 'and line two' }, function() withbuf({ 'line one', 'and line two' }, function()
local a = Pos.new(nil, 1, 1) local a = Pos.new(nil, 1, 1)
local b = Pos.new(nil, 2, 2) local b = Pos.new(nil, 1, Pos.MAX_COL)
local range = Range.from_cmd_args(args) --[[@as u.Range]]
assert.are.same(range.start, a)
assert.are.same(range.stop, b)
assert.are.same(range.mode, 'V')
assert.are.same(range:text(), 'line one')
end)
end)
it('from_cmd_args: range=2: no-visual', function()
local args = { range = 2, line1 = 1, line2 = 2 }
withbuf({ 'line one', 'and line two' }, function()
local range = Range.from_cmd_args(args) --[[@as u.Range]]
assert.are.same(range.start, Pos.new(nil, 1, 1))
assert.are.same(range.stop, Pos.new(nil, 2, Pos.MAX_COL))
assert.are.same(range.mode, 'V')
assert.are.same(range:text(), 'line one\nand line two')
end)
end)
it('from_cmd_args: range=2: visual: linewise', function()
local args = { range = 2, line1 = 1, line2 = 2 }
withbuf({ 'line one', 'and line two' }, function()
local a = Pos.new(nil, 1, 1)
local b = Pos.new(nil, 2, Pos.MAX_COL)
a:save_to_pos "'<" a:save_to_pos "'<"
b:save_to_pos "'>" b:save_to_pos "'>"
local range = Range.from_cmd_args(args) --[[@as u.Range]]
assert.are.same(range.start, a)
assert.are.same(range.stop, b)
assert.are.same(range.mode, 'V')
assert.are.same(range:text(), 'line one\nand line two')
end)
end)
local range = Range.from_cmd_args(args) it('from_cmd_args: range=2: visual: charwise', function()
local args = { range = 2, line1 = 1, line2 = 1 }
withbuf({ 'line one', 'and line two' }, function()
-- Simulate a visual selection:
local a = Pos.new(nil, 1, 1)
local b = Pos.new(nil, 1, 4)
a:save_to_pos "'<"
b:save_to_pos "'>"
Range.new(a, b, 'v'):set_visual_selection()
assert.are.same(vim.fn.mode(), 'v')
-- In this simulated setup, we need to force visualmode() to return
-- 'v' and histget() to return [['<,'>]]:
-- visualmode()
local orig_visualmode = vim.fn.visualmode
--- @diagnostic disable-next-line: duplicate-set-field
function vim.fn.visualmode() return 'v' end
assert.are.same(vim.fn.visualmode(), 'v')
-- histget()
local orig_histget = vim.fn.histget
--- @diagnostic disable-next-line: duplicate-set-field
function vim.fn.histget(x, y) return [['<,'>]] end
-- Now run the test:
local range = Range.from_cmd_args(args) --[[@as u.Range]]
assert.are.same(range.start, a) assert.are.same(range.start, a)
assert.are.same(range.stop, b) assert.are.same(range.stop, b)
assert.are.same(range.mode, 'v') assert.are.same(range.mode, 'v')
assert.are.same(range:text(), 'line')
-- Reset visualmode() and histget():
vim.fn.visualmode = orig_visualmode
vim.fn.histget = orig_histget
end) end)
end) end)