diff --git a/README.md b/README.md index ee98400..f3b0ded 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,23 @@ require("ivy").setup { -- default one. { "ivy.backends.files", { keymap = "" } }, }, + -- Set mappings of your own, you can use the action `key` to define the + -- action you want. + mappings = { + [""] = "complete" + } +} +``` + +When defining config overrides in the setup function, this will overwrite any +default config, not merge it. To merge the configuration you can use the +`vim.tbl_extend` use the default configuration and add any extra. + +```lua +require("ivy").setup { + mappings = vim.tbl_extend("force", config:get { "mappings" }, { + [""] = "destroy", + }), } ``` @@ -129,43 +146,31 @@ show. It will also provide functionality when actions are taken. The Command and Key Map are the default options provided by the backend, they can be customized when you register it. -| Module | Command | Key Map | Description | -| ------------------------------------ | ------------------ | ----------- | ----------------------------------------------------------- | -| `ivy.backends.files` | IvyFd | \p | Find files in your project with a custom rust file finder | -| `ivy.backends.ag` | IvyAg | \/ | Find content in files using the silver searcher | -| `ivy.backends.rg` | IvyRg | \/ | Find content in files using ripgrep cli tool | -| `ivy.backends.buffers` | IvyBuffers | \b | Search though open buffers | -| `ivy.backends.lines` | IvyLines | | Search the lines in the current buffer | -| `ivy.backends.lsp-workspace-symbols` | IvyWorkspaceSymbol | | Search for workspace symbols using the lsp workspace/symbol | +| Module | Command | Default Key Map | Description | +| ------------------------------------ | ------------------ | --------------- | ----------------------------------------------------------- | +| `ivy.backends.files` | IvyFd | \p | Find files in your project with a custom rust file finder | +| `ivy.backends.ag` | IvyAg | \/ | Find content in files using the silver searcher | +| `ivy.backends.rg` | IvyRg | \/ | Find content in files using ripgrep cli tool | +| `ivy.backends.buffers` | IvyBuffers | \b | Search though open buffers | +| `ivy.backends.lines` | IvyLines | | Search the lines in the current buffer | +| `ivy.backends.lsp-workspace-symbols` | IvyWorkspaceSymbol | | Search for workspace symbols using the lsp workspace/symbol | ### Actions Action can be run on selected candidates provide functionality -| Action | Key Map | Description | -| ------------------- | --------- | ---------------------------------------------------------------- | -| Complete | \ | Run the completion function, usually this will be opening a file | -| Vertical Split | \ | Run the completion function in a new vertical split | -| Split | \ | Run the completion function in a new split | -| Destroy | \ | Close the results window | -| Clear | \ | Clear the results window | -| Delete word | \ | Delete the word under the cursor | -| Next | \ | Move to the next candidate | -| Previous | \ | Move to the previous candidate | -| Next Checkpoint | \ | Move to the next candidate and keep Ivy open and focussed | -| Previous Checkpoint | \ | Move to the previous candidate and keep Ivy open and focussed | - -Add your own keymaps for an action by adding a `ftplugin/ivy.lua` file in your config. -Just add a simple keymap like this: - -```lua -vim.api.nvim_set_keymap( - "n", - "", - "lua vim.ivy.destroy()", - { noremap = true, silent = true, nowait = true } -) -``` +| Action | Key | Default Key Map | Description | +| ------------------- | --------------------- | --------------- | ---------------------------------------------------------------- | +| Complete | `complete` | \ | Run the completion function, usually this will be opening a file | +| Vertical Split | `vsplit` | \ | Run the completion function in a new vertical split | +| Split | `split` | \ | Run the completion function in a new split | +| Destroy | `destroy` | \ | Close the results window | +| Clear | `clear` | \ | Clear the results window | +| Delete word | `delete_word` | \ | Delete the word under the cursor | +| Next | `next` | \ | Move to the next candidate | +| Previous | `previous` | \ | Move to the previous candidate | +| Next Checkpoint | `next_checkpoint` | \ | Move to the next candidate and keep Ivy open and focussed | +| Previous Checkpoint | `previous_checkpoint` | \ | Move to the previous candidate and keep Ivy open and focussed | ## API diff --git a/lua/ivy/config.lua b/lua/ivy/config.lua index 8ff1e6a..e8095b9 100644 --- a/lua/ivy/config.lua +++ b/lua/ivy/config.lua @@ -28,6 +28,21 @@ config.default_config = { "ivy.backends.rg", "ivy.backends.lsp-workspace-symbols", }, + mappings = { + [""] = "destroy", + [""] = "clear", + [""] = "next", + [""] = "previous", + [""] = "next_checkpoint", + [""] = "previous_checkpoint", + [""] = "complete", + [""] = "vsplit", + [""] = "split", + [""] = "backspace", + [""] = "left", + [""] = "right", + [""] = "delete_word", + }, } return setmetatable(config, config_mt) diff --git a/lua/ivy/window.lua b/lua/ivy/window.lua index 087e94b..276d366 100644 --- a/lua/ivy/window.lua +++ b/lua/ivy/window.lua @@ -1,3 +1,5 @@ +local config = require "ivy.config" + -- Constent options that will be used for the keymaps local opts = { noremap = true, silent = true, nowait = true } @@ -37,6 +39,24 @@ local function call_gc(items) end end +local callbacks = { + destroy = "lua vim.ivy.destroy()", + clear = "lua vim.ivy.search('')", + next = "lua vim.ivy.next()", + previous = "lua vim.ivy.previous()", + next_checkpoint = "lua vim.ivy.next(); vim.ivy.checkpoint()", + previous_checkpoint = "lua vim.ivy.previous(); vim.ivy.checkpoint()", + + complete = "lua vim.ivy.complete(vim.ivy.action.EDIT)", + vsplit = "lua vim.ivy.complete(vim.ivy.action.VSPLIT)", + split = "lua vim.ivy.complete(vim.ivy.action.SPLIT)", + + backspace = "lua vim.ivy.input('BACKSPACE')", + left = "lua vim.ivy.input('LEFT')", + right = "lua vim.ivy.input('RIGHT')", + delete_word = "lua vim.ivy.input('DELETE_WORD')", +} + local window = {} window.index = 0 @@ -75,25 +95,15 @@ window.make_buffer = function() vim.api.nvim_buf_set_keymap(window.buffer, "n", chars[index], "lua vim.ivy.input('" .. char .. "')", opts) end - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.destroy()", opts) - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.search('')", opts) - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.next()", opts) - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.previous()", opts) - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.next(); vim.ivy.checkpoint()", opts) - vim.api.nvim_buf_set_keymap( - window.buffer, - "n", - "", - "lua vim.ivy.previous(); vim.ivy.checkpoint()", - opts - ) - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.complete(vim.ivy.action.EDIT)", opts) - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.complete(vim.ivy.action.VSPLIT)", opts) - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.complete(vim.ivy.action.SPLIT)", opts) - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.input('BACKSPACE')", opts) - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.input('LEFT')", opts) - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.input('RIGHT')", opts) - vim.api.nvim_buf_set_keymap(window.buffer, "n", "", "lua vim.ivy.input('DELETE_WORD')", opts) + local mappings = config:get { "mappings" } + assert(mappings, "The mappings key is missing from the config, something has gone horribly wrong") + for key, value in pairs(mappings) do + if callbacks[value] == nil then + error("The mapping '" .. value .. "' is not a valid ivy callback") + end + + vim.api.nvim_buf_set_keymap(window.buffer, "n", key, callbacks[value], opts) + end end window.get_current_selection = function()