Skip to content

Commit

Permalink
🔖 Release v1.1 - Additional core features
Browse files Browse the repository at this point in the history
* ✨ Add buffer keymap option
* ✨ Add minimal version of lua function support
* 📝 Remove planned features list from README, referring to GH issues
* 🔥 Remove LuaDoc as it seems like no one implements it
* 🙈 Add gitignore
* 📝 Add docs for buffer keymaps
* ✨ Add multiple modes via longer mode strings
* 📝 Replace redundant neovim support bullet with grouping vp
* 📝 Add docs for multiple modes
* ✨ Enable `expr` bindings with lua rhs
* ✨ Add _ for empty mode and adapt docs
* 🎨 Use single quotes everywhere
* 📝 Remove helloworld function from doc example
* 📝 Add example for lua expr function
  • Loading branch information
LionC authored Sep 12, 2021
1 parent fbd999a commit b789d30
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 58 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
testdata/
78 changes: 51 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ and trees

- Modular, maintainable pure Lua way to define keymaps
- Written in a single file of ~100 lines
- Only supports `neovim`
- Supports mapping keys to Lua functions with `expr` support
- Allows grouping keymaps the way you think about them concisely

## Installation

Expand All @@ -29,11 +30,11 @@ call dein#add('LionC/nest.nvim')

## Quickstart Guide

The `nest` Lua module exposes an `applyKeymaps` function that can be called
any number of times with a list of (nested) keymaps to be set.
The `nest` Lua module exposes an `applyKeymaps` function that can be called any
number of times with a list of (nested) keymaps to be set.

Keymaps will default to `normal` mode, `noremap` and `silent` unless
overwritten. Overrides are inherited by nested keymaps.
Keymaps will default to global, normal (`n`) mode, `noremap` and `silent`
unless overwritten. Overrides are inherited by nested keymaps.

```lua
local nest = require('nest')
Expand All @@ -47,23 +48,24 @@ nest.applyKeymaps {
{ '<leader>', {
-- Prefix every nested keymap with f (meaning actually <leader>f here)
{ 'f', {
{ 'f', '<Cmd>Telescope find_files<CR>' },
{ 'f', '<cmd>Telescope find_files<cr>' },
-- This will actually map <leader>fl
{ 'l', '<Cmd>Telescope live_grep<CR>' },
{ 'l', '<cmd>Telescope live_grep<cr>' },
-- Prefix every nested keymap with g (meaning actually <leader>fg here)
{ 'g', {
{ 'b', '<Cmd>Telescope git_branches<CR>' },
{ 'b', '<cmd>Telescope git_branches<cr>' },
-- This will actually map <leader>fgc
{ 'c', '<Cmd>Telescope git_commits<CR>' },
{ 's', '<Cmd>Telescope git_status<CR>' },
{ 'c', '<cmd>Telescope git_commits<cr>' },
{ 's', '<cmd>Telescope git_status<cr>' },
}},
}},

-- Lua functions can be right side values instead of key sequences
{ 'l', {
{ 'c', '<Cmd>lua vim.lsp.buf.code_actions()<CR>' },
{ 'r', '<Cmd>lua vim.lsp.buf.rename()<CR>' },
{ 's', '<Cmd>lua vim.lsp.buf.signature_help()<CR>' },
{ 'h', '<Cmd>lua vim.lsp.buf.hover()<CR>' },
{ 'c', lua vim.lsp.buf.code_actions },
{ 'r', lua vim.lsp.buf.rename },
{ 's', lua vim.lsp.buf.signature_help },
{ 'h', lua vim.lsp.buf.hover },
}},
}},

Expand All @@ -73,17 +75,22 @@ nest.applyKeymaps {

-- Set <expr> option for all nested keymaps
{ options = { expr = true }, {
{ "<CR>", "compe#confirm('<CR>')" },
-- This is equivalent to viml `inoremap <C-Space> <expr>compe#complete()`
{ "<C-Space>", "compe#complete()" },
{ '<cr>', 'compe#confirm("<CR>")' },
-- This is equivalent to viml `:inoremap <C-Space> <expr>compe#complete()`
{ '<C-Space>', 'compe#complete()' },
}},

{ '<C-', {
-- Buffer `true` sets keymaps only for the current buffer
{ '<C-', buffer = true, {
{ 'h>', '<left>' },
{ 'l>', '<right>' },
{ 'o>', '<Esc>o' },
-- You can also set bindings for a specific buffer
{ 'o>', '<Esc>o', buffer = 2 },
}},
}},

-- Keymaps can be defined for multiple modes at once
{ 'H', '^', mode = 'nv' },
}
```

Expand Down Expand Up @@ -113,6 +120,7 @@ Defaults start out as
{
mode = 'n',
prefix = '',
buffer = false,
options = {
noremap = true,
silent = true,
Expand All @@ -125,7 +133,7 @@ Defaults start out as
### `nest.applyKeymaps`

Expects a `keymapConfig`, which is a table with at least two indexed properties
in one of the following three shapes:
in one of the following four shapes:

#### Keymap

Expand All @@ -136,6 +144,16 @@ in one of the following three shapes:
Sets a keymap, mapping the input sequence to the output sequence similiar to
the VimL `:*map` commands.

#### Lua Function Keymap

```lua
{ 'inputsequence', someLuaFunction }
```

Sets a keymap, mapping the input sequence to call the given lua function. Also
works when `expr` is set - just `return` a string from your function (e.g.
`'<cmd>echo "Hello"<cr>'`).

#### Config Subtree

```lua
Expand Down Expand Up @@ -163,10 +181,19 @@ to all containing sub-`keymapConfig`s:

