From 6b43b810c303bcb20d5f12d09ff0a3c6a3a70c5b Mon Sep 17 00:00:00 2001 From: rootiest Date: Wed, 28 Aug 2024 06:34:45 -0400 Subject: [PATCH] feat: introduce floating command window with history navigation --- lua/config/rootiest.lua | 13 ++++ lua/utils/cmd_window.lua | 138 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 lua/utils/cmd_window.lua diff --git a/lua/config/rootiest.lua b/lua/config/rootiest.lua index 791c8e1..7f4381e 100644 --- a/lua/config/rootiest.lua +++ b/lua/config/rootiest.lua @@ -158,7 +158,20 @@ end function M.setup() M.eval_neovide() M.define_commands() + + -- Setup types data require("data.types").setup() + + -- ━━━━━━━━━━━━━━━━━━━━━━━━━ Rootiest cmd window ━━━━━━━━━━━━━━━━━━━━━━━━━ + -- + -- Setup Rootiest cmd window utility + require("utils.cmd_window").setup() + + -- Setup Rootiest cmd window (override default command-line behavior) + -- require("utils.cmd_window").setup({ override_cmdline = true }) + + -- Setup indentor + require("utils.indentor") end return M diff --git a/lua/utils/cmd_window.lua b/lua/utils/cmd_window.lua new file mode 100644 index 0000000..07bfa9a --- /dev/null +++ b/lua/utils/cmd_window.lua @@ -0,0 +1,138 @@ +-- ╭─────────────────────────────────────────────────────────╮ +-- │ Rootiest Command Window │ +-- ╰─────────────────────────────────────────────────────────╯ + +local M = {} + +function M.open_floating_window_with_completion() + local buf = vim.api.nvim_create_buf(false, true) -- Create a new buffer + local win_height = 1 -- Height of floating window + local win_width = math.floor(vim.o.columns * 0.25) -- Width of floating window + local row = math.floor((vim.o.lines - win_height) / 2) -- Position row + local col = math.floor((vim.o.columns - win_width) / 2) -- Position column + local win_border = "rounded" + + -- Create a floating window + local win = vim.api.nvim_open_win(buf, true, { + relative = "editor", + width = win_width, + height = win_height, + col = col, + row = row, + border = win_border, + }) + + -- Set the buffer's filetype + vim.bo[buf].filetype = "cmdline" -- Set a unique filetype + + -- Variables to manage history + _G.history_index = 0 + _G.history_size = vim.fn.histnr("cmd") + + -- Function to close the window + _G.close_window = function() + vim.api.nvim_win_close(win, true) -- Close the window + -- Switch back to normal mode + vim.api.nvim_command("stopinsert") + end + + -- Function to execute the command + _G.execute_command = function() + local cmd = vim.api.nvim_buf_get_lines(buf, 0, -1, false)[1] or "" + -- Ensure abbreviation expansion + vim.api.nvim_command("execute 'silent! " .. cmd .. "'") + close_window() + end + + -- Function to handle navigation and clear buffer + _G.handle_history_navigation = function(direction) + -- Update history index + _G.history_index = (_G.history_index + direction) % _G.history_size + if _G.history_index < 0 then + _G.history_index = _G.history_size - 1 + end + + -- Clear the buffer + vim.api.nvim_buf_set_lines(buf, 0, -1, false, {}) + + -- Fetch history item and insert into buffer + local history_cmd = vim.fn["histget"]("cmd", _G.history_index + 1) + vim.api.nvim_buf_set_lines(buf, 0, -1, false, { history_cmd or "" }) + vim.api.nvim_win_set_cursor(win, { 1, #history_cmd or 0 }) + end + + -- Setup keymaps for buffer + -- Map to execute the command + vim.api.nvim_buf_set_keymap( + buf, + "i", + "", + [[lua execute_command()]], + { noremap = true, silent = true } + ) + -- Map to close the window + vim.api.nvim_buf_set_keymap( + buf, + "i", + "", + [[lua close_window()]], + { noremap = true, silent = true } + ) + -- Map to navigate command history + vim.api.nvim_buf_set_keymap( + buf, + "i", + "", + [[lua handle_history_navigation(-1)]], + { noremap = true, silent = true } + ) + -- Map to navigate command history + vim.api.nvim_buf_set_keymap( + buf, + "i", + "", + [[lua handle_history_navigation(1)]], + { noremap = true, silent = true } + ) + -- Map to navigate command history + vim.api.nvim_buf_set_keymap( + buf, + "i", + "", + [[lua handle_history_navigation(1)]], + { noremap = true, silent = true } + ) + -- Map to navigate command history + vim.api.nvim_buf_set_keymap( + buf, + "i", + "", + [[lua handle_history_navigation(-1)]], + { noremap = true, silent = true } + ) + + -- Start in insert mode + vim.api.nvim_command("startinsert") +end + +M.setup = function(opts) + opts = opts or {} + + -- Add a user command to open the floating window + vim.api.nvim_create_user_command( + "FloatingWindowWithCompletion", + M.open_floating_window_with_completion, + {} + ) + + -- Optionally override default command-line behavior + if opts.override_cmdline then + require("data").func.add_keymap( + ":", + "lua require('utils.cmd_window').open_floating_window_with_completion()", + "FloatingWindowWithCompletion" + ) + end +end + +return M