diff --git a/lua/ivy/prompt.lua b/lua/ivy/prompt.lua index f867d2e..b893ce1 100644 --- a/lua/ivy/prompt.lua +++ b/lua/ivy/prompt.lua @@ -1,60 +1,81 @@ -- The prefix that will be before the search text for the user local prompt_prefix = ">> " +-- Gets the suffix to delete from some text biased on what happens in a bash +-- prompt. If the text dose not end in a letter then the last word and all of +-- the tailing special characters will be returned. If the text dose end in a +-- letter then only the last word will be returned leaving the special +-- characters that are before the last word. For example +-- +-- `some word` -> `some ` +-- `some word` -> `some ` +-- `some word ` -> `some ` +local function get_delete_suffix(text) + if text:match "([A-Za-z]+)$" == nil then + return text:match "([A-Za-z]+[^A-Za-z]+)$" + end + + return text:match "([A-Za-z]+)$" +end + local prompt = {} prompt.suffix = "" prompt.value = "" prompt.text = function() return prompt.value .. prompt.suffix end + prompt.update = function() vim.api.nvim_echo({ { prompt_prefix, "None" }, { prompt.value:sub(1, -2), "None" }, { prompt.value:sub(-1, -1), "Underlined" }, { prompt.suffix, "None" }, }, false, {}) end prompt.input = function(char) if char == "BACKSPACE" then prompt.value = string.sub(prompt.value, 0, -2) elseif char == "LEFT" then if #prompt.value > 0 then prompt.suffix = prompt.value:sub(-1, -1) .. prompt.suffix prompt.value = prompt.value:sub(1, -2) end elseif char == "RIGHT" then if #prompt.suffix > 0 then prompt.value = prompt.value .. prompt.suffix:sub(1, 1) prompt.suffix = prompt.suffix:sub(2, -1) end elseif char == "DELETE_WORD" then - prompt.value = prompt.value:match "(.*)%s+.*$" - if prompt.value == nil then + local suffix = get_delete_suffix(prompt.value) + + if suffix == nil then prompt.value = "" + else + prompt.value = prompt.value:sub(1, #prompt.value - #suffix) end elseif char == "\\\\" then prompt.value = prompt.value .. "\\" else prompt.value = prompt.value .. char end prompt.update() end prompt.set = function(value) prompt.value = value prompt.suffix = "" prompt.update() end prompt.destroy = function() prompt.value = "" prompt.suffix = "" vim.notify "" end return prompt diff --git a/lua/ivy/prompt_test.lua b/lua/ivy/prompt_test.lua index a99680d..ee834b6 100644 --- a/lua/ivy/prompt_test.lua +++ b/lua/ivy/prompt_test.lua @@ -1,61 +1,94 @@ local prompt = require "ivy.prompt" local vim_mock = require "ivy.vim_mock" before_each(function() vim_mock.reset() prompt.destroy() end) -- Input a list of strings into the prompt local input = function(input_table) for index = 1, #input_table do prompt.input(input_table[index]) end end -- Asserts the prompt contains the correct value local assert_prompt = function(t, expected) local text = prompt.text() if text ~= expected then t.error("The prompt text should be '" .. expected .. "' found '" .. text .. "'") end end it("starts with empty text", function(t) if prompt.text() ~= "" then t.error "The prompt should start with empty text" end end) it("can input some text", function(t) input { "A", "d", "e" } assert_prompt(t, "Ade") end) it("can delete a char", function(t) input { "A", "d", "e", "BACKSPACE" } assert_prompt(t, "Ad") end) it("will reset the text", function(t) input { "A", "d", "e" } prompt.set "New" assert_prompt(t, "New") end) it("can move around the a word", function(t) input { "P", "r", "o", "p", "t", "LEFT", "LEFT", "LEFT", "RIGHT", "m" } assert_prompt(t, "Prompt") end) it("can delete a word", function(t) prompt.set "Ade Attwood" input { "DELETE_WORD" } - assert_prompt(t, "Ade") + assert_prompt(t, "Ade ") end) it("can delete a word in the middle", function(t) prompt.set "Ade middle A" input { "LEFT", "LEFT", "DELETE_WORD" } - assert_prompt(t, "Ade A") + assert_prompt(t, "Ade A") +end) + +it("will delete the space and the word if the last word is single space", function(t) + prompt.set "some.thing " + input { "DELETE_WORD" } + assert_prompt(t, "some.") end) + +it("will only delete one word from path", function(t) + prompt.set "some/nested/path" + input { "DELETE_WORD" } + assert_prompt(t, "some/nested/") +end) + +it("will delete tailing space", function(t) + prompt.set "word " + input { "DELETE_WORD" } + assert_prompt(t, "") +end) + +it("will leave a random space", function(t) + prompt.set "some word " + input { "DELETE_WORD" } + assert_prompt(t, "some ") +end) + +local special_characters = { ".", "/", "^" } +for _, char in ipairs(special_characters) do + it(string.format("will stop at a %s", char), function(t) + prompt.set(string.format("key%sValue", char)) + input { "DELETE_WORD" } + assert_prompt(t, string.format("key%s", char)) + end) +end