diff --git a/README.md b/README.md index 3027876..2531726 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ return { config = { -- startVisible = true, -- showBlankVirtLine = true, + -- highlightColor = "Comment", -- hints = { -- Caret = { text = "^", prio = 2 }, -- Dollar = { text = "$", prio = 1 }, diff --git a/lua/precognition/init.lua b/lua/precognition/init.lua index d84369c..9d5e3b5 100644 --- a/lua/precognition/init.lua +++ b/lua/precognition/init.lua @@ -28,12 +28,14 @@ local M = {} ---@class Precognition.Config ---@field startVisible boolean ---@field showBlankVirtLine boolean +---@field highlightColor string ---@field hints Precognition.HintConfig ---@field gutterHints Precognition.GutterHintConfig ---@class Precognition.PartialConfig ---@field startVisible? boolean ---@field showBlankVirtLine? boolean +---@field highlightColor? string ---@field hints? Precognition.HintConfig ---@field gutterHints? Precognition.GutterHintConfig @@ -70,6 +72,7 @@ local defaultHintConfig = { local default = { startVisible = true, showBlankVirtLine = true, + highlightColor = "Comment", hints = defaultHintConfig, gutterHints = { --prio is not currentlt used for gutter hints @@ -142,7 +145,7 @@ local function build_virt_line(marks, line_len) if line:match("^%s+$") then return {} end - table.insert(virt_line, { line, "Comment" }) + table.insert(virt_line, { line, config.highlightColor }) return virt_line end @@ -174,7 +177,7 @@ local function apply_gutter_hints(gutter_hints, bufnr) end vim.fn.sign_define(gutter_name_prefix .. hint, { text = config.gutterHints[hint].text, - texthl = "Comment", + texthl = config.highlightColor, }) local ok, res = pcall(vim.fn.sign_place, 0, gutter_group, gutter_name_prefix .. hint, bufnr, { lnum = loc, diff --git a/lua/precognition/utils.lua b/lua/precognition/utils.lua index 741ba9e..04cf32e 100644 --- a/lua/precognition/utils.lua +++ b/lua/precognition/utils.lua @@ -11,7 +11,7 @@ M.char_classes = { ---@param big_word boolean ---@return integer function M.char_class(char, big_word) - big_word = big_word or false + assert(type(big_word) == "boolean", "big_word must be a boolean") local cc = M.char_classes local byte = string.byte(char) diff --git a/lua/precognition/vertical_motions.lua b/lua/precognition/vertical_motions.lua index 6e5da66..5cd3fc3 100644 --- a/lua/precognition/vertical_motions.lua +++ b/lua/precognition/vertical_motions.lua @@ -24,7 +24,7 @@ function M.next_paragraph_line(bufnr) local cursorline, _ = unpack(vim.api.nvim_win_get_cursor(0)) while not found and cursorline < visibleline do local cursorlinecontent = buffcontent[cursorline] - while cursorline < visibleline and cursorlinecontent:match("^%s*$") do + while cursorline < visibleline and cursorlinecontent:match("^[\n\r]*$") do cursorline = cursorline + 1 cursorlinecontent = buffcontent[cursorline] end @@ -32,7 +32,7 @@ function M.next_paragraph_line(bufnr) while cursorline < visibleline and not found do cursorline = cursorline + 1 cursorlinecontent = buffcontent[cursorline] - if cursorlinecontent:match("^%s*$") then + if cursorlinecontent:match("^[\n\r]*$") then found = true end end @@ -54,7 +54,7 @@ function M.prev_paragraph_line(bufnr) local cursorline, _ = unpack(vim.api.nvim_win_get_cursor(0)) while not found and cursorline > visibleline do local cursorlinecontent = buffcontent[cursorline] - while cursorline > visibleline and cursorlinecontent:match("^%s*$") do + while cursorline > visibleline and cursorlinecontent:match("^[\n\r]*$") do cursorline = cursorline - 1 cursorlinecontent = buffcontent[cursorline] end @@ -62,7 +62,7 @@ function M.prev_paragraph_line(bufnr) while cursorline > visibleline and not found do cursorline = cursorline - 1 cursorlinecontent = buffcontent[cursorline] - if cursorlinecontent:match("^%s*$") then + if cursorlinecontent:match("^[\n\r]*$") then found = true end end diff --git a/tests/precognition/e2e_spec.lua b/tests/precognition/e2e_spec.lua index 70b6493..0245f71 100644 --- a/tests/precognition/e2e_spec.lua +++ b/tests/precognition/e2e_spec.lua @@ -29,13 +29,14 @@ describe("e2e tests", function() eq(7, vim.tbl_count(autocmds)) end) - -- 0.1 onlu? + -- 0.1 only -- it("namespace is created", function() -- local ns = vim.api.nvim_get_namespaces() -- -- eq(1, ns["precognition"]) -- eq(2, ns["precognition_gutter"]) -- :end) + -- end) -- it("virtual line is displayed and updated", function() local buffer = vim.api.nvim_create_buf(true, false) @@ -59,12 +60,16 @@ describe("e2e tests", function() for _, extmark in pairs(gutter_extmarks) do if extmark[4].sign_text == "G " then + eq("Comment", extmark[4].sign_hl_group) eq(5, extmark[2]) elseif extmark[4].sign_text == "gg" then + eq("Comment", extmark[4].sign_hl_group) eq(0, extmark[2]) elseif extmark[4].sign_text == "{ " then + eq("Comment", extmark[4].sign_hl_group) eq(0, extmark[2]) elseif extmark[4].sign_text == "} " then + eq("Comment", extmark[4].sign_hl_group) eq(2, extmark[2]) else assert(false, "unexpected sign text") @@ -73,6 +78,7 @@ describe("e2e tests", function() eq(vim.api.nvim_win_get_cursor(0)[1] - 1, extmarks[1]) eq("b e w $", extmarks[3].virt_lines[1][1][1]) + eq("Comment", extmarks[3].virt_lines[1][1][2]) vim.api.nvim_win_set_cursor(0, { 1, 6 }) precognition.on_cursor_moved() @@ -148,4 +154,48 @@ describe("e2e tests", function() end end end) + + it("virtual line text color can be customised", function() + precognition.setup({ highlightColor = "Function" }) + local buffer = vim.api.nvim_create_buf(true, false) + vim.api.nvim_set_current_buf(buffer) + vim.api.nvim_buf_set_lines( + buffer, + 0, + -1, + false, + { "Hello World this is a test", "line 2", "", "line 4", "", "line 6" } + ) + vim.api.nvim_win_set_cursor(0, { 1, 1 }) + + precognition.on_cursor_moved() + + local extmarks = vim.api.nvim_buf_get_extmark_by_id(buffer, precognition.ns, precognition.extmark, { + details = true, + }) + + local gutter_extmarks = get_gutter_extmarks(buffer) + + for _, extmark in pairs(gutter_extmarks) do + if extmark[4].sign_text == "G " then + eq("Function", extmark[4].sign_hl_group) + eq(5, extmark[2]) + elseif extmark[4].sign_text == "gg" then + eq("Function", extmark[4].sign_hl_group) + eq(0, extmark[2]) + elseif extmark[4].sign_text == "{ " then + eq("Function", extmark[4].sign_hl_group) + eq(0, extmark[2]) + elseif extmark[4].sign_text == "} " then + eq("Function", extmark[4].sign_hl_group) + eq(2, extmark[2]) + else + assert(false, "unexpected sign text") + end + end + + eq(vim.api.nvim_win_get_cursor(0)[1] - 1, extmarks[1]) + eq("b e w $", extmarks[3].virt_lines[1][1][1]) + eq("Function", extmarks[3].virt_lines[1][1][2]) + end) end) diff --git a/tests/precognition/horizontal_motions_spec.lua b/tests/precognition/horizontal_motions_spec.lua index fc47ef9..5500d5d 100644 --- a/tests/precognition/horizontal_motions_spec.lua +++ b/tests/precognition/horizontal_motions_spec.lua @@ -4,36 +4,40 @@ local eq = assert.are.same describe("boundaries", function() it("finds the next word boundary", function() - eq(5, hm.next_word_boundary("abc efg", 1, 7, false)) - eq(5, hm.next_word_boundary("abc efg", 2, 7, false)) - eq(5, hm.next_word_boundary("abc efg", 3, 7, false)) - eq(5, hm.next_word_boundary("abc efg", 4, 7, false)) - eq(0, hm.next_word_boundary("abc efg", 5, 7, false)) - eq(0, hm.next_word_boundary("abc efg", 6, 7, false)) - eq(0, hm.next_word_boundary("abc efg", 7, 7, false)) + local str = "abc efg" + eq(5, hm.next_word_boundary(str, 1, #str, false)) + eq(5, hm.next_word_boundary(str, 2, #str, false)) + eq(5, hm.next_word_boundary(str, 3, #str, false)) + eq(5, hm.next_word_boundary(str, 4, #str, false)) + eq(0, hm.next_word_boundary(str, 5, #str, false)) + eq(0, hm.next_word_boundary(str, 6, #str, false)) + eq(0, hm.next_word_boundary(str, 7, #str, false)) - eq(9, hm.next_word_boundary("slighly more complex test", 1, 22, false)) - eq(9, hm.next_word_boundary("slighly more complex test", 2, 22, false)) - eq(14, hm.next_word_boundary("slighly more complex test", 10, 22, false)) - eq(14, hm.next_word_boundary("slighly more complex test", 13, 22, false)) - eq(22, hm.next_word_boundary("slighly more complex test", 15, 22, false)) - eq(22, hm.next_word_boundary("slighly more complex test", 21, 22, false)) + str = "slighly more complex test" + eq(9, hm.next_word_boundary(str, 1, #str, false)) + eq(9, hm.next_word_boundary(str, 2, #str, false)) + eq(14, hm.next_word_boundary(str, 10, #str, false)) + eq(14, hm.next_word_boundary(str, 13, #str, false)) + eq(22, hm.next_word_boundary(str, 15, #str, false)) + eq(22, hm.next_word_boundary(str, 21, #str, false)) - eq(5, hm.next_word_boundary(" myFunction(example, stuff)", 1, 30, false)) - eq(5, hm.next_word_boundary(" myFunction(example, stuff)", 2, 30, false)) - eq(5, hm.next_word_boundary(" myFunction(example, stuff)", 3, 30, false)) - eq(15, hm.next_word_boundary(" myFunction(example, stuff)", 5, 30, false)) - eq(16, hm.next_word_boundary(" myFunction(example, stuff)", 15, 30, false)) - eq(23, hm.next_word_boundary(" myFunction(example, stuff)", 16, 30, false)) - eq(25, hm.next_word_boundary(" myFunction(example, stuff)", 23, 30, false)) - eq(25, hm.next_word_boundary(" myFunction(example, stuff)", 24, 30, false)) - eq(30, hm.next_word_boundary(" myFunction(example, stuff)", 25, 30, false)) - eq(0, hm.next_word_boundary(" myFunction(example, stuff)", 30, 30, false)) + str = " myFunction(example, stuff)" + eq(5, hm.next_word_boundary(str, 1, #str, false)) + eq(5, hm.next_word_boundary(str, 2, #str, false)) + eq(5, hm.next_word_boundary(str, 3, #str, false)) + eq(15, hm.next_word_boundary(str, 5, #str, false)) + eq(16, hm.next_word_boundary(str, 15, #str, false)) + eq(23, hm.next_word_boundary(str, 16, #str, false)) + eq(25, hm.next_word_boundary(str, 23, #str, false)) + eq(25, hm.next_word_boundary(str, 24, #str, false)) + eq(30, hm.next_word_boundary(str, 25, #str, false)) + eq(0, hm.next_word_boundary(str, 30, #str, false)) end) it("finds next big word boundary", function() - eq(12, hm.next_word_boundary("a big.word string", 3, 17, true)) - eq(12, hm.next_word_boundary("a big.word string", 4, 17, true)) + local str = "a big.word string" + eq(12, hm.next_word_boundary(str, 3, #str, true)) + eq(12, hm.next_word_boundary(str, 4, #str, true)) end) it("can walk string with w", function() @@ -62,45 +66,49 @@ describe("boundaries", function() describe("previous word boundary", function() it("finds the previous word boundary", function() - eq(0, hm.prev_word_boundary("abc efg", 1, 7, false)) - eq(1, hm.prev_word_boundary("abc efg", 2, 7, false)) - eq(1, hm.prev_word_boundary("abc efg", 3, 7, false)) - eq(1, hm.prev_word_boundary("abc efg", 4, 7, false)) - eq(1, hm.prev_word_boundary("abc efg", 5, 7, false)) - eq(5, hm.prev_word_boundary("abc efg", 6, 7, false)) - eq(5, hm.prev_word_boundary("abc efg", 7, 7, false)) + local str = "abc efg" + eq(0, hm.prev_word_boundary(str, 1, #str, false)) + eq(1, hm.prev_word_boundary(str, 2, #str, false)) + eq(1, hm.prev_word_boundary(str, 3, #str, false)) + eq(1, hm.prev_word_boundary(str, 4, #str, false)) + eq(1, hm.prev_word_boundary(str, 5, #str, false)) + eq(5, hm.prev_word_boundary(str, 6, #str, false)) + eq(5, hm.prev_word_boundary(str, 7, #str, false)) - eq(9, hm.prev_word_boundary("slighly more complex test", 10, 22, false)) - eq(9, hm.prev_word_boundary("slighly more complex test", 11, 22, false)) - eq(14, hm.prev_word_boundary("slighly more complex test", 15, 22, false)) - eq(14, hm.prev_word_boundary("slighly more complex test", 16, 22, false)) - eq(22, hm.prev_word_boundary("slighly more complex test", 23, 22, false)) - eq(22, hm.prev_word_boundary("slighly more complex test", 24, 22, false)) - eq(22, hm.prev_word_boundary("slighly more complex test", 25, 22, false)) - eq(0, hm.prev_word_boundary("slighly more complex test", 1, 22, false)) + str = "slighly more complex test" + eq(9, hm.prev_word_boundary(str, 10, #str, false)) + eq(9, hm.prev_word_boundary(str, 11, #str, false)) + eq(14, hm.prev_word_boundary(str, 15, #str, false)) + eq(14, hm.prev_word_boundary(str, 16, #str, false)) + eq(22, hm.prev_word_boundary(str, 23, #str, false)) + eq(22, hm.prev_word_boundary(str, 24, #str, false)) + eq(22, hm.prev_word_boundary(str, 25, #str, false)) + eq(0, hm.prev_word_boundary(str, 1, #str, false)) - eq(0, hm.prev_word_boundary(" myFunction(example, stuff)", 1, 30, false)) - eq(0, hm.prev_word_boundary(" myFunction(example, stuff)", 2, 30, false)) - eq(0, hm.prev_word_boundary(" myFunction(example, stuff)", 3, 30, false)) - eq(0, hm.prev_word_boundary(" myFunction(example, stuff)", 4, 30, false)) - eq(0, hm.prev_word_boundary(" myFunction(example, stuff)", 5, 30, false)) - eq(5, hm.prev_word_boundary(" myFunction(example, stuff)", 6, 30, false)) - eq(5, hm.prev_word_boundary(" myFunction(example, stuff)", 15, 30, false)) - eq(15, hm.prev_word_boundary(" myFunction(example, stuff)", 16, 30, false)) - eq(16, hm.prev_word_boundary(" myFunction(example, stuff)", 17, 30, false)) - eq(16, hm.prev_word_boundary(" myFunction(example, stuff)", 18, 30, false)) - eq(16, hm.prev_word_boundary(" myFunction(example, stuff)", 19, 30, false)) - eq(23, hm.prev_word_boundary(" myFunction(example, stuff)", 25, 30, false)) - eq(25, hm.prev_word_boundary(" myFunction(example, stuff)", 26, 30, false)) - eq(25, hm.prev_word_boundary(" myFunction(example, stuff)", 27, 30, false)) - eq(25, hm.prev_word_boundary(" myFunction(example, stuff)", 28, 30, false)) - eq(25, hm.prev_word_boundary(" myFunction(example, stuff)", 29, 30, false)) - eq(25, hm.prev_word_boundary(" myFunction(example, stuff)", 30, 30, false)) + str = " myFunction(example, stuff)" + eq(0, hm.prev_word_boundary(str, 1, #str, false)) + eq(0, hm.prev_word_boundary(str, 2, #str, false)) + eq(0, hm.prev_word_boundary(str, 3, #str, false)) + eq(0, hm.prev_word_boundary(str, 4, #str, false)) + eq(0, hm.prev_word_boundary(str, 5, #str, false)) + eq(5, hm.prev_word_boundary(str, 6, #str, false)) + eq(5, hm.prev_word_boundary(str, 15, #str, false)) + eq(15, hm.prev_word_boundary(str, 16, #str, false)) + eq(16, hm.prev_word_boundary(str, 17, #str, false)) + eq(16, hm.prev_word_boundary(str, 18, #str, false)) + eq(16, hm.prev_word_boundary(str, 19, #str, false)) + eq(23, hm.prev_word_boundary(str, 25, #str, false)) + eq(25, hm.prev_word_boundary(str, 26, #str, false)) + eq(25, hm.prev_word_boundary(str, 27, #str, false)) + eq(25, hm.prev_word_boundary(str, 28, #str, false)) + eq(25, hm.prev_word_boundary(str, 29, #str, false)) + eq(25, hm.prev_word_boundary(str, 30, #str, false)) end) it("finds previous big word boundary", function() - eq(3, hm.prev_word_boundary("a big.word string", 10, 17, true)) - eq(3, hm.prev_word_boundary("a big.word string", 10, 17, true)) + local str = "a big.word string" + eq(3, hm.prev_word_boundary(str, 10, #str, true)) + eq(3, hm.prev_word_boundary(str, 10, #str, true)) end) it("can walk string with b", function() @@ -127,33 +135,37 @@ describe("boundaries", function() describe("end of current word", function() it("finds the end of words", function() - eq(3, hm.end_of_word("abc efg", 1, 7, false)) - eq(3, hm.end_of_word("abc efg", 2, 7, false)) - eq(7, hm.end_of_word("abc efg", 3, 7, false)) + local str = "abc efg" + eq(3, hm.end_of_word(str, 1, #str, false)) + eq(3, hm.end_of_word(str, 2, #str, false)) + eq(7, hm.end_of_word(str, 3, #str, false)) - eq(7, hm.end_of_word("slighly more complex test", 1, 25, false)) - eq(7, hm.end_of_word("slighly more complex test", 2, 25, false)) - eq(12, hm.end_of_word("slighly more complex test", 10, 25, false)) - eq(20, hm.end_of_word("slighly more complex test", 13, 25, false)) - eq(20, hm.end_of_word("slighly more complex test", 15, 25, false)) - eq(25, hm.end_of_word("slighly more complex test", 21, 25, false)) + str = "slighly more complex test" + eq(7, hm.end_of_word(str, 1, #str, false)) + eq(7, hm.end_of_word(str, 2, #str, false)) + eq(12, hm.end_of_word(str, 10, #str, false)) + eq(20, hm.end_of_word(str, 13, #str, false)) + eq(20, hm.end_of_word(str, 15, #str, false)) + eq(25, hm.end_of_word(str, 21, #str, false)) - eq(14, hm.end_of_word(" myFunction(example, stuff)", 1, 30, false)) - eq(14, hm.end_of_word(" myFunction(example, stuff)", 2, 30, false)) - eq(14, hm.end_of_word(" myFunction(example, stuff)", 3, 30, false)) - eq(14, hm.end_of_word(" myFunction(example, stuff)", 5, 30, false)) - eq(15, hm.end_of_word(" myFunction(example, stuff)", 14, 30, false)) - eq(22, hm.end_of_word(" myFunction(example, stuff)", 15, 30, false)) - eq(22, hm.end_of_word(" myFunction(example, stuff)", 16, 30, false)) - eq(29, hm.end_of_word(" myFunction(example, stuff)", 23, 30, false)) - eq(29, hm.end_of_word(" myFunction(example, stuff)", 24, 30, false)) - eq(29, hm.end_of_word(" myFunction(example, stuff)", 25, 30, false)) - eq(30, hm.end_of_word(" myFunction(example, stuff)", 29, 30, false)) - eq(0, hm.end_of_word(" myFunction(example, stuff)", 30, 30, false)) + str = " myFunction(example, stuff)" + eq(14, hm.end_of_word(str, 1, #str, false)) + eq(14, hm.end_of_word(str, 2, #str, false)) + eq(14, hm.end_of_word(str, 3, #str, false)) + eq(14, hm.end_of_word(str, 5, #str, false)) + eq(15, hm.end_of_word(str, 14, #str, false)) + eq(22, hm.end_of_word(str, 15, #str, false)) + eq(22, hm.end_of_word(str, 16, #str, false)) + eq(29, hm.end_of_word(str, 23, #str, false)) + eq(29, hm.end_of_word(str, 24, #str, false)) + eq(29, hm.end_of_word(str, 25, #str, false)) + eq(30, hm.end_of_word(str, 29, #str, false)) + eq(0, hm.end_of_word(str, 30, #str, false)) end) it("finds the end of the current big word", function() - eq(10, hm.end_of_word("a big.word string", 3, 17, true)) + local str = "a big.word string" + eq(10, hm.end_of_word(str, 3, #str, true)) end) end) end) @@ -182,66 +194,74 @@ end) describe("matching brackets", function() it("if cursor is over a bracket it can find the pair", function() - eq(9, hm.matching_bracket("abc (efg)", 5, 9)) - eq(0, hm.matching_bracket("abc (efg)", 6, 9)) - eq(0, hm.matching_bracket("abc (efg)", 7, 9)) - eq(0, hm.matching_bracket("abc (efg)", 8, 9)) - eq(5, hm.matching_bracket("abc (efg)", 9, 9)) + local str = "abc (efg)" + eq(9, hm.matching_bracket(str, 5, #str)) + eq(0, hm.matching_bracket(str, 6, #str)) + eq(0, hm.matching_bracket(str, 7, #str)) + eq(0, hm.matching_bracket(str, 8, #str)) + eq(5, hm.matching_bracket(str, 9, #str)) end) it("if cursor is over a square bracket it can find the pair", function() - eq(9, hm.matching_bracket("abc [efg]", 5, 9)) - eq(0, hm.matching_bracket("abc [efg]", 6, 9)) - eq(0, hm.matching_bracket("abc [efg]", 7, 9)) - eq(0, hm.matching_bracket("abc [efg]", 8, 9)) - eq(5, hm.matching_bracket("abc [efg]", 9, 9)) + local str = "abc [efg]" + eq(9, hm.matching_bracket(str, 5, #str)) + eq(0, hm.matching_bracket(str, 6, #str)) + eq(0, hm.matching_bracket(str, 7, #str)) + eq(0, hm.matching_bracket(str, 8, #str)) + eq(5, hm.matching_bracket(str, 9, #str)) end) it("if cursor is over a curly bracket it can find the pair", function() - eq(9, hm.matching_bracket("abc {efg}", 5, 9)) - eq(0, hm.matching_bracket("abc {efg}", 6, 9)) - eq(0, hm.matching_bracket("abc {efg}", 7, 9)) - eq(0, hm.matching_bracket("abc {efg}", 8, 9)) - eq(5, hm.matching_bracket("abc {efg}", 9, 9)) + local str = "abc {efg}" + eq(9, hm.matching_bracket(str, 5, #str)) + eq(0, hm.matching_bracket(str, 6, #str)) + eq(0, hm.matching_bracket(str, 7, #str)) + eq(0, hm.matching_bracket(str, 8, #str)) + eq(5, hm.matching_bracket(str, 9, #str)) end) it("nested brackets find the correct pair", function() - eq(19, hm.matching_bracket("abc (efg [hij] klm)", 5, 19)) - eq(0, hm.matching_bracket("abc (efg [hij] klm)", 6, 19)) - eq(14, hm.matching_bracket("abc (efg [hij] klm)", 10, 19)) - eq(10, hm.matching_bracket("abc (efg [hij] klm)", 14, 19)) - eq(0, hm.matching_bracket("abc (efg [hij] klm)", 15, 19)) - eq(5, hm.matching_bracket("abc (efg [hij] klm)", 19, 19)) + local str = "abc (efg [hij] klm)" + eq(19, hm.matching_bracket(str, 5, #str)) + eq(0, hm.matching_bracket(str, 6, #str)) + eq(14, hm.matching_bracket(str, 10, #str)) + eq(10, hm.matching_bracket(str, 14, #str)) + eq(0, hm.matching_bracket(str, 15, #str)) + eq(5, hm.matching_bracket(str, 19, #str)) end) it("nested brackets of the same type find the correct pair", function() - eq(19, hm.matching_bracket("abc (efg (hij) klm)", 5, 19)) - eq(0, hm.matching_bracket("abc (efg (hij) klm)", 6, 19)) - eq(14, hm.matching_bracket("abc (efg (hij) klm)", 10, 19)) - eq(10, hm.matching_bracket("abc (efg (hij) klm)", 14, 19)) - eq(0, hm.matching_bracket("abc (efg (hij) klm)", 15, 19)) - eq(5, hm.matching_bracket("abc (efg (hij) klm)", 19, 19)) + local str = "abc (efg (hij) klm)" + eq(19, hm.matching_bracket(str, 5, #str)) + eq(0, hm.matching_bracket(str, 6, #str)) + eq(14, hm.matching_bracket(str, 10, #str)) + eq(10, hm.matching_bracket(str, 14, #str)) + eq(0, hm.matching_bracket(str, 15, #str)) + eq(5, hm.matching_bracket(str, 19, #str)) end) it("if cursor is over an unclosed bracket it returns 0", function() - eq(0, hm.matching_bracket("abc (efg", 5, 8)) - eq(0, hm.matching_bracket("abc [efg", 5, 8)) - eq(0, hm.matching_bracket("abc {efg", 5, 8)) + local str = "abc (efg" + eq(0, hm.matching_bracket(str, 5, #str)) + eq(0, hm.matching_bracket(str, 5, #str)) + eq(0, hm.matching_bracket(str, 5, #str)) end) end) describe("matching comments", function() it("if cursor is over a comment it can find the pair", function() - eq(11, hm.matching_comment("abc /*efg*/", 5, 11)) - eq(11, hm.matching_comment("abc /*efg*/", 6, 11)) - eq(0, hm.matching_comment("abc /*efg*/", 7, 11)) - eq(5, hm.matching_comment("abc /*efg*/", 10, 11)) - eq(5, hm.matching_comment("abc /*efg*/", 11, 11)) + local str = "abc /*efg*/" + eq(11, hm.matching_comment(str, 5, #str)) + eq(11, hm.matching_comment(str, 6, #str)) + eq(0, hm.matching_comment(str, 7, #str)) + eq(5, hm.matching_comment(str, 10, #str)) + eq(5, hm.matching_comment(str, 11, #str)) end) it("if cursor is over an unclosed comment it returns 0", function() - eq(0, hm.matching_comment("abc /*efg", 5, 9)) - eq(0, hm.matching_comment("abc /*efg", 6, 9)) + local str = "abc /*efg" + eq(0, hm.matching_comment(str, 5, #str)) + eq(0, hm.matching_comment(str, 6, #str)) end) end) diff --git a/tests/precognition/vertical_motions_spec.lua b/tests/precognition/vertical_motions_spec.lua index ac8e03f..1119622 100644 --- a/tests/precognition/vertical_motions_spec.lua +++ b/tests/precognition/vertical_motions_spec.lua @@ -142,4 +142,24 @@ describe("gutter motion locations", function() local next_line = vm.next_paragraph_line(testBuf) eq(8, next_line) end) + + it("lines with just whitespace as part of a paragraph", function() + local testBuf = vim.api.nvim_create_buf(true, true) + vim.api.nvim_buf_set_lines(testBuf, 0, -1, false, { + "ABC", + "DEF", + " ", + "GHI", + "", + "JKL", + "", + "MNO", + }) + + vim.api.nvim_set_current_buf(testBuf) + vim.api.nvim_win_set_cursor(0, { 1, 0 }) + + local next_line = vm.next_paragraph_line(testBuf) + eq(5, next_line) + end) end) diff --git a/tests/precognition/virtline_spec.lua b/tests/precognition/virtline_spec.lua index 9a54729..a925e68 100644 --- a/tests/precognition/virtline_spec.lua +++ b/tests/precognition/virtline_spec.lua @@ -42,6 +42,7 @@ describe("Build Virtual Line", function() it("can build a complex virtual line", function() ---@type Precognition.VirtLine + ---@diagnostic disable-next-line: missing-fields local marks = { Caret = 1, e = 6, @@ -113,6 +114,7 @@ end) describe("Priority", function() it("0 priority item is not added", function() precognition.setup({ + ---@diagnostic disable-next-line: missing-fields hints = { Caret = { prio = 0, @@ -138,6 +140,7 @@ describe("Priority", function() it("a higher priority mark in the same space takes priority", function() precognition.setup({ + ---@diagnostic disable-next-line: missing-fields hints = { Caret = { prio = 0, @@ -163,6 +166,7 @@ describe("Priority", function() it("a higher priority mark in the same space takes priority", function() precognition.setup({ + ---@diagnostic disable-next-line: missing-fields hints = { Caret = { prio = 1, @@ -185,6 +189,7 @@ describe("Priority", function() eq(1, #virtual_line[1][1]) precognition.setup({ + ---@diagnostic disable-next-line: missing-fields hints = { Caret = { prio = 100,