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:
parent
478c623268
commit
aa49be08cb
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue