feat: allow users to configure the window keymaps #3

Merged
AdeAttwood merged 1 commit from mapping-config into 0.x 2024-12-14 11:38:57 +00:00
3 changed files with 81 additions and 51 deletions

View file

@ -76,6 +76,23 @@ require("ivy").setup {
-- default one. -- default one.
{ "ivy.backends.files", { keymap = "<C-p>" } }, { "ivy.backends.files", { keymap = "<C-p>" } },
}, },
-- Set mappings of your own, you can use the action `key` to define the
-- action you want.
mappings = {
["<CR>"] = "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" }, {
["<esc>"] = "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 and Key Map are the default options provided by the backend, they can be
customized when you register it. customized when you register it.
| Module | Command | Key Map | Description | | Module | Command | Default Key Map | Description |
| ------------------------------------ | ------------------ | ----------- | ----------------------------------------------------------- | | ------------------------------------ | ------------------ | --------------- | ----------------------------------------------------------- |
| `ivy.backends.files` | IvyFd | \<leader\>p | Find files in your project with a custom rust file finder | | `ivy.backends.files` | IvyFd | \<leader\>p | Find files in your project with a custom rust file finder |
| `ivy.backends.ag` | IvyAg | \<leader\>/ | Find content in files using the silver searcher | | `ivy.backends.ag` | IvyAg | \<leader\>/ | Find content in files using the silver searcher |
| `ivy.backends.rg` | IvyRg | \<leader\>/ | Find content in files using ripgrep cli tool | | `ivy.backends.rg` | IvyRg | \<leader\>/ | Find content in files using ripgrep cli tool |
| `ivy.backends.buffers` | IvyBuffers | \<leader\>b | Search though open buffers | | `ivy.backends.buffers` | IvyBuffers | \<leader\>b | Search though open buffers |
| `ivy.backends.lines` | IvyLines | | Search the lines in the current buffer | | `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 | | `ivy.backends.lsp-workspace-symbols` | IvyWorkspaceSymbol | | Search for workspace symbols using the lsp workspace/symbol |
### Actions ### Actions
Action can be run on selected candidates provide functionality Action can be run on selected candidates provide functionality
| Action | Key Map | Description | | Action | Key | Default Key Map | Description |
| ------------------- | --------- | ---------------------------------------------------------------- | | ------------------- | --------------------- | --------------- | ---------------------------------------------------------------- |
| Complete | \<CR\> | Run the completion function, usually this will be opening a file | | Complete | `complete` | \<CR\> | Run the completion function, usually this will be opening a file |
| Vertical Split | \<C-v\> | Run the completion function in a new vertical split | | Vertical Split | `vsplit` | \<C-v\> | Run the completion function in a new vertical split |
| Split | \<C-s\> | Run the completion function in a new split | | Split | `split` | \<C-s\> | Run the completion function in a new split |
| Destroy | \<C-c\> | Close the results window | | Destroy | `destroy` | \<C-c\> | Close the results window |
| Clear | \<C-u\> | Clear the results window | | Clear | `clear` | \<C-u\> | Clear the results window |
| Delete word | \<C-w\> | Delete the word under the cursor | | Delete word | `delete_word` | \<C-w\> | Delete the word under the cursor |
| Next | \<C-n\> | Move to the next candidate | | Next | `next` | \<C-n\> | Move to the next candidate |
| Previous | \<C-p\> | Move to the previous candidate | | Previous | `previous` | \<C-p\> | Move to the previous candidate |
| Next Checkpoint | \<C-M-n\> | Move to the next candidate and keep Ivy open and focussed | | Next Checkpoint | `next_checkpoint` | \<C-M-n\> | Move to the next candidate and keep Ivy open and focussed |
| Previous Checkpoint | \<C-M-n\> | Move to the previous candidate and keep Ivy open and focussed | | Previous Checkpoint | `previous_checkpoint` | \<C-M-n\> | 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",
"<esc>",
"<cmd>lua vim.ivy.destroy()<CR>",
{ noremap = true, silent = true, nowait = true }
)
```
## API ## API

View file

@ -28,6 +28,21 @@ config.default_config = {
"ivy.backends.rg", "ivy.backends.rg",
"ivy.backends.lsp-workspace-symbols", "ivy.backends.lsp-workspace-symbols",
}, },
mappings = {
["<C-c>"] = "destroy",
["<C-u>"] = "clear",
["<C-n>"] = "next",
["<C-p>"] = "previous",
["<C-M-n>"] = "next_checkpoint",
["<C-M-p>"] = "previous_checkpoint",
["<CR>"] = "complete",
["<C-v>"] = "vsplit",
["<C-s>"] = "split",
["<BS>"] = "backspace",
["<Left>"] = "left",
["<Right>"] = "right",
["<C-w>"] = "delete_word",
},
} }
return setmetatable(config, config_mt) return setmetatable(config, config_mt)

