From 672a00f839078d80feff38ad5f13d949dabd32bf Mon Sep 17 00:00:00 2001 From: Tristan Knight Date: Tue, 21 May 2024 21:37:58 +0100 Subject: [PATCH] feat: big word support (#23) --- README.md | 7 +- lua/precognition/horizontal_motions.lua | 39 ++-- lua/precognition/init.lua | 12 +- lua/precognition/utils.lua | 6 +- tests/precognition/char_spec.lua | 41 +++- .../precognition/horizontal_motions_spec.lua | 216 ++++++++++-------- 6 files changed, 185 insertions(+), 136 deletions(-) diff --git a/README.md b/README.md index e2e149d..3027876 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ > > 1. foreknowledge of an event, especially as a form of extrasensory perception. -**precognition.nvim** is a nvim plugin for discovering motions (Both vertical and horizontal) to navigate your current buffer +**precognition.nvim** assists with discovering motions (Both vertical and horizontal) to navigate your current buffer ![image](https://github.com/tris203/precognition.nvim/assets/18444302/ea24caee-85da-42d8-b0e9-555b47268643) @@ -28,9 +28,12 @@ return { -- w = { text = "w", prio = 10 }, -- b = { text = "b", prio = 9 }, -- e = { text = "e", prio = 8 }, + -- W = { text = "W", prio = 7 }, + -- B = { text = "B", prio = 6 }, + -- E = { text = "E", prio = 5 }, -- }, -- gutterHints = { - -- --prio is not currentlt used for gutter hints + -- -- prio is not currently used for gutter hints -- G = { text = "G", prio = 1 }, -- gg = { text = "gg", prio = 1 }, -- PrevParagraph = { text = "{", prio = 1 }, diff --git a/lua/precognition/horizontal_motions.lua b/lua/precognition/horizontal_motions.lua index 1052630..42b23d0 100644 --- a/lua/precognition/horizontal_motions.lua +++ b/lua/precognition/horizontal_motions.lua @@ -28,21 +28,22 @@ end ---@param str string ---@param cursorcol integer ---@param _linelen integer +---@param big_word boolean ---@return Precognition.PlaceLoc -function M.next_word_boundary(str, cursorcol, _linelen) +function M.next_word_boundary(str, cursorcol, _linelen, big_word) local offset = cursorcol local len = vim.fn.strcharlen(str) local char = vim.fn.strcharpart(str, offset - 1, 1) - local c_class = utils.char_class(char) + local c_class = utils.char_class(char, big_word) if c_class ~= cc.whitespace then - while utils.char_class(char) == c_class and offset <= len do + while utils.char_class(char, big_word) == c_class and offset <= len do offset = offset + 1 char = vim.fn.strcharpart(str, offset - 1, 1) end end - while utils.char_class(char) == cc.whitespace and offset <= len do + while utils.char_class(char, big_word) == cc.whitespace and offset <= len do offset = offset + 1 char = vim.fn.strcharpart(str, offset - 1, 1) end @@ -56,15 +57,16 @@ end ---@param str string ---@param cursorcol integer ---@param linelen integer +---@param big_word boolean ---@return Precognition.PlaceLoc -function M.end_of_word(str, cursorcol, linelen) +function M.end_of_word(str, cursorcol, linelen, big_word) if cursorcol >= linelen then return 0 end local offset = cursorcol local char = vim.fn.strcharpart(str, offset - 1, 1) - local c_class = utils.char_class(char) - local next_char_class = utils.char_class(vim.fn.strcharpart(str, (offset - 1) + 1, 1)) + local c_class = utils.char_class(char, big_word) + local next_char_class = utils.char_class(vim.fn.strcharpart(str, (offset - 1) + 1, 1), big_word) local rev_offset if @@ -72,26 +74,26 @@ function M.end_of_word(str, cursorcol, linelen) then offset = offset + 1 char = vim.fn.strcharpart(str, offset - 1, 1) - c_class = utils.char_class(char) - next_char_class = utils.char_class(vim.fn.strcharpart(str, (offset - 1) + 1, 1)) + c_class = utils.char_class(char, big_word) + next_char_class = utils.char_class(vim.fn.strcharpart(str, (offset - 1) + 1, 1), big_word) end if c_class ~= cc.whitespace and next_char_class ~= cc.whitespace then - while utils.char_class(char) == c_class and offset <= linelen do + while utils.char_class(char, big_word) == c_class and offset <= linelen do offset = offset + 1 char = vim.fn.strcharpart(str, offset - 1, 1) end end if c_class == cc.whitespace or next_char_class == cc.whitespace then - local next_word_start = M.next_word_boundary(str, cursorcol, linelen) + local next_word_start = M.next_word_boundary(str, cursorcol, linelen, big_word) if next_word_start then - next_char_class = utils.char_class(vim.fn.strcharpart(str, (next_word_start - 1) + 1, 1)) + next_char_class = utils.char_class(vim.fn.strcharpart(str, (next_word_start - 1) + 1, 1), big_word) --next word is single char if next_char_class == cc.whitespace then rev_offset = next_word_start else - rev_offset = M.end_of_word(str, next_word_start, linelen) + rev_offset = M.end_of_word(str, next_word_start, linelen, big_word) end end end @@ -113,22 +115,23 @@ end ---@param str string ---@param cursorcol integer ---@param _linelen integer +---@param big_word boolean ---@return Precognition.PlaceLoc -function M.prev_word_boundary(str, cursorcol, _linelen) +function M.prev_word_boundary(str, cursorcol, _linelen, big_word) local len = vim.fn.strcharlen(str) local offset = cursorcol - 1 local char = vim.fn.strcharpart(str, offset - 1, 1) - local c_class = utils.char_class(char) + local c_class = utils.char_class(char, big_word) if c_class == cc.whitespace then - while utils.char_class(char) == cc.whitespace and offset >= 0 do + while utils.char_class(char, big_word) == cc.whitespace and offset >= 0 do offset = offset - 1 char = vim.fn.strcharpart(str, offset - 1, 1) end - c_class = utils.char_class(char) + c_class = utils.char_class(char, big_word) end - while utils.char_class(char) == c_class and offset >= 0 do + while utils.char_class(char, big_word) == c_class and offset >= 0 do offset = offset - 1 char = vim.fn.strcharpart(str, offset - 1, 1) --if remaining string is whitespace, return nil_wrap diff --git a/lua/precognition/init.lua b/lua/precognition/init.lua index a3eb6f7..f0289bb 100644 --- a/lua/precognition/init.lua +++ b/lua/precognition/init.lua @@ -61,6 +61,9 @@ local defaultHintConfig = { w = { text = "w", prio = 10 }, b = { text = "b", prio = 9 }, e = { text = "e", prio = 8 }, + W = { text = "W", prio = 7 }, + B = { text = "B", prio = 6 }, + E = { text = "E", prio = 5 }, } ---@type Precognition.Config @@ -213,9 +216,12 @@ local function display_marks() ---@type Precognition.VirtLine local virtual_line_marks = { Caret = hm.line_start_non_whitespace(cur_line, cursorcol, line_len), - w = hm.next_word_boundary(cur_line, cursorcol, line_len), - e = hm.end_of_word(cur_line, cursorcol, line_len), - b = hm.prev_word_boundary(cur_line, cursorcol, line_len), + w = hm.next_word_boundary(cur_line, cursorcol, line_len, false), + e = hm.end_of_word(cur_line, cursorcol, line_len, false), + b = hm.prev_word_boundary(cur_line, cursorcol, line_len, false), + W = hm.next_word_boundary(cur_line, cursorcol, line_len, true), + E = hm.end_of_word(cur_line, cursorcol, line_len, true), + B = hm.prev_word_boundary(cur_line, cursorcol, line_len, true), MatchingPair = hm.matching_pair(cur_line, cursorcol, line_len)(cur_line, cursorcol, line_len), Dollar = hm.line_end(cur_line, cursorcol, line_len), Zero = 1, diff --git a/lua/precognition/utils.lua b/lua/precognition/utils.lua index 442031a..ab13953 100644 --- a/lua/precognition/utils.lua +++ b/lua/precognition/utils.lua @@ -8,8 +8,10 @@ M.char_classes = { } ---@param char string +---@param big_word boolean ---@return integer -function M.char_class(char) +function M.char_class(char, big_word) + big_word = big_word or false local cc = M.char_classes local byte = string.byte(char) @@ -18,7 +20,7 @@ function M.char_class(char) return cc.whitespace end if char == "_" or char:match("%w") then - return cc.word + return big_word and cc.other or cc.word end return cc.other end diff --git a/tests/precognition/char_spec.lua b/tests/precognition/char_spec.lua index 098b7b5..5d51caa 100644 --- a/tests/precognition/char_spec.lua +++ b/tests/precognition/char_spec.lua @@ -13,21 +13,42 @@ end) describe("char classing", function() it("white space is classeed", function() - eq(utils.char_class(" "), 0) - eq(utils.char_class("\t"), 0) - eq(utils.char_class("\0"), 0) + eq(utils.char_class(" ", false), 0) + eq(utils.char_class("\t", false), 0) + eq(utils.char_class("\0", false), 0) end) it("word characters are classed", function() - eq(utils.char_class("_"), 2) - eq(utils.char_class("a"), 2) - eq(utils.char_class("A"), 2) - eq(utils.char_class("0"), 2) + eq(utils.char_class("_", false), 2) + eq(utils.char_class("a", false), 2) + eq(utils.char_class("A", false), 2) + eq(utils.char_class("0", false), 2) end) it("other characters are classed", function() - eq(utils.char_class("!"), 1) - eq(utils.char_class("@"), 1) - eq(utils.char_class("."), 1) + eq(utils.char_class("!", false), 1) + eq(utils.char_class("@", false), 1) + eq(utils.char_class(".", false), 1) + end) +end) + +describe("big_word classing", function() + it("big_word whitespace is classed", function() + eq(utils.char_class(" ", true), 0) + eq(utils.char_class("\t", true), 0) + eq(utils.char_class("\0", true), 0) + end) + + it("big_word word characters are classed", function() + eq(utils.char_class("_", true), 1) + eq(utils.char_class("a", true), 1) + eq(utils.char_class("A", true), 1) + eq(utils.char_class("0", true), 1) + end) + + it("big_word other characters are classed", function() + eq(utils.char_class("!", true), 1) + eq(utils.char_class("@", true), 1) + eq(utils.char_class(".", true), 1) end) end) diff --git a/tests/precognition/horizontal_motions_spec.lua b/tests/precognition/horizontal_motions_spec.lua index 719a69c..fc47ef9 100644 --- a/tests/precognition/horizontal_motions_spec.lua +++ b/tests/precognition/horizontal_motions_spec.lua @@ -4,36 +4,41 @@ 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)) - eq(5, hm.next_word_boundary("abc efg", 2, 7)) - eq(5, hm.next_word_boundary("abc efg", 3, 7)) - eq(5, hm.next_word_boundary("abc efg", 4, 7)) - eq(0, hm.next_word_boundary("abc efg", 5, 7)) - eq(0, hm.next_word_boundary("abc efg", 6, 7)) - eq(0, hm.next_word_boundary("abc efg", 7, 7)) + 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)) - eq(9, hm.next_word_boundary("slighly more complex test", 1, 22)) - eq(9, hm.next_word_boundary("slighly more complex test", 2, 22)) - eq(14, hm.next_word_boundary("slighly more complex test", 10, 22)) - eq(14, hm.next_word_boundary("slighly more complex test", 13, 22)) - eq(22, hm.next_word_boundary("slighly more complex test", 15, 22)) - eq(22, hm.next_word_boundary("slighly more complex test", 21, 22)) + 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)) - eq(5, hm.next_word_boundary(" myFunction(example, stuff)", 1, 30)) - eq(5, hm.next_word_boundary(" myFunction(example, stuff)", 2, 30)) - eq(5, hm.next_word_boundary(" myFunction(example, stuff)", 3, 30)) - eq(15, hm.next_word_boundary(" myFunction(example, stuff)", 5, 30)) - eq(16, hm.next_word_boundary(" myFunction(example, stuff)", 15, 30)) - eq(23, hm.next_word_boundary(" myFunction(example, stuff)", 16, 30)) - eq(25, hm.next_word_boundary(" myFunction(example, stuff)", 23, 30)) - eq(25, hm.next_word_boundary(" myFunction(example, stuff)", 24, 30)) - eq(30, hm.next_word_boundary(" myFunction(example, stuff)", 25, 30)) - eq(0, hm.next_word_boundary(" myFunction(example, stuff)", 30, 30)) + 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)) + 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)) end) it("can walk string with w", function() local test_string = "abcdefg hijklmn opqrstu vwxyz" - local pos = hm.next_word_boundary(test_string, 1, #test_string) + local pos = hm.next_word_boundary(test_string, 1, #test_string, false) if pos == 0 then error("pos is 0") end @@ -41,105 +46,114 @@ describe("boundaries", function() if pos == 0 then error("pos is 0") end - pos = hm.next_word_boundary(test_string, pos, #test_string) + pos = hm.next_word_boundary(test_string, pos, #test_string, false) if pos == 0 then error("pos is 0") end eq("o", test_string:sub(pos, pos)) - pos = hm.next_word_boundary(test_string, pos, #test_string) + pos = hm.next_word_boundary(test_string, pos, #test_string, false) if pos == 0 then error("pos is 0") end eq("v", test_string:sub(pos, pos)) - pos = hm.next_word_boundary(test_string, pos, #test_string) + pos = hm.next_word_boundary(test_string, pos, #test_string, false) eq(0, pos) end) describe("previous word boundary", function() it("finds the previous word boundary", function() - eq(0, hm.prev_word_boundary("abc efg", 1, 7)) - eq(1, hm.prev_word_boundary("abc efg", 2, 7)) - eq(1, hm.prev_word_boundary("abc efg", 3, 7)) - eq(1, hm.prev_word_boundary("abc efg", 4, 7)) - eq(1, hm.prev_word_boundary("abc efg", 5, 7)) - eq(5, hm.prev_word_boundary("abc efg", 6, 7)) - eq(5, hm.prev_word_boundary("abc efg", 7, 7)) + 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)) + + 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)) - eq(9, hm.prev_word_boundary("slighly more complex test", 10, 22)) - eq(9, hm.prev_word_boundary("slighly more complex test", 11, 22)) - eq(14, hm.prev_word_boundary("slighly more complex test", 15, 22)) - eq(14, hm.prev_word_boundary("slighly more complex test", 16, 22)) - eq(22, hm.prev_word_boundary("slighly more complex test", 23, 22)) - eq(22, hm.prev_word_boundary("slighly more complex test", 24, 22)) - eq(22, hm.prev_word_boundary("slighly more complex test", 25, 22)) - eq(0, hm.prev_word_boundary("slighly more complex test", 1, 22)) + 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)) + end) - eq(0, hm.prev_word_boundary(" myFunction(example, stuff)", 1, 30)) - eq(0, hm.prev_word_boundary(" myFunction(example, stuff)", 2, 30)) - eq(0, hm.prev_word_boundary(" myFunction(example, stuff)", 3, 30)) - eq(0, hm.prev_word_boundary(" myFunction(example, stuff)", 4, 30)) - eq(0, hm.prev_word_boundary(" myFunction(example, stuff)", 5, 30)) - eq(5, hm.prev_word_boundary(" myFunction(example, stuff)", 6, 30)) - eq(5, hm.prev_word_boundary(" myFunction(example, stuff)", 15, 30)) - eq(15, hm.prev_word_boundary(" myFunction(example, stuff)", 16, 30)) - eq(16, hm.prev_word_boundary(" myFunction(example, stuff)", 17, 30)) - eq(16, hm.prev_word_boundary(" myFunction(example, stuff)", 18, 30)) - eq(16, hm.prev_word_boundary(" myFunction(example, stuff)", 19, 30)) - eq(23, hm.prev_word_boundary(" myFunction(example, stuff)", 25, 30)) - eq(25, hm.prev_word_boundary(" myFunction(example, stuff)", 26, 30)) - eq(25, hm.prev_word_boundary(" myFunction(example, stuff)", 27, 30)) - eq(25, hm.prev_word_boundary(" myFunction(example, stuff)", 28, 30)) - eq(25, hm.prev_word_boundary(" myFunction(example, stuff)", 29, 30)) - eq(25, hm.prev_word_boundary(" myFunction(example, stuff)", 30, 30)) + 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)) end) it("can walk string with b", function() local test_string = "abcdefg hijklmn opqrstu vwxyz" - local pos = hm.prev_word_boundary(test_string, 29, #test_string) + local pos = hm.prev_word_boundary(test_string, 29, #test_string, false) if pos == 0 then error("pos is 0") end eq("v", test_string:sub(pos, pos)) - pos = hm.prev_word_boundary(test_string, pos, #test_string) + pos = hm.prev_word_boundary(test_string, pos, #test_string, false) if pos == 0 then error("pos is 0") end eq("o", test_string:sub(pos, pos)) - pos = hm.prev_word_boundary(test_string, pos, #test_string) + pos = hm.prev_word_boundary(test_string, pos, #test_string, false) if pos == 0 then error("pos is 0") end eq("h", test_string:sub(pos, pos)) - pos = hm.prev_word_boundary(test_string, pos, #test_string) + pos = hm.prev_word_boundary(test_string, pos, #test_string, false) eq(1, pos) end) end) describe("end of current word", function() it("finds the end of words", function() - eq(3, hm.end_of_word("abc efg", 1, 7)) - eq(3, hm.end_of_word("abc efg", 2, 7)) - eq(7, hm.end_of_word("abc efg", 3, 7)) + 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)) + + 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)) - eq(7, hm.end_of_word("slighly more complex test", 1, 25)) - eq(7, hm.end_of_word("slighly more complex test", 2, 25)) - eq(12, hm.end_of_word("slighly more complex test", 10, 25)) - eq(20, hm.end_of_word("slighly more complex test", 13, 25)) - eq(20, hm.end_of_word("slighly more complex test", 15, 25)) - eq(25, hm.end_of_word("slighly more complex test", 21, 25)) + 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)) + end) - eq(14, hm.end_of_word(" myFunction(example, stuff)", 1, 30)) - eq(14, hm.end_of_word(" myFunction(example, stuff)", 2, 30)) - eq(14, hm.end_of_word(" myFunction(example, stuff)", 3, 30)) - eq(14, hm.end_of_word(" myFunction(example, stuff)", 5, 30)) - eq(15, hm.end_of_word(" myFunction(example, stuff)", 14, 30)) - eq(22, hm.end_of_word(" myFunction(example, stuff)", 15, 30)) - eq(22, hm.end_of_word(" myFunction(example, stuff)", 16, 30)) - eq(29, hm.end_of_word(" myFunction(example, stuff)", 23, 30)) - eq(29, hm.end_of_word(" myFunction(example, stuff)", 24, 30)) - eq(29, hm.end_of_word(" myFunction(example, stuff)", 25, 30)) - eq(30, hm.end_of_word(" myFunction(example, stuff)", 29, 30)) - eq(0, hm.end_of_word(" myFunction(example, stuff)", 30, 30)) + it("finds the end of the current big word", function() + eq(10, hm.end_of_word("a big.word string", 3, 17, true)) end) end) end) @@ -233,41 +247,41 @@ end) describe("edge case", function() it("can handle empty strings", function() - eq(0, hm.next_word_boundary("", 1, 0)) - eq(0, hm.prev_word_boundary("", 1, 0)) - eq(0, hm.end_of_word("", 1, 0)) + eq(0, hm.next_word_boundary("", 1, 0, false)) + eq(0, hm.prev_word_boundary("", 1, 0, false)) + eq(0, hm.end_of_word("", 1, 0, false)) end) it("can handle strings with only whitespace", function() - eq(0, hm.next_word_boundary(" ", 1, 1)) - eq(0, hm.prev_word_boundary(" ", 1, 1)) - eq(0, hm.end_of_word(" ", 1, 1)) + eq(0, hm.next_word_boundary(" ", 1, 1, false)) + eq(0, hm.prev_word_boundary(" ", 1, 1, false)) + eq(0, hm.end_of_word(" ", 1, 1, false)) end) it("can handle strings with special characters in the middle", function() local str = "vim.keymap.set('n', 't;', ':Test')" - eq(5, hm.next_word_boundary(str, 4, #str)) - eq(1, hm.prev_word_boundary(str, 4, #str)) - eq(10, hm.end_of_word(str, 4, #str)) + eq(5, hm.next_word_boundary(str, 4, #str, false)) + eq(1, hm.prev_word_boundary(str, 4, #str, false)) + eq(10, hm.end_of_word(str, 4, #str, false)) end) it("can handle strings with multiple consecutive special characters", function() local str = "this || that" - eq(9, hm.next_word_boundary(str, 6, #str)) - eq(1, hm.prev_word_boundary(str, 6, #str)) - eq(7, hm.end_of_word(str, 6, #str)) + eq(9, hm.next_word_boundary(str, 6, #str, false)) + eq(1, hm.prev_word_boundary(str, 6, #str, false)) + eq(7, hm.end_of_word(str, 6, #str, false)) end) it("strings with spaces at the end", function() local str = "there is a space " - eq(0, hm.end_of_word(str, 16, #str)) + eq(0, hm.end_of_word(str, 16, #str, false)) end) it("single character next word ends", function() local str = "show_something = true," - eq(14, hm.end_of_word(str, 1, #str)) - eq(16, hm.end_of_word(str, 14, #str)) - eq(16, hm.end_of_word(str, 15, #str)) - eq(22, hm.end_of_word(str, 21, #str)) + eq(14, hm.end_of_word(str, 1, #str, false)) + eq(16, hm.end_of_word(str, 14, #str, false)) + eq(16, hm.end_of_word(str, 15, #str, false)) + eq(22, hm.end_of_word(str, 21, #str, false)) end) end)