Add Range:length and Range:sub
All checks were successful
NeoVim tests / plenary-tests (push) Successful in 9s
All checks were successful
NeoVim tests / plenary-tests (push) Successful in 9s
This commit is contained in:
parent
9f5fdb4f2b
commit
58e447aad6
@ -308,7 +308,6 @@ function Range:contains(x)
|
||||
return false
|
||||
end
|
||||
|
||||
--- TODO: test
|
||||
--- @param other u.Range
|
||||
--- @return u.Range|nil, u.Range|nil
|
||||
function Range:difference(other)
|
||||
@ -337,6 +336,64 @@ function Range:difference(other)
|
||||
return left, right
|
||||
end
|
||||
|
||||
function Range:length()
|
||||
if self:is_empty() then return 0 end
|
||||
|
||||
local line_positions =
|
||||
vim.fn.getregionpos(self.start:as_real():as_vim(), self.stop:as_real():as_vim(), { type = 'v' })
|
||||
|
||||
local len = 0
|
||||
for linenr, line in ipairs(line_positions) do
|
||||
if linenr > 1 then len = len + 1 end -- each newline is counted as a char
|
||||
local line_start_col = line[1][3]
|
||||
local line_stop_col = line[2][3]
|
||||
local line_len = line_stop_col - line_start_col + 1
|
||||
len = len + line_len
|
||||
end
|
||||
return len
|
||||
end
|
||||
|
||||
--- @param i number 1-based
|
||||
--- @param j? number 1-based
|
||||
function Range:sub(i, j)
|
||||
local line_positions =
|
||||
vim.fn.getregionpos(self.start:as_real():as_vim(), self.stop:as_real():as_vim(), { type = 'v' })
|
||||
|
||||
--- @param idx number 1-based
|
||||
--- @return u.Pos|nil
|
||||
local function get_pos(idx)
|
||||
if idx < 0 then return get_pos(self:length() + idx + 1) end
|
||||
|
||||
-- find the position of the first line that contains the i-th character:
|
||||
local curr_len = 0
|
||||
for linenr, line in ipairs(line_positions) do
|
||||
if linenr > 1 then curr_len = curr_len + 1 end -- each newline is counted as a char
|
||||
local line_start_col = line[1][3]
|
||||
local line_stop_col = line[2][3]
|
||||
local line_len = line_stop_col - line_start_col + 1
|
||||
|
||||
if curr_len + line_len >= idx then
|
||||
return Pos.new(self.start.bufnr, line[1][2], line_start_col + (idx - curr_len) - 1)
|
||||
end
|
||||
curr_len = curr_len + line_len
|
||||
end
|
||||
end
|
||||
|
||||
local start = get_pos(i)
|
||||
if not start then
|
||||
-- start is inalid, so return an empty range:
|
||||
return Range.new(self.start, nil, self.mode)
|
||||
end
|
||||
|
||||
local stop
|
||||
if j then stop = get_pos(j) end
|
||||
if not stop then
|
||||
-- stop is inalid, so return an empty range:
|
||||
return Range.new(start, nil, self.mode)
|
||||
end
|
||||
return Range.new(start, stop, 'v')
|
||||
end
|
||||
|
||||
--- @return string[]
|
||||
function Range:lines()
|
||||
if self:is_empty() then return {} end
|
||||
@ -346,10 +403,6 @@ end
|
||||
--- @return string
|
||||
function Range:text() return vim.fn.join(self:lines(), '\n') end
|
||||
|
||||
--- @param i number 1-based
|
||||
--- @param j? number 1-based
|
||||
function Range:sub(i, j) return self:text():sub(i, j) end
|
||||
|
||||
--- @param l number
|
||||
--- @return { line: string; idx0: { start: number; stop: number; }; lnum: number; range: fun():u.Range; text: fun():string }|nil
|
||||
function Range:line(l)
|
||||
|
@ -446,6 +446,28 @@ describe('Range', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
it('length', function()
|
||||
withbuf({ 'line one', 'and line two' }, function()
|
||||
local range = Range.new(Pos.new(nil, 2, 4), Pos.new(nil, 2, 9), 'v')
|
||||
assert.are.same(range:length(), #range:text())
|
||||
|
||||
range = Range.new(Pos.new(nil, 1, 4), Pos.new(nil, 2, 9), 'v')
|
||||
assert.are.same(range:length(), #range:text())
|
||||
end)
|
||||
end)
|
||||
|
||||
it('sub', function()
|
||||
withbuf({ 'line one', 'and line two' }, function()
|
||||
local range = Range.new(Pos.new(nil, 2, 4), Pos.new(nil, 2, 9), 'v')
|
||||
assert.are.same(range:text(), ' line ')
|
||||
assert.are.same(range:sub(1, -1):text(), ' line ')
|
||||
assert.are.same(range:sub(2, -2):text(), 'line')
|
||||
assert.are.same(range:sub(1, 5):text(), ' line')
|
||||
assert.are.same(range:sub(2, 5):text(), 'line')
|
||||
assert.are.same(range:sub(20, 25):text(), '')
|
||||
end)
|
||||
end)
|
||||
|
||||
it('shrink', function()
|
||||
withbuf({ 'line one', 'and line two' }, function()
|
||||
local range = Range.new(Pos.new(nil, 2, 3), Pos.new(nil, 3, 5), 'v')
|
||||
@ -462,7 +484,10 @@ describe('Range', function()
|
||||
assert.are.same(shrunk.start, Pos.new(nil, 2, 4))
|
||||
assert.are.same(shrunk.stop, Pos.new(nil, 3, 4))
|
||||
|
||||
assert.has.error(function() range:must_shrink(100) end, 'error in Range:must_shrink: Range:shrink() returned nil')
|
||||
assert.has.error(
|
||||
function() range:must_shrink(100) end,
|
||||
'error in Range:must_shrink: Range:shrink() returned nil'
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
@ -500,10 +525,16 @@ describe('Range', function()
|
||||
local r = Range.new(Pos.new(b, 1, 5), Pos.new(b, 1, 9), 'v')
|
||||
|
||||
r:replace 'bleh1'
|
||||
assert.are.same({ 'The bleh1 brown fox jumps over the lazy dog' }, vim.api.nvim_buf_get_lines(b, 0, -1, false))
|
||||
assert.are.same(
|
||||
{ 'The bleh1 brown fox jumps over the lazy dog' },
|
||||
vim.api.nvim_buf_get_lines(b, 0, -1, false)
|
||||
)
|
||||
|
||||
r:replace 'bleh2'
|
||||
assert.are.same({ 'The bleh2 brown fox jumps over the lazy dog' }, vim.api.nvim_buf_get_lines(b, 0, -1, false))
|
||||
assert.are.same(
|
||||
{ 'The bleh2 brown fox jumps over the lazy dog' },
|
||||
vim.api.nvim_buf_get_lines(b, 0, -1, false)
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
@ -517,11 +548,17 @@ describe('Range', function()
|
||||
assert.are.same({ 'jumps', 'over' }, r:lines())
|
||||
|
||||
r:replace 'bleh1'
|
||||
assert.are.same({ 'The quick brown fox bleh1 the lazy dog' }, vim.api.nvim_buf_get_lines(b, 0, -1, false))
|
||||
assert.are.same(
|
||||
{ 'The quick brown fox bleh1 the lazy dog' },
|
||||
vim.api.nvim_buf_get_lines(b, 0, -1, false)
|
||||
)
|
||||
assert.are.same({ 'bleh1' }, r:lines())
|
||||
|
||||
r:replace 'blehGoo2'
|
||||
assert.are.same({ 'The quick brown fox blehGoo2 the lazy dog' }, vim.api.nvim_buf_get_lines(b, 0, -1, false))
|
||||
assert.are.same(
|
||||
{ 'The quick brown fox blehGoo2 the lazy dog' },
|
||||
vim.api.nvim_buf_get_lines(b, 0, -1, false)
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user