View file

@ -1,3 +1,5 @@
local config = require "ivy.config"
-- Constent options that will be used for the keymaps -- Constent options that will be used for the keymaps
local opts = { noremap = true, silent = true, nowait = true } local opts = { noremap = true, silent = true, nowait = true }
@ -37,6 +39,24 @@ local function call_gc(items)
end end
end end
local callbacks = {
destroy = "<cmd>lua vim.ivy.destroy()<CR>",
clear = "<cmd>lua vim.ivy.search('')<CR>",
next = "<cmd>lua vim.ivy.next()<CR>",
previous = "<cmd>lua vim.ivy.previous()<CR>",
next_checkpoint = "<cmd>lua vim.ivy.next(); vim.ivy.checkpoint()<CR>",
previous_checkpoint = "<cmd>lua vim.ivy.previous(); vim.ivy.checkpoint()<CR>",
complete = "<cmd>lua vim.ivy.complete(vim.ivy.action.EDIT)<CR>",
vsplit = "<cmd>lua vim.ivy.complete(vim.ivy.action.VSPLIT)<CR>",
split = "<cmd>lua vim.ivy.complete(vim.ivy.action.SPLIT)<CR>",
backspace = "<cmd>lua vim.ivy.input('BACKSPACE')<CR>",
left = "<cmd>lua vim.ivy.input('LEFT')<CR>",
right = "<cmd>lua vim.ivy.input('RIGHT')<CR>",
delete_word = "<cmd>lua vim.ivy.input('DELETE_WORD')<CR>",
}
local window = {} local window = {}
window.index = 0 window.index = 0
@ -75,25 +95,15 @@ window.make_buffer = function()
vim.api.nvim_buf_set_keymap(window.buffer, "n", chars[index], "<cmd>lua vim.ivy.input('" .. char .. "')<CR>", opts) vim.api.nvim_buf_set_keymap(window.buffer, "n", chars[index], "<cmd>lua vim.ivy.input('" .. char .. "')<CR>", opts)
end end
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<C-c>", "<cmd>lua vim.ivy.destroy()<CR>", opts) local mappings = config:get { "mappings" }
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<C-u>", "<cmd>lua vim.ivy.search('')<CR>", opts) assert(mappings, "The mappings key is missing from the config, something has gone horribly wrong")
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<C-n>", "<cmd>lua vim.ivy.next()<CR>", opts) for key, value in pairs(mappings) do
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<C-p>", "<cmd>lua vim.ivy.previous()<CR>", opts) if callbacks[value] == nil then
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<C-M-n>", "<cmd>lua vim.ivy.next(); vim.ivy.checkpoint()<CR>", opts) error("The mapping '" .. value .. "' is not a valid ivy callback")
vim.api.nvim_buf_set_keymap( end
window.buffer,
"n", vim.api.nvim_buf_set_keymap(window.buffer, "n", key, callbacks[value], opts)
"<C-M-p>", end
"<cmd>lua vim.ivy.previous(); vim.ivy.checkpoint()<CR>",
opts
)
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<CR>", "<cmd>lua vim.ivy.complete(vim.ivy.action.EDIT)<CR>", opts)
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<C-v>", "<cmd>lua vim.ivy.complete(vim.ivy.action.VSPLIT)<CR>", opts)
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<C-s>", "<cmd>lua vim.ivy.complete(vim.ivy.action.SPLIT)<CR>", opts)
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<BS>", "<cmd>lua vim.ivy.input('BACKSPACE')<CR>", opts)
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<Left>", "<cmd>lua vim.ivy.input('LEFT')<CR>", opts)
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<Right>", "<cmd>lua vim.ivy.input('RIGHT')<CR>", opts)
vim.api.nvim_buf_set_keymap(window.buffer, "n", "<C-w>", "<cmd>lua vim.ivy.input('DELETE_WORD')<CR>", opts)
end end
window.get_current_selection = function() window.get_current_selection = function()