#### `mode`

Sets the Vim mode for keymaps contained in the `keymapConfig`.
Sets the Vim mode(s) for keymaps contained in the `keymapConfig`.

Accepts a string with each char representing a mode. The modes follow the Vim
prefixes (`n` for normal, `i` for insert...) **except the special character `_`**, which
stands for the empty mode (`:map `). See `:help map-table` for a reference.

#### `buffer`

Determines whether binding are global or local to a buffer:

Accepts all values `nvim_set_keymap`s `mode` parameter accepts. See `:help
nvim_set_keymap`
- `false` means global
- `true` means current buffer
- A number means that specific buffer (see `:ls` for buffer numbering)

#### `options`

Expand All @@ -192,7 +219,4 @@ Sets a `string` prefix to be applied to all keymap inputs.

## Planned Features

- 1.1
- add optional `description`s to keymaps
- allow looking up custom keymaps via some command
- optional telescope integration
See issues and milestones
103 changes: 72 additions & 31 deletions lua/nest.lua
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
local module = {}

--- Defaults used for `applyKeymaps`
-- You can set these to override them. Defaults are:
--
-- @field mode string Mode for the keymaps. Defaults to `'n'`. See @see vim.api.nvim_set_keymap
-- @field prefix string Prefix being applied to **all** (left side) key sequences. Defaults to an empty string (no prefix)
-- @field options table Keymap options like `<buffer>` and `<silent>` as a table of booleans. Defaults to `{ noremap = true, silent = true }`. See @see vim.api.nvim_set_keymap
--- Defaults being applied to `applyKeymaps`
-- Can be modified to change defaults applied.
module.defaults = {
mode = "n",
prefix = "",
mode = 'n',
prefix = '',
buffer = false,
options = {
noremap = true,
silent = true,
},
}

local rhsFns = {}

module._callRhsFn = function(index)
rhsFns[index]()
end

module._getRhsExpr = function(index)
local keys = rhsFns[index]()

return vim.api.nvim_replace_termcodes(keys, true, true, true)
end

local function functionToRhs(func, expr)
table.insert(rhsFns, func)

local insertedIndex = #rhsFns

return expr
and 'v:lua.package.loaded.nest._getRhsExpr(' .. insertedIndex .. ')'
or '<cmd>lua package.loaded.nest._callRhsFn(' .. insertedIndex .. ')<cr>'
end

local function copy(table)
local ret = {}

Expand All @@ -38,41 +57,39 @@ end
local function mergeOptions(left, right)
local ret = copy(left)

if (right == nil) then
if right == nil then
return ret
end

if (right.mode ~= nil) then
if right.mode ~= nil then
ret.mode = right.mode
end

if (right.prefix ~= nil) then
if right.buffer ~= nil then
ret.buffer = right.buffer
end

if right.prefix ~= nil then
ret.prefix = ret.prefix .. right.prefix
end

if (right.options ~= nil) then
if right.options ~= nil then
ret.options = mergeTables(ret.options, right.options)
end

return ret
end

--- Applies the given keymaps using the current `defaults`
-- Keymaps can be passed as a list of configs, with each config
-- being one of three options:
--
-- 1. A pair of strings
-- 2. A pair of a string and another config
-- 3. A new list of configs
--
-- with each having optional properties to override the current `defaults`.
--- Applies the given `keymapConfig`, creating nvim keymaps
module.applyKeymaps = function (config, presets)
local presets = presets or module.defaults
local mergedPresets = mergeOptions(presets, config)
local mergedPresets = mergeOptions(
presets or module.defaults,
config
)

local first = config[1]

if(type(first) == "table") then
if type(first) == 'table' then
for _, it in ipairs(config) do
module.applyKeymaps(it, mergedPresets)
end
Expand All @@ -84,18 +101,42 @@ module.applyKeymaps = function (config, presets)

mergedPresets.prefix = mergedPresets.prefix .. first

if(type(second) == "table") then
if type(second) == 'table' then
module.applyKeymaps(second, mergedPresets)

return
end

vim.api.nvim_set_keymap(
mergedPresets.mode,
mergedPresets.prefix,
second,
mergedPresets.options
)
local rhs = type(second) == 'function'
and functionToRhs(second, mergedPresets.options.expr)
or second

for mode in string.gmatch(mergedPresets.mode, '.') do
local sanitizedMode = mode == '_'
and ''
or mode

if mergedPresets.buffer then
local buffer = (mergedPresets.buffer == true)
and 0
or mergedPresets.buffer

vim.api.nvim_buf_set_keymap(
buffer,
sanitizedMode,
mergedPresets.prefix,
rhs,
mergedPresets.options
)
else
vim.api.nvim_set_keymap(
sanitizedMode,
mergedPresets.prefix,
rhs,
mergedPresets.options
)
end
end
end

return module

0 comments on commit b789d30

Please sign in to comment.