initial commit

This commit is contained in:
2024-08-31 22:36:09 -06:00
commit 61460f0180
18 changed files with 1646 additions and 0 deletions

13
spec/buffer_spec.lua Normal file
View File

@@ -0,0 +1,13 @@
local Buffer = require 'tt.buffer'
local withbuf = require '__tt_test_tools'
describe('Buffer', function()
it('should replace all lines', function()
withbuf({}, function()
local buf = Buffer.new()
buf:all():replace 'bleh'
local actual_lines = vim.api.nvim_buf_get_lines(buf.buf, 0, -1, false)
assert.are.same({ 'bleh' }, actual_lines)
end)
end)
end)

29
spec/codewriter_spec.lua Normal file
View File

@@ -0,0 +1,29 @@
local CodeWriter = require 'tt.codewriter'
describe('CodeWriter', function()
it('should write with indentation', function()
local cw = CodeWriter.new()
cw:write '{'
cw:indent(function(cw2) cw2:write 'x: 123' end)
cw:write '}'
assert.are.same(cw.lines, { '{', ' x: 123', '}' })
end)
it('should keep relative indentation', function()
local cw = CodeWriter.new()
cw:write '{'
cw:indent(function(cw2)
cw2:write 'x: 123'
cw2:write ' y: 123'
end)
cw:write '}'
assert.are.same(cw.lines, {
'{',
' x: 123',
' y: 123',
'}',
})
end)
end)

69
spec/pos_spec.lua Normal file
View File

@@ -0,0 +1,69 @@
local Pos = require 'tt.pos'
local withbuf = require '__tt_test_tools'
describe('Pos', function()
it('get a char from a given position', function()
withbuf({ 'asdf', 'bleh', 'a', '', 'goo' }, function()
assert.are.same('a', Pos.new(nil, 0, 0):char())
assert.are.same('d', Pos.new(nil, 0, 2):char())
assert.are.same('f', Pos.new(nil, 0, 3):char())
assert.are.same('a', Pos.new(nil, 2, 0):char())
assert.are.same('', Pos.new(nil, 3, 0):char())
assert.are.same('o', Pos.new(nil, 4, 2):char())
end)
end)
it('comparison operators', function()
local a = Pos.new(0, 0, 0, 0)
local b = Pos.new(0, 1, 0, 0)
assert.are.same(a == a, true)
assert.are.same(a < b, true)
end)
it('get the next position', function()
withbuf({ 'asdf', 'bleh', 'a', '', 'goo' }, function()
-- line 1: a => s
assert.are.same(Pos.new(nil, 0, 1), Pos.new(nil, 0, 0):next())
-- line 1: d => f
assert.are.same(Pos.new(nil, 0, 3), Pos.new(nil, 0, 2):next())
-- line 1 => 2
assert.are.same(Pos.new(nil, 1, 0), Pos.new(nil, 0, 3):next())
-- line 3 => 4
assert.are.same(Pos.new(nil, 3, 0), Pos.new(nil, 2, 0):next())
-- line 4 => 5
assert.are.same(Pos.new(nil, 4, 0), Pos.new(nil, 3, 0):next())
-- end returns nil
assert.are.same(nil, Pos.new(nil, 4, 2):next())
end)
end)
it('get the previous position', function()
withbuf({ 'asdf', 'bleh', 'a', '', 'goo' }, function()
-- line 1: s => a
assert.are.same(Pos.new(nil, 0, 0), Pos.new(nil, 0, 1):next(-1))
-- line 1: f => d
assert.are.same(Pos.new(nil, 0, 2), Pos.new(nil, 0, 3):next(-1))
-- line 2 => 1
assert.are.same(Pos.new(nil, 0, 3), Pos.new(nil, 1, 0):next(-1))
-- line 4 => 3
assert.are.same(Pos.new(nil, 2, 0), Pos.new(nil, 3, 0):next(-1))
-- line 5 => 4
assert.are.same(Pos.new(nil, 3, 0), Pos.new(nil, 4, 0):next(-1))
-- beginning returns nil
assert.are.same(nil, Pos.new(nil, 0, 0):next(-1))
end)
end)
it('find matching brackets', function()
withbuf({ 'asdf ({} def <[{}]>) ;lkj' }, function()
-- outer parens are matched:
assert.are.same(Pos.new(nil, 0, 19), Pos.new(nil, 0, 5):find_match())
-- outer parens are matched (backward):
assert.are.same(Pos.new(nil, 0, 5), Pos.new(nil, 0, 19):find_match())
-- no potential match returns nil
assert.are.same(nil, Pos.new(nil, 0, 0):find_match())
-- watchdog expires before an otherwise valid match is found:
assert.are.same(nil, Pos.new(nil, 0, 5):find_match(2))
end)
end)
end)

