diff --git a/lua/hawtkeys/ts.lua b/lua/hawtkeys/ts.lua index 6ed552b..0075311 100644 --- a/lua/hawtkeys/ts.lua +++ b/lua/hawtkeys/ts.lua @@ -395,18 +395,31 @@ function M.get_all_keymaps() return returnKeymaps end ]] local keymaps = {} - local paths = get_runtime_path() - for _, path in ipairs(paths) do - if string.match(path, "%.config") then - local files = find_files(path) - for _, file in ipairs(files) do - local file_keymaps = find_maps_in_file(file) - for _, keymap in ipairs(file_keymaps) do - table.insert(keymaps, keymap) + + if M._testing then + local files = + find_files(vim.loop.cwd() .. "/tests/hawtkeys/example_configs") + for _, file in ipairs(files) do + local file_keymaps = find_maps_in_file(file) + for _, keymap in ipairs(file_keymaps) do + table.insert(keymaps, keymap) + end + end + else + local paths = get_runtime_path() + for _, path in ipairs(paths) do + if string.match(path, "%.config") then + local files = find_files(path) + for _, file in ipairs(files) do + local file_keymaps = find_maps_in_file(file) + for _, keymap in ipairs(file_keymaps) do + table.insert(keymaps, keymap) + end end end end end + local vimKeymaps = get_keymaps_from_vim() returnKeymaps = utils.merge_tables(keymaps, vimKeymaps) scannedFiles = {} diff --git a/lua/hawtkeys/ui.lua b/lua/hawtkeys/ui.lua index 7a8e44d..ae413de 100644 --- a/lua/hawtkeys/ui.lua +++ b/lua/hawtkeys/ui.lua @@ -1,13 +1,15 @@ local M = {} + local Hawtkeys = require("hawtkeys.score") local ShowAll = require("hawtkeys.show_all") local showDuplicates = require("hawtkeys.duplicates") -local ns = vim.api.nvim_create_namespace("hawtkeys") +local Namespace = vim.api.nvim_create_namespace("hawtkeys") local ResultWin local ResultBuf local SearchWin +local SearchBuf local prompt_extmark @@ -17,21 +19,25 @@ local function create_win(enter, opts) opts.win_options = nil local buf = vim.api.nvim_create_buf(false, true) + vim.bo[buf].bufhidden = "wipe" - local win = vim.api.nvim_open_win( - buf, - enter, - vim.tbl_deep_extend("keep", opts, { - relative = "editor", - anchor = "NW", - border = "single", - noautocmd = true, - col = (vim.o.columns / 2) - (opts.width / 2), - row = (vim.o.lines / 2) - (opts.height / 2), - footer_pos = opts.footer and "center", - title_pos = opts.title and "center", - }) - ) + local config = vim.tbl_deep_extend("keep", opts, { + relative = "editor", + anchor = "NW", + border = "single", + noautocmd = true, + col = (vim.o.columns / 2) - (opts.width / 2), + row = (vim.o.lines / 2) - (opts.height / 2), + footer_pos = opts.footer and "center", + title_pos = opts.title and "center", + }) + + if vim.fn.has("nvim-0.10") == 0 then + config.footer = nil + config.footer_pos = nil + end + + local win = vim.api.nvim_open_win(buf, enter, config) vim.api.nvim_create_autocmd("BufLeave", { buffer = buf, @@ -188,8 +194,7 @@ M.show = function() winhl = "Normal:NormalFloatNC", }, }) - local searchBuf - SearchWin, searchBuf = create_win(true, { + SearchWin, SearchBuf = create_win(true, { width = width, height = 1, row = (vim.o.lines / 2) - (height / 2) - 2, @@ -203,31 +208,33 @@ M.show = function() }, }) - local map_opts = { noremap = true, silent = true, buffer = searchBuf } + local map_opts = { noremap = true, silent = true, buffer = SearchBuf } vim.keymap.set({ "n", "i" }, "", M.hide, map_opts) --disallow new lines in searchBuf vim.keymap.set("i", "", "", map_opts) local function update_search_hint(text) if text == "" then - prompt_extmark = vim.api.nvim_buf_set_extmark(searchBuf, ns, 0, 0, { - id = prompt_extmark, - virt_text = { { "Type to search", "Comment" } }, - virt_text_pos = "inline", - }) + prompt_extmark = + vim.api.nvim_buf_set_extmark(SearchBuf, Namespace, 0, 0, { + id = prompt_extmark, + virt_text = { { "Type to search", "Comment" } }, + virt_text_pos = "overlay", + }) else - prompt_extmark = vim.api.nvim_buf_set_extmark(searchBuf, ns, 0, 0, { - id = prompt_extmark, - virt_text = { { "", "Comment" } }, - virt_text_pos = "inline", - }) + prompt_extmark = + vim.api.nvim_buf_set_extmark(SearchBuf, Namespace, 0, 0, { + id = prompt_extmark, + virt_text = { { "", "Comment" } }, + virt_text_pos = "overlay", + }) end end -- subscribe to changed text in searchBuf - vim.api.nvim_buf_attach(searchBuf, false, { + vim.api.nvim_buf_attach(SearchBuf, false, { on_lines = vim.schedule_wrap(function() - local text = vim.api.nvim_buf_get_lines(searchBuf, 0, 1, false)[1] + local text = vim.api.nvim_buf_get_lines(SearchBuf, 0, 1, false)[1] update_search_hint(text) @@ -241,7 +248,7 @@ M.show = function() }) update_search_hint("") - vim.api.nvim_command("startinsert") + vim.api.nvim_feedkeys("i", "n", false) end M.show_all = function() @@ -283,7 +290,7 @@ M.show_all = function() -1 ) -- mapping rhs as extmark so the cursor skips over it - vim.api.nvim_buf_set_extmark(ResultBuf, ns, i - 1, 0, { + vim.api.nvim_buf_set_extmark(ResultBuf, Namespace, i - 1, 0, { virt_lines = { { { l2, "Function" } } }, }) end @@ -320,4 +327,36 @@ M.hide = function() vim.api.nvim_command("stopinsert") end +-- This is for testing purposes, since we need to +-- access these variables from outside the module +-- but we don't want to expose them to the user +local state = { + ResultWin = function() + return ResultWin + end, + ResultBuf = function() + return ResultBuf + end, + SearchWin = function() + return SearchWin + end, + SearchBuf = function() + return SearchBuf + end, + Namespace = function() + return Namespace + end, + prompt_extmark = function() + return prompt_extmark + end, +} + +setmetatable(M, { + __index = function(_, k) + if state[k] then + return state[k]() + end + end, +}) + return M diff --git a/tests/hawtkeys/init_spec.lua b/tests/hawtkeys/init_spec.lua index c6cd05b..33d3924 100644 --- a/tests/hawtkeys/init_spec.lua +++ b/tests/hawtkeys/init_spec.lua @@ -71,6 +71,7 @@ describe("set up function", function() it("User commands should be available after setup", function() local commandspresetup = vim.api.nvim_get_commands({}) hawtkeys.setup({}) + local commandsPostSetup = vim.api.nvim_get_commands({}) -- Check that the commands are not present before setup for command, _ in ipairs(userCommands) do diff --git a/tests/hawtkeys/ui_spec.lua b/tests/hawtkeys/ui_spec.lua new file mode 100644 index 0000000..43a27c2 --- /dev/null +++ b/tests/hawtkeys/ui_spec.lua @@ -0,0 +1,119 @@ +local eq = assert.are.same + +local MiniTest = require("mini.test") + +---TODO: add search functionality tests (willothy) + +describe("ui", function() + local child = MiniTest.new_child_neovim() + local SearchBuf, SearchWin, ResultBuf, ResultWin, Namespace, prompt_extmark + + before_each(function() + child.restart({ "-u", "tests/minimal_init.lua" }) + child.lua([[require("hawtkeys").setup({})]]) + end) + + describe("search", function() + before_each(function() + child.lua([[require("hawtkeys.ui").show()]]) + SearchBuf, SearchWin, ResultBuf, ResultWin, Namespace, prompt_extmark = + unpack(child.lua([[ + local ui = require("hawtkeys.ui") + return { + ui.SearchBuf, + ui.SearchWin, + ui.ResultBuf, + ui.ResultWin, + ui.Namespace, + ui.prompt_extmark + } + ]])) + end) + + it("should show the search UI", function() + assert(child.api.nvim_buf_is_valid(SearchBuf)) + assert(child.api.nvim_win_is_valid(SearchWin)) + + assert(child.api.nvim_buf_is_valid(ResultBuf)) + assert(child.api.nvim_win_is_valid(ResultWin)) + + eq(SearchBuf, child.api.nvim_get_current_buf()) + eq(SearchWin, child.api.nvim_get_current_win()) + + local win_config = child.api.nvim_win_get_config(SearchWin) + eq("editor", win_config.relative) + end) + + it("starts in insert mode", function() + assert(child.api.nvim_buf_is_valid(SearchBuf)) + assert(child.api.nvim_win_is_valid(SearchWin)) + + eq(child.api.nvim_get_current_win(), SearchWin) + eq("i", child.api.nvim_get_mode().mode) + end) + + it("should show the hint extmark", function() + assert(SearchBuf) + assert(prompt_extmark) + assert(Namespace) + local extmark_info = child.api.nvim_buf_get_extmark_by_id( + SearchBuf, + Namespace, + prompt_extmark, + { details = true, hl_name = true } + ) + eq(extmark_info[3].virt_text_pos, "overlay") + eq(extmark_info[3].virt_text, { { "Type to search", "Comment" } }) + end) + end) + + describe("all", function() + before_each(function() + child.lua([[require("hawtkeys.ui").show_all()]]) + ResultBuf, ResultWin, Namespace = unpack(child.lua([[ + local ui = require("hawtkeys.ui") + return { + ui.ResultBuf, + ui.ResultWin, + ui.Namespace, + } + ]])) + end) + + it("should show the all UI", function() + assert(child.api.nvim_buf_is_valid(ResultBuf)) + assert(child.api.nvim_win_is_valid(ResultWin)) + + eq(child.api.nvim_get_current_buf(), ResultBuf) + eq(child.api.nvim_get_current_win(), ResultWin) + + local win_config = child.api.nvim_win_get_config(ResultWin) + eq(win_config.relative, "editor") + end) + end) + + describe("dupes", function() + before_each(function() + child.lua([[require("hawtkeys.ui").show_dupes()]]) + ResultBuf, ResultWin, Namespace = unpack(child.lua([[ + local ui = require("hawtkeys.ui") + return { + ui.ResultBuf, + ui.ResultWin, + ui.Namespace, + } + ]])) + end) + + it("should show the duplicates UI", function() + assert(child.api.nvim_buf_is_valid(ResultBuf)) + assert(child.api.nvim_win_is_valid(ResultWin)) + + eq(child.api.nvim_get_current_buf(), ResultBuf) + eq(child.api.nvim_get_current_win(), ResultWin) + + local win_config = child.api.nvim_win_get_config(ResultWin) + eq(win_config.relative, "editor") + end) + end) +end) diff --git a/tests/minimal_init.lua b/tests/minimal_init.lua index 075d7fd..5f7fab2 100644 --- a/tests/minimal_init.lua +++ b/tests/minimal_init.lua @@ -1,28 +1,54 @@ local plenary_dir = os.getenv("PLENARY_DIR") or "/tmp/plenary.nvim" local treesitter_dir = os.getenv("TREESITTER_DIR") or "/tmp/nvim-treesitter" local whichkey_dir = os.getenv("WHICHKEY_DIR") or "/tmp/which-key.nvim" -if vim.fn.isdirectory(plenary_dir) == 0 then - vim.fn.system({"git", "clone", "https://github.com/nvim-lua/plenary.nvim", plenary_dir}) +local mini_dir = os.getenv("MINI_DIR") or "/tmp/mini-test" +if vim.fn.isdirectory(plenary_dir) == 0 then + vim.fn.system({ + "git", + "clone", + "https://github.com/nvim-lua/plenary.nvim", + plenary_dir, + }) end -if vim.fn.isdirectory(treesitter_dir) == 0 then - vim.fn.system({"git", "clone", "https://github.com/nvim-treesitter/nvim-treesitter", treesitter_dir}) +if vim.fn.isdirectory(treesitter_dir) == 0 then + vim.fn.system({ + "git", + "clone", + "https://github.com/nvim-treesitter/nvim-treesitter", + treesitter_dir, + }) end -if vim.fn.isdirectory(whichkey_dir) == 0 then - vim.fn.system({"git", "clone", "https://github.com/folke/which-key.nvim", whichkey_dir}) +if vim.fn.isdirectory(whichkey_dir) == 0 then + vim.fn.system({ + "git", + "clone", + "https://github.com/folke/which-key.nvim", + whichkey_dir, + }) +end +if vim.fn.isdirectory(mini_dir) == 0 then + vim.fn.system({ + "git", + "clone", + "https://github.com/echasnovski/mini.test", + mini_dir, + }) end vim.opt.rtp:append(".") vim.opt.rtp:append(plenary_dir) vim.opt.rtp:append(treesitter_dir) vim.opt.rtp:append(whichkey_dir) +vim.opt.rtp:append(mini_dir) vim.cmd("runtime plugin/plenary.vim") vim.cmd("runtime plugin/treesitter.vim") -require("nvim-treesitter.configs").setup { - ensure_installed = "lua", - highlight = { - enable = true, - }, -} +require("nvim-treesitter.configs").setup({ + ensure_installed = "lua", + highlight = { + enable = true, + }, +}) vim.cmd("runtime plugin/which-key.vim") -require("which-key").setup {} +require("which-key").setup({}) require("plenary.busted") +require("mini.test").setup()