nvim: refactor psoxizsh.key

We remove the old bind.lua functionality for creating recursive auto
initialized groups of bindings, replacing it with a simpler data
structure that only provides a common, simple mechanism for storing all
the information needed to make a new key bind in the future.

This change is good for two reasons:

1. the luals LSP can now provide autocompletion for keybinds
2. the module is much simpler, and can be extended easily to map the
   existing data structure into other formats, like the one used by
   lazy.nvim's keys map, or Neovim's own vim.keymap.set

We also update, refactor and rename the old map.lua file to binds.lua,
so that we remain consistent in our terminology with Neovim itself

Lastly, we touch up key/init.lua to handle these changes, and make it
easier for others to potentially create their own keybinds
This commit is contained in:
Paul Stemmet 2024-08-14 14:38:39 +00:00
parent 478c623268
commit aa49be08cb
Signed by: Paul Stemmet
GPG Key ID: EDEA539F594E7E75
5 changed files with 246 additions and 461 deletions

View File

@ -1,297 +0,0 @@
local M = {}
---@class BindOptions
---@field noremap boolean Defaults to true
---@field silent boolean Defaults to true
---@field mode 'n'|'i'|'v'|'c' Mode of the bind, n=Normal, i=Insert, etc
---@field prefix string|nil A prefix that is appended to the bind key (for example: '<Leader>')
---@field skip boolean|nil Should this bind be skipped silently when `Bind.register/2` is called?
--- A key bind.
---
--- Each Bind object represents a single key binding that can be registered with Neovim.
---@class Bind
---
---@field __struct "BindKey" Class identifier
---@field label string|nil Description of the keybind
---@field key string|nil Key that will be bound -- though this may be modified by `self.opts.prefix`
---@field action string|function|nil Action to bind to `self.key`. May be a string, which will be interpreted as vimscript or a lua function
---@field opts BindOptions
---@field new fun(self: Bind, opts: BindOptions?): Bind Create a new key bind
---@field update fun(self: Bind, updates: BindOptions?): Bind Update this Bind with new options
---@field register fun(self: Bind, ephemeral: BindOptions?): nil Register this Bind with Neovim
---
---@operator call(BindOptions):Bind See `Bind.update/2`
local Bind = {
opts = { noremap = true, silent = true, mode = 'n', prefix = nil },
__struct = 'BindKey',
}
setmetatable(Bind, {
__call = function(self, opts) return self:update(opts) end
})
--- A group of key Binds.
---
--- Groups are inherently composable, and any group may add a sub group simply
--- by indexing the parent object. Groups created in such a way will automatically
--- inherit parent options, and add them to any Binds created on that Group.
---
---@class BindGroup
---@field __struct "BindGroup" Class identifier
---@field __children table<string, BindGroup|Bind> Subgroups and/or Binds that are direct children of this BindGroup
---@field __opts BindOptions Options to apply to child BindGroup/Binds
---@field new fun(self: BindGroup, opts: BindOptions?): BindGroup Create a new BindGroup
---@field options fun(self: BindGroup, opts: BindOptions?): BindGroup Update this BindGroup with the provided opts
---@field register fun(self: BindGroup, ephemeral: BindOptions?): nil Recursively register all child Binds
---@operator call(table<string, Bind|BindGroup|BindOptions>?): BindGroup
local Group = {
__children = {},
__opts = {},
__struct = 'BindGroup',
}
setmetatable(Group, {
---Group.__index meta method
---@param self BindGroup
---@param name string
---@return BindGroup
__index = function(self, name)
if not self.__children[name] then
self:child(name, self:new())
end
return self.__children[name]
end,
__newindex = function(self, name, new)
local t = type(new) == 'table' and new.__struct or nil
if t and t == Group.__struct or t == Bind.__struct then
-- We rely on public behavior here (__call meta method)
-- should perhaps refactor the logic out of that and directly
-- call it here
self { [name] = new }
else
rawset(self, name, new)
end
end,
---Group.__call meta method
---@param self BindGroup
---@param new table<string, Bind|BindGroup|BindOptions>
---@return BindGroup
__call = function(self, new)
local opts = new[1] and new[1] or {}
new[1] = nil
self.__opts = vim.tbl_extend('force', self.__opts, new[1] or {})
for name, entry in pairs(new) do
if entry.__struct == 'BindGroup' then
self:child(name, entry:options(opts, 'force'))
elseif entry.__struct == 'BindKey' then
self:child(name, entry:update(opts, 'force'))
else
self:child(name, Bind:new(opts):update(entry))
end
end
return self
end,
})
--- Create a new Group, inheriting the options from `self`
---@param self BindGroup
---@param opts BindOptions?
---@return BindGroup
function Group.new(self, opts)
local this = vim.tbl_extend('force',
vim.deepcopy(Group), { __opts = self.__opts }
)
setmetatable(this, getmetatable(Group))
return this:options(opts)
end
--- Update this Group with the provided `opts`
---@param self BindGroup
---@param opts BindOptions?
---@param mode nil|'force'|'keep'
---@return BindGroup
function Group.options(self, opts, mode)
self.opts = vim.tbl_extend(mode or 'keep', opts or {}, self.__opts)
return self
end
---Register all Binds below this Group, recursively iterating through any subgroups
---
--- Note that any options passed to this function *will not be persisted to the respective
--- Binds, and will only effect this register/2 call.
---@param self BindGroup
---@param ephemeral BindOptions?
---@return nil
function Group.register(self, ephemeral)
for _, entry in pairs(self.__children) do
local type = entry.__struct
if type and (type == 'BindKey' or type == 'BindGroup') then
entry:register(ephemeral)
end
end
end
--- [PRIVATE] Add a child to this Group, returning the child
---@param self BindGroup
---@param name string
---@param group Bind|BindGroup
---@return Bind|BindGroup
function Group.child(self, name, group)
self.__children[name] = group
return self.__children[name]
end
--- Create a new Bind, merging `self` and `opts` options
---@param self Bind
---@param opts BindOptions?
---@return Bind
function Bind.new(self, opts)
local this = vim.tbl_extend('force',
vim.deepcopy(Bind), { opts = self.opts }
)
setmetatable(this, getmetatable(Bind))
return this:update(opts)
end
--- Update this Bind with the provided updates
---
--- Note that this function modifies the given updates table, *consuming values*
---@param self Bind
---@param updates BindOptions?
---@param mode 'force'|'keep'|nil
---@return Bind
function Bind.update(self, updates, mode)
local u = updates or {}
if u.key then self.key = u.key u.key = nil end
if u.label then self.label = u.label u.label = nil end
if u.action then self.action = u.action u.action = nil end
self.opts = vim.tbl_extend(mode or 'keep', u, self.opts)
return self
end
--- Register this Bind with Neovim.
---
--- This function may be passed an ephemeral set of BindOptions, which are not
--- persisted but do apply to the registered bind
---
--- Calling this function may fail (though not raise) unless one of the following
--- is true:
---
--- 1. (key and action) =~ nil
--- 2. opts.skip == true
---@param self Bind
---@param ephemeral BindOptions
---@return Bind
function Bind.register(self, ephemeral)
self:do_register(ephemeral)
return self
end
--- [PRIVATE] Make arg map to pass to nvim api
---@param self Bind
---@param ephemeral BindOptions
---@return string|nil
---@return string|nil
---@return string|function|nil
---@return table<string, any>|nil
function Bind.make_keymap_args(self, ephemeral)
local key = self.key
local action, cmd = self.action, type(self.action) == 'string'
local opts = vim.tbl_extend('force',
vim.deepcopy(self.opts),
{ desc = self.label },
ephemeral or {}
)
local mode = opts.mode
opts.mode = nil
opts.skip = nil
if cmd and action:lower():sub(1, #'<plug>') == '<plug>' then
opts.noremap = false
end
if opts.prefix and #opts.prefix > 0 then
key = opts.prefix .. key
end
opts.prefix = nil
return mode, key, action, opts
end
--- [PRIVATE] Internal handler for registering key binds with Neovim
---@param self Bind
---@param ephemeral BindOptions
---@return nil
function Bind.do_register(self, ephemeral)
if self.opts.skip then return end
local mode, lhs, rhs, opts = self:make_keymap_args(ephemeral)
if not (mode and lhs and rhs) then
self:log(vim.log.levels.WARN, mode, lhs, rhs, opts.desc)
return
end
vim.keymap.set(mode, lhs, rhs, opts)
end
--- [PRIVATE] Log failures
---@param self Bind
---@param level any
---@param mode any
---@param lhs any
---@param rhs any
---@param label any
---@return nil
function Bind.log(self, level, mode, lhs, rhs, label)
local msg, fo = { 'Skipping keymap, invalid args!' }, { newline = '', indent = ' ' }
table.insert(msg, 'mode: ' .. vim.inspect(mode, fo))
table.insert(msg, 'label: ' .. vim.inspect(label, fo))
table.insert(msg, 'key: ' .. vim.inspect(lhs, fo))
table.insert(msg, 'action: ' .. vim.inspect(rhs, fo))
vim.notify(table.concat(msg, "\n"), level, { title = self.__struct })
end
--- Convenience wrapper around `Bind.new/2`, allowing callers to use
--- array like syntax for setting `Bind.{label,key,action}` options.
---
--- Examples:
---
--- -- Say hello when pressing 'p' in normal mode
--- MkBind { 'Description of this bind', 'p', 'echo Hello, World!' }
---
--- -- Create a insert mode bind of <Leader><C-q> to save and quit
--- MkBind { 'Fast Quit', '<C-q>', 'w | quitall', prefix = '<Leader>', mode = 'i', expr = true }
---
---@param opts { [1]: BindOptions.label?, [2]: BindOptions.key?, [3]: BindOptions.action? } | BindOptions
---@return Bind
local function mkbind(opts)
if opts[1] then opts.label = opts[1] opts[1] = nil end
if opts[2] then opts.key = opts[2] opts[2] = nil end
if opts[3] then opts.action = opts[3] opts[3] = nil end
return Bind:new(opts)
end
M.Bind = Bind:new()
M.Group = Group:new()
M.MkBind = mkbind
return M

View File

@ -0,0 +1,117 @@
local core = require 'psoxizsh.key.core'
---@alias PsoxizshKeyBinds psoxizsh.key.binds
---@class psoxizsh.key.binds
local M = {}
local B = core.mkbind
-- ############################
-- ## GLOBAL BINDINGS ##
-- ############################
M.Global = {
-- ############
-- ## Supers ##
-- ############
--
Super = {
FileBrowser = B { '<C-Left>' , '<cmd>Neotree toggle reveal position=left<CR>' , desc = 'Toggle File Browser' , } ,
FuzzySearch = B { '<C-Right>' , '<cmd>Telescope builtin<CR>' , desc = 'Activate Telescope fuzzy finder' , } ,
Terminal = B { '<C-Up>' , '<cmd>ToggleTerm<CR>' , desc = 'Open terminal in a float' , } ,
Diagnostics = B { '<C-Down>' , '<cmd>TroubleToggle<CR>' , desc = 'Open workspace diagnostics' , } ,
},
-- ##############
-- ## <Leader> ##
-- ##############
--
Format = B { '<Leader>F' , desc = 'Format selection or buffer' , } ,
OpenConfig = B { '<Leader>ve' , desc = 'Open user Neovim configuration files' , } ,
ReloadConfig = B { '<Leader>vs' , desc = 'Reload Neovim configuration' , } ,
ToggleGutter = B { '<Leader>N' , desc = 'Toggle Neovim gutter' , } ,
ToggleBuffers = B { '<Leader><Tab>' , desc = 'Open buffer list' , } ,
ToggleGitStatus = B { '<Leader>gs' , desc = 'Open Git status float' , } ,
-- ################
-- ## Navigation ##
-- ################
--
-- Tmux interplay
NavigateLeft = B { '<C-h>', desc = 'Navigate left one window' , } ,
NavigateDown = B { '<C-j>', desc = 'Navigate down one window' , } ,
NavigateUp = B { '<C-k>', desc = 'Navigate up one window' , } ,
NavigateRight = B { '<C-l>', desc = 'Navigate right one window' , } ,
--
-- Buffer movement
--
BufferNext = B { '<Tab>' , desc = 'Next buffer or tab' , } ,
BufferPrev = B { '<S-Tab>' , desc = 'Previous buffer or tab' , } ,
--
-- Diagnostics
--
DiagnosticNext = B { ']g' , desc = 'Next buffer diagnostic' , } ,
DiagnosticPrev = B { '[g' , desc = 'Previous buffer diagnostic' , } ,
-- #####################
-- ## Auto completion ##
-- #####################
--
AutoComplete = {
Trigger = B { '<C-Space>' , desc = 'Request completion at <cword>' , } ,
Abort = B { '<C-CR>' , desc = 'Abort active completion' , } ,
Confirm = B { '<CR>' , desc = 'Select active completion' , } ,
Next = B { '<Tab>' , desc = 'Next completion entry' , } ,
Prev = B { '<S-Tab>' , desc = 'Previous completion entry' , } ,
ScrollUp = B { '<PageUp>' , desc = 'Scroll up completion entry documentation' , } ,
ScrollDown = B { '<PageDown>' , desc = 'Scroll down completion entry documentation' , } ,
},
SudoWrite = B { 'w!!' , desc = 'Sudo write the current file' , mode = 'c' } ,
}
-- ############################
-- ## BUFFER BINDINGS ##
-- ############################
M.Buffer = {
-- ###################
-- ## LSP on_attach ##
-- ###################
--
Lsp = {
LspInfo = B { '<Leader>Ci' , desc = 'Language Server Information' , } ,
RenameSymbol = B { '<Leader>rn' , desc = 'Rename <cword>' , } ,
RenameFile = B { '<Leader>rF' , desc = 'Rename the current file' , } ,
ShowDocumentation = B { 'K' , desc = 'Display documentation of <cword>' , } ,
ShowSignature = B { '<Leader>K' , desc = 'Display function signature help of <cword>' , } ,
ShowReferences = B { '<Leader>Cr' , desc = 'Display all references to <cword>' , } ,
CodeAction = B { '<Leader>.' , desc = 'Request code actions for <cword>' , } ,
SourceAction = B { '<Leader>Ca' , desc = 'Request source actions for <cword>' , } ,
GotoDefinition = B { 'gd' , desc = 'Jump to definition of <cword>' , } ,
GotoTypeDefinition = B { 'gT' , desc = 'Jump to type definition of <cword>' , } ,
GotoImplementation = B { 'gI' , desc = 'Jump to implementation of <cword>' , } ,
GotoDeclaration = B { 'gD' , desc = 'Jump to declaration of <cword>' , } ,
CodelensDisplay = B { '<Leader>>' , desc = 'Refresh & Display Codelens' , } ,
CodelensRun = B { '<Leader>r>' , desc = 'Run Codelens at <cword>' , } ,
ReferenceNext = B { ']]' , desc = 'Next reference' , } ,
ReferencePrev = B { '[[' , desc = 'Previous reference' , } ,
},
}
-- ############################
-- ## PLUGIN BINDINGS ##
-- ############################
M.Plugin = {
-- ###################
-- ## dressing.nvim ##
-- ###################
--
Dressing = {
Close = B { '<Esc>' , desc = 'Close the input modal' , mode = 'i' , } ,
Confirm = B { '<CR>' , desc = 'Submit the current input' , mode = 'i' , } ,
Prev = B { '<Up>' , desc = 'Previous item in input history' , mode = 'i' , } ,
Next = B { '<Down>' , desc = 'Next item in input history' , mode = 'i' , } ,
},
}
return M

View File

@ -0,0 +1,118 @@
local M = {}
--- A key bind.
---
--- Each Bind object represents a single key binding that can be registered with Neovim.
---@class PsoxizshKeyBind
---
---@field __struct 'PsoxizshKeyBind' Class identifier
---@field Key string Key that will be bound
---@field Mode string|string[] Mode(s) of the keybind, defaults to 'n' if unset
---@field Desc string|nil Description of the keybind
---@field Action string|function|nil Action to bind to `self.key`. May be a string, which will be interpreted as vimscript or a lua function
---@field opts PsoxizshKeyBindOpts|nil Set of options for this keybind -- not all options will apply to all call sites
---@field as fun(self: PsoxizshKeyBind, args: { [1]: PsoxizshKeyAsType }|PsoxizshKeyArgs): table
---@field _as_lazy fun(self: PsoxizshKeyBind, overrides?: PsoxizshKeyArgs): LazyKeysSpec
--- A set of `vim.keymap.set` {opts}.
---
--- See :h vim.keymap.set and :h map-arguments for details
---@class PsoxizshKeyBindOpts
---
---@field noremap boolean|nil Defaults to true
---@field remap boolean|nil Opposite of noremap (overrides, if set)
---@field nowait boolean|nil Defaults to false
---@field silent boolean|nil Defaults to true
---@field script boolean|nil Defaults to false
---@field expr boolean|nil Defaults to false
---@field unique boolean|nil Defaults to false
---@field buffer number|nil Defaults to false
---@class PsoxizshNewKeyBindArgs
---
---@field [1] string|nil The key pattern to use, alternative to `self.key`
---@field [2] string|function|nil The action to take; if applicable, alternative to `self.action`
---@field key string|nil The key pattern to use
---@field action string|function|nil The action to take; if applicable
---@field desc string|nil The description for this key bind
---@field mode string|string[]|nil The mode(s) to apply this key bind in
---@alias PsoxizshKeyArgs PsoxizshNewKeyBindArgs|PsoxizshKeyBindOpts
---@alias PsoxizshKeyAsType 'lazy'
local Bind = {
__struct = 'PsoxizshKeyBind',
}
---Create a new PsoxizshKeyBind
---@param key string
---@param action string|function|nil
---@param desc string|nil
---@param mode string|string[]
---@param opts PsoxizshKeyBindOpts|nil
function Bind.new(key, action, desc, mode, opts)
local this = vim.deepcopy(Bind)
this.Key = key
this.Action = action
this.Desc = desc
this.Mode = mode
this.opts = opts
return this
end
---Convert this PsoxizshKeyBind into another key bind format `type`
---@param self PsoxizshKeyBind
---@param args { [1]: PsoxizshKeyAsType }|PsoxizshKeyArgs
---@return table
function Bind.as(self, args)
local type = table.remove(args, 1)
if type == 'lazy' then return self:_as_lazy(args) end
return {}
end
---Convert this PsoxizshKeyBind into a LazyKeysSpec
---@param self PsoxizshKeyBind
---@param overrides? PsoxizshKeyArgs
---@return LazyKeysSpec
function Bind._as_lazy(self, overrides)
local args = overrides or {}
local key = args.key or args[1] or self.Key ; args.key = nil ; args[1] = nil
local action = args.action or args[2] or self.Action ; args.action = nil ; args[2] = nil
local desc = args.desc or self.Desc ; args.desc = nil
local mode = args.mode or self.Mode ; args.mode = nil
if mode == 'n' then mode = nil end ---@diagnostic disable-line: cast-local-type
local opts = vim.tbl_extend('force', self.opts or {}, args)
return { key, action, desc = desc, mode = mode, unpack(opts) }
end
---Create a new @PsoxizshKeyBind from the provided `opts`
---@param opts PsoxizshNewKeyBindArgs|PsoxizshKeyBindOpts
---@return PsoxizshKeyBind|nil
function M.mkbind(opts)
local key = opts[1] or opts.key
local action = opts[2] or opts.action
local mode = opts.mode or 'n'
local kopts = {
noremap = opts.noremap,
remap = opts.remap,
nowait = opts.nowait,
silent = opts.silent,
script = opts.script,
expr = opts.expr,
unique = opts.unique,
buffer = opts.buffer,
}
if not key then return nil end
return Bind.new(key, action, opts.desc, mode, next(kopts) ~= nil and kopts or nil)
end
return M

View File

@ -1 +1,11 @@
return require 'psoxizsh.key.map'
local core, binds = require 'psoxizsh.key.core', require 'psoxizsh.key.binds'
---@class psoxizsh.key
local M = {}
M.binds = binds
M.fn = {}
M.fn.mkbind = core.mkbind
return M

View File

@ -1,163 +0,0 @@
local bind = require 'psoxizsh.key.bind'
local G, B = bind.Group, bind.MkBind
local M = G:new()
-- ############################
-- ## NORMAL global bindings ##
-- ############################
M.Global.N {
{ mode = 'n' },
-- #####################
-- ## Leader Mappings ##
-- #####################
--
Leader = G {
{ prefix = '<Leader>' },
OpenConfig = B { 'Open user Neovim configuration files' , key = 've' , } ,
ReloadConfig = B { 'Reload Neovim configuration' , key = 'vs' , } ,
ToggleGutter = B { 'Toggle Neovim gutter' , key = 'N' , } ,
SpellWhiteList = B { 'Whitelist <cword> to [count] spellfile' , key = 'ss' , action = 'zg' , } ,
SpellBlackList = B { 'Blacklist <cword> to [count] spellfile' , key = 'sw' , action = 'zw' , } ,
SpellWhiteListUndo = B { 'Undo whitelist <cword> in [count] spellfile' , key = 'sus' , action = 'zug' , } ,
SpellBlackListUndo = B { 'Undo blacklist <cword> to [count] spellfile' , key = 'suw' , action = 'zuw' , } ,
ToggleBuffers = B { 'Open buffer list' , key = '<Tab>' , action = '<cmd>Neotree toggle reveal float source=buffers<CR>' , } ,
ToggleGitStatus = B { 'Open Git status float' , key = 'gs' , action = '<cmd>Neotree float git_status<CR>' , } ,
},
-- ############
-- ## Supers ##
-- ############
--
Super = G {
FileBrowser = B { 'Toggle File Browser' , key = '<C-Left>' , action = '<cmd>Neotree toggle reveal position=left<CR>' , } ,
FuzzySearch = B { 'Activate Telescope fuzzy finder' , key = '<C-Right>' , action = '<cmd>Telescope builtin<CR>' , } ,
Terminal = B { 'Open terminal in a float' , key = '<C-Up>' , action = '<cmd>ToggleTerm<CR>' , } ,
Diagnostics = B { 'Open workspace diagnostics' , key = '<C-Down>' , action = '<cmd>TroubleToggle<CR>' , } ,
},
-- ################
-- ## Navigation ##
-- ################
--
-- Tmux interplay
--
NavigateLeft = B { 'Navigate left one window' , key = '<C-h>', action = '<cmd>TmuxNavigateLeft<CR>' , } ,
NavigateDown = B { 'Navigate down one window' , key = '<C-j>', action = '<cmd>TmuxNavigateDown<CR>' , } ,
NavigateUp = B { 'Navigate up one window' , key = '<C-k>', action = '<cmd>TmuxNavigateUp<CR>' , } ,
NavigateRight = B { 'Navigate right one window' , key = '<C-l>', action = '<cmd>TmuxNavigateRight<CR>' , } ,
--
-- Buffer movement
--
BufferNext = B { 'Next buffer or tab' , key = '<Tab>' , action = '<cmd>BufferLineCycleNext<CR>' , } ,
BufferPrev = B { 'Previous buffer or tab' , key = '<S-Tab>' , action = '<cmd>BufferLineCyclePrev<CR>' , } ,
--
-- Diagnostics
--
DiagnosticNext = B { 'Next buffer diagnostic' , key = ']g' , } ,
DiagnosticPrev = B { 'Previous buffer diagnostic' , key = '[g' , } ,
}
-- #############################
-- ## COMMAND global bindings ##
-- #############################
M.Global.C {
{ mode = 'c' },
-- ####################
-- ## File utilities ##
-- ####################
--
SudoWrite = B { 'Sudo write the current file' , key = 'w!!', action = 'w !sudo tee % >/dev/null', } ,
}
-- ############################
-- ## INSERT global bindings ##
-- ############################
M.Global.I {
{ mode = 'i' },
-- #####################
-- ## Auto completion ##
-- #####################
--
Completion = G {
{ skip = true },
Confirm = B { 'Select the active completion entry and insert it' , key = '<C-Space>' , } ,
Next = B { 'Cycle selected completion item in completion menu' , key = '<Tab>' , } ,
Prev = B { 'Reverse cycle selected completion item in completion menu' , key = '<S-Tab>' , } ,
ScrollUp = B { 'Scroll up completion item documentation' , key = '<PageUp>' , } ,
ScrollDown = B { 'Scroll down completion item documentation' , key = '<PageDown>' , } ,
},
}
-- ############################
-- ## VISUAL global bindings ##
-- ############################
M.Global.V {
{ mode = 'v' },
Completion = M.Global.I.Completion:new({ mode = 'v' })
}
M.Buffer.N {
{ mode = 'n' },
CloseNetrw = B { 'Force close netrw windows', key = '<ESC>' }
}
-- ###################################
-- ## NORMAL LSP on_attach bindings ##
-- ###################################
M.Buffer.Lsp.N {
{ mode = 'n' },
-- #####################
-- ## Leader Mappings ##
-- #####################
--
Leader = G {
{ prefix = '<Leader>' },
-- ##################
-- ## LSP Mappings ##
-- ##################
--
RenameSymbol = B { 'Rename <cword> symbol' , key = 'rn' , action = vim.lsp.buf.rename , } ,
FormatDocument = B { 'Format current document' , key = 'F' , action = vim.lsp.buf.format , } ,
ShowSignature = B { 'Display function signature help of <cword> symbol' , key = 'K' , action = vim.lsp.buf.signature_help , } ,
CodeAction = B { 'Request code actions for <cword>' , key = '.' , action = vim.lsp.buf.code_action , } ,
},
-- ##################
-- ## LSP Mappings ##
-- ##################
--
GotoDefinition = B { 'Jump to definition of <cword> symbol' , key = 'gd' , action = vim.lsp.buf.definition , } ,
ShowDocumentation = B { 'Display documentation of <cword> symbol' , key = 'K' , action = vim.lsp.buf.hover , } ,
}
-- ###################################
-- ## PLUGIN dressing.nvim Mappings ##
-- ###################################
M.Plugin.Dressing {
Input = G {
{ mode = 'i', skip = true },
Close = B { 'Close the input modal' , key = '<Esc>' , } ,
Confirm = B { 'Submit the current input' , key = '<CR>' , } ,
Prev = B { 'Previous item in input history' , key = '<Up>' , } ,
Next = B { 'Next item in input history' , key = '<Down>' , } ,
}
}
return M