279
spec/range_spec.lua Normal file
View File

@@ -0,0 +1,279 @@
local Range = require 'tt.range'
local Pos = require 'tt.pos'
local withbuf = require '__tt_test_tools'
describe('Range', function()
it('get text in buffer', function()
withbuf({ 'line one', 'and line two' }, function()
local range = Range.from_buf_text()
local lines = range:lines()
assert.are.same({
'line one',
'and line two',
}, lines)
local text = range:text()
assert.are.same('line one\nand line two', text)
end)
withbuf({}, function()
local range = Range.from_buf_text()
local lines = range:lines()
assert.are.same({ '' }, lines)
local text = range:text()
assert.are.same('', text)
end)
end)
it('get from positions: v in single line', function()
withbuf({ 'line one', 'and line two' }, function()
local range = Range.new(Pos.new(nil, 0, 1), Pos.new(nil, 0, 3), 'v')
local lines = range:lines()
assert.are.same({ 'ine' }, lines)
local text = range:text()
assert.are.same('ine', text)
end)
end)
it('get from positions: v across multiple lines', function()
withbuf({ 'pre line', 'the quick brown fox', 'jumps over a lazy dog', 'post line' }, function()
local range = Range.new(Pos.new(nil, 1, 4), Pos.new(nil, 2, 4), 'v')
local lines = range:lines()
assert.are.same({ 'quick brown fox', 'jumps' }, lines)
end)
end)
it('get from positions: V', function()
withbuf({ 'line one', 'and line two' }, function()
local range = Range.new(Pos.new(nil, 0, 0), Pos.new(nil, 0, Pos.MAX_COL), 'V')
local lines = range:lines()
assert.are.same({ 'line one' }, lines)
local text = range:text()
assert.are.same('line one', text)
end)
end)
it('get from positions: V across multiple lines', function()
withbuf({ 'pre line', 'the quick brown fox', 'jumps over a lazy dog', 'post line' }, function()
local range = Range.new(Pos.new(nil, 1, 0), Pos.new(nil, 2, Pos.MAX_COL), 'V')
local lines = range:lines()
assert.are.same({ 'the quick brown fox', 'jumps over a lazy dog' }, lines)
end)
end)
it('get from line', function()
withbuf({ 'line one', 'and line two' }, function()
local range = Range.from_line(nil, 0)
local lines = range:lines()
assert.are.same({ 'line one' }, lines)
local text = range:text()
assert.are.same('line one', text)
end)
end)
it('get from lines', function()
withbuf({ 'line one', 'and line two', 'and line 3' }, function()
local range = Range.from_lines(nil, 0, 1)
local lines = range:lines()
assert.are.same({ 'line one', 'and line two' }, lines)
local text = range:text()
assert.are.same('line one\nand line two', text)
end)
end)
it('replace within line', function()
withbuf({ 'pre line', 'the quick brown fox', 'jumps over a lazy dog', 'post line' }, function()
local range = Range.new(Pos.new(nil, 1, 4), Pos.new(nil, 1, 8), 'v')
range:replace 'quack'
local text = Range.from_line(nil, 1):text()
assert.are.same('the quack brown fox', text)
end)
end)
it('delete within line', function()
withbuf({ 'pre line', 'the quick brown fox', 'jumps over a lazy dog', 'post line' }, function()
local range = Range.new(Pos.new(nil, 1, 4), Pos.new(nil, 1, 9), 'v')
range:replace ''
local text = Range.from_line(nil, 1):text()
assert.are.same('the brown fox', text)
end)
withbuf({ 'pre line', 'the quick brown fox', 'jumps over a lazy dog', 'post line' }, function()
local range = Range.new(Pos.new(nil, 1, 4), Pos.new(nil, 1, 9), 'v')
range:replace(nil)
local text = Range.from_line(nil, 1):text()
assert.are.same('the brown fox', text)
end)
end)
it('replace across multiple lines: v', function()
withbuf({ 'pre line', 'the quick brown fox', 'jumps over a lazy dog', 'post line' }, function()
local range = Range.new(Pos.new(nil, 1, 4), Pos.new(nil, 2, 4), 'v')
range:replace 'plane flew'
local lines = Range.from_buf_text():lines()
assert.are.same({
'pre line',
'the plane flew over a lazy dog',
'post line',
}, lines)
end)
end)
it('replace a line', function()
withbuf({ 'pre line', 'the quick brown fox', 'jumps over a lazy dog', 'post line' }, function()
local range = Range.from_line(nil, 1)
range:replace 'the rabbit'
local lines = Range.from_buf_text():lines()
assert.are.same({
'pre line',
'the rabbit',
'jumps over a lazy dog',
'post line',
}, lines)
end)
end)
it('replace multiple lines', function()
withbuf({ 'pre line', 'the quick brown fox', 'jumps over a lazy dog', 'post line' }, function()
local range = Range.from_lines(nil, 1, 2)
range:replace 'the rabbit'
local lines = Range.from_buf_text():lines()
assert.are.same({
'pre line',
'the rabbit',
'post line',
}, lines)
end)
end)
it('delete single line', function()
withbuf({ 'pre line', 'the quick brown fox', 'jumps over a lazy dog', 'post line' }, function()
local range = Range.from_line(nil, 1)
range:replace(nil) -- delete lines
local lines = Range.from_buf_text():lines()
assert.are.same({
'pre line',
'jumps over a lazy dog',
'post line',
}, lines)
end)
end)
it('delete multiple lines', function()
withbuf({ 'pre line', 'the quick brown fox', 'jumps over a lazy dog', 'post line' }, function()
local range = Range.from_lines(nil, 1, 2)
range:replace(nil) -- delete lines
local lines = Range.from_buf_text():lines()
assert.are.same({
'pre line',
'post line',
}, lines)
end)
end)
it('text object: word', function()
withbuf({ 'the quick brown fox' }, function()
vim.fn.setpos('.', { 0, 1, 5, 0 })
assert.are.same('quick ', Range.from_text_object('aw'):text())
vim.fn.setpos('.', { 0, 1, 5, 0 })
assert.are.same('quick', Range.from_text_object('iw'):text())
end)
end)
it('text object: quote', function()
withbuf({ [[the "quick" brown fox]] }, function()
vim.fn.setpos('.', { 0, 1, 5, 0 })
assert.are.same('"quick"', Range.from_text_object('a"'):text())
vim.fn.setpos('.', { 0, 1, 6, 0 })
assert.are.same('quick', Range.from_text_object('i"'):text())
end)
withbuf({ [[the 'quick' brown fox]] }, function()
vim.fn.setpos('.', { 0, 1, 5, 0 })
assert.are.same("'quick'", Range.from_text_object([[a']]):text())
vim.fn.setpos('.', { 0, 1, 6, 0 })
assert.are.same('quick', Range.from_text_object([[i']]):text())
end)
withbuf({ [[the `quick` brown fox]] }, function()
vim.fn.setpos('.', { 0, 1, 5, 0 })
assert.are.same('`quick`', Range.from_text_object([[a`]]):text())
vim.fn.setpos('.', { 0, 1, 6, 0 })
assert.are.same('quick', Range.from_text_object([[i`]]):text())
end)
end)
it('text object: block', function()
withbuf({ 'this is a {', 'block', '} here' }, function()
vim.fn.setpos('.', { 0, 2, 1, 0 })
assert.are.same('{\nblock\n}', Range.from_text_object('a{'):text())
vim.fn.setpos('.', { 0, 2, 1, 0 })
assert.are.same('block', Range.from_text_object('i{'):text())
end)
end)
it('text object: restores cursor position', function()
withbuf({ 'this is a {block} here' }, function()
vim.fn.setpos('.', { 0, 1, 13, 0 })
assert.are.same('{block}', Range.from_text_object('a{'):text())
assert.are.same(vim.api.nvim_win_get_cursor(0), { 1, 12 })
end)
end)
it('should get nearest block', function()
withbuf({
'this is a {',
'block',
'} here',
}, function()
vim.fn.setpos('.', { 0, 2, 1, 0 })
assert.are.same('{\nblock\n}', Range.find_nearest_brackets():text())
end)
withbuf({
'this is a {',
'(block)',
'} here',
}, function()
vim.fn.setpos('.', { 0, 2, 3, 0 })
assert.are.same('(block)', Range.find_nearest_brackets():text())
end)
end)
it('line0', function()
withbuf({
'this is a {',
'block',
'} here',
}, function()
local range = Range.new(Pos.new(0, 0, 5), Pos.new(0, 1, 4), 'v')
local lfirst = range:line0(0)
assert.are.same(5, lfirst.idx0.start)
assert.are.same(10, lfirst.idx0.stop)
assert.are.same(0, lfirst.lnum)
assert.are.same('is a {', lfirst.text())
assert.are.same('is a {', lfirst.range():text())
assert.are.same(Pos.new(0, 0, 5), lfirst.range().start)
assert.are.same(Pos.new(0, 0, 10), lfirst.range().stop)
assert.are.same('block', range:line0(1).text())
end)
end)
end)