Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/b0o/mapx.nvim

🗺 A better way to create key mappings in Neovim
https://github.com/b0o/mapx.nvim

lua neovim neovim-configuration neovim-lua neovim-lua-plugin nvim vim vim-configuration

Last synced: about 1 month ago
JSON representation

🗺 A better way to create key mappings in Neovim

Awesome Lists containing this project

README

        

# Mapx.nvim [![version](https://img.shields.io/github/v/tag/b0o/mapx.nvim?style=flat&color=yellow&label=version&sort=semver)](https://github.com/b0o/mapx.nvim/releases) [![license: MIT](https://img.shields.io/github/license/b0o/mapx.nvim?style=flat&color=green)](https://mit-license.org) [![Build Status](https://img.shields.io/github/workflow/status/b0o/mapx.nvim/test)](https://github.com/b0o/mapx.nvim/actions/workflows/test.yaml)

A Neovim Lua plugin to make mapping and commands more manageable.

Mapx.nvim is a Lua library that mimics Vim's `:map` and `:command` family of
commands.
Its aim is to make configuring key mappings and commands from within Lua more
ergonomic.

Without Mapx:

```lua
vim.api.nvim_set_keymap("n", "j", "v:count ? 'j' : 'gj'", { noremap = true, expr = true })
vim.api.nvim_set_keymap("n", "k", "v:count ? 'k' : 'gk'", { noremap = true, expr = true })

vim.api.nvim_set_keymap("n", "J", "5j", {})
vim.api.nvim_set_keymap("n", "K", "5k", {})

vim.api.nvim_set_keymap("i", "", [[pumvisible() ? "\" : "\"]], { noremap = true, silent = true, expr = true })
vim.api.nvim_set_keymap("i", "", [[pumvisible() ? "\" : "\"]], { noremap = true, silent = true, expr = true })

vim.api.nvim_set_keymap("", "", ":Commentary", { silent = true })

vim.cmd [[command -nargs=0 LspDiag lua vim.lsp.diagnostic.set_loclist()]]
```

With Mapx:

```lua
require'mapx'.setup{ global = true }

nnoremap("j", "v:count ? 'j' : 'gj'", "expr")
nnoremap("k", "v:count ? 'k' : 'gk'", "expr")

nmap("J", "5j")
nmap("K", "5k")

inoremap("", [[pumvisible() ? "\" : "\"]], "silent", "expr")
inoremap("", [[pumvisible() ? "\" : "\"]], "silent", "expr")

map("", ":Commentary", "silent")

cmd("LspDiag", function() vim.lsp.diagnostic.set_loclist() end, {nargs = 0})
```

## Features

Create multiple mappings to the same action in one shot:

```lua
nnoremap({"", "f"}, ":lua require('telescope.builtin').find_files()", "silent")
```

#### WhichKey Integration

Integrate with [which-key.nvim](https://github.com/folke/which-key.nvim) by
passing a label as the final argument:

```lua
local m = require'mapx'.setup{ global = true, whichkey = true }

nnoremap("gD", "lua vim.lsp.buf.declaration()", "silent", "LSP: Goto declaration")

-- Also supports setting WhichKey group names
m.nname("l", "LSP")
nnoremap("li", ":LspInfo", "LSP: Show LSP information")
nnoremap("lr", ":LspRestart", "LSP: Restart LSP")
nnoremap("ls", ":LspStart", "LSP: Start LSP")
nnoremap("lS", ":LspStop", "LSP: Stop LSP")
```

#### FileType Mappings

FileType mappings will be applied only to buffers with a matching filetype.

```lua
nnoremap("", [[:call search('\(\w\+(\w\+)\)', 's')]], "silent", { ft = "man" })
nnoremap("", [[:call search('\(\w\+(\w\+)\)', 'sb')]], "silent", { ft = "man" })
```

#### Groups

Mappings with common options can be grouped to reduce repetition.

```lua
mapx.group("silent", { ft = "man" }, function()
nnoremap("", [[:call search('\(\w\+(\w\+)\)', 's')]])
nnoremap("", [[:call search('\(\w\+(\w\+)\)', 'sb')]])
end)
```

#### Lua Function Mappings

The `{rhs}` of a mapping can be a Lua function.

```lua
map("hi", function() print("Hello!") end, "silent")

-- Expression maps work too:
nnoremap("j", function() return vim.v.count > 0 and "j" or "gj" end, "silent", "expr")
nnoremap("k", function() return vim.v.count > 0 and "k" or "gk" end, "silent", "expr")
```

#### Buffer Mappings

Mappings can be applied to the current buffer, or to a specific buffer.

```lua
-- Use the current buffer
nnoremap("", ":call man#get_page_from_cword('horizontal', v:count)", "silent", "buffer")

-- Use a specific buffer
nnoremap("", ":call man#get_page_from_cword('horizontal', v:count)", "silent", {
buffer = vim.api.nvim_win_get_buf(myWindowVariable)
})
```

#### Map Options

There are various ways to specify map options:

```lua
-- Lua tables
nnoremap ("j", "v:count ? 'j' : 'gj'", { silent = true, expr = true })

-- Multiple Lua tables
nnoremap ("j", "v:count ? 'j' : 'gj'", { silent = true }, { expr = true })

-- Mapx's exported convenience variables
nnoremap ("j", "v:count ? 'j' : 'gj'", mapx.silent, mapx.expr)

-- Strings
nnoremap ("j", "v:count ? 'j' : 'gj'", "silent", "expr")

-- Vim-style strings
nnoremap ("j", "v:count ? 'j' : 'gj'", "", "")
```

#### Global Functions

Adding the Mapx map functions to the global scope is opt-in.

```lua
local mapx = require'mapx'
mapx.nmap("J", "5j")
mapx.nmap("K", "5k")
```

#### Commands

Create commands easily with the `cmd` and `cmdbang` functions. The
`cmdbang` function only differs from the `cmd` function in that it creates
a function with a bang which overwrites a previously defined function with
the same name.

```lua
cmd("LspDiag",
function() vim.lsp.diagnostic.set_loclist() end,
{nargs = 0})
cmdbang("LspAddFolder",
function(opt) vim.lsp.buf.add_workspace_folder(opt.arguments[1]) end,
{nargs = 1, complete = 'file'})
cmdbang("LspRemFolder",
function(opt) vim.lsp.buf.remove_workspace_folder(opt.arguments[1]) end,
{nargs = 1, complete = 'file'})
```

#### Documentation

Mapx is fully documented. See [`:help mapx`](https://github.com/b0o/mapx.nvim/blob/main/doc/mapx.txt).

#### Autoconvert your Neovim-style mappings to Mapx

Mapx provides the ability to convert mappings that use Neovim's
`vim.api.nvim_set_keymap()`/`vim.api.nvim_buf_set_keymap()` functions to the
Mapx API.

See the [conversion documentation](https://github.com/b0o/mapx.nvim/blob/main/conversion.md) for instructions.

## Install

[Packer](https://github.com/wbthomason/packer.nvim):

```lua
use "b0o/mapx.nvim"
```

## Wishlist

Mapx aims to be the most powerful way to configure key mappings. To that end,
we'd like to include the following features in future versions:

- [ ] Autocommand mappings (a generalization of FileType mappings).
- [ ] VimL conversion tool.
- [ ] [Telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) integration.
- [x] API for creating user commands.
- [ ] API for creating user autocommands.
- [ ] Support passing mapping mode in opts.
- [ ] Support specifying multiple modes as a string like 'nvt'.
- [ ] Support specifying labels on groups which become which-key group names.
- [ ] Support progressively building up maps with groups, like:

```lua
mapx.group({ prefix = "t" }, "LSP", function()
mapx.group({ prefix = "g" }, "Goto", function()
nnoremap("d", "lua vim.lsp.buf.definition()", "Definition")
nnoremap("D", "lua vim.lsp.buf.declaration()", "Declaration")
nnoremap("i", "lua vim.lsp.buf.implementation()", "Implementation")
nnoremap("t", "lua vim.lsp.buf.type_definition()", "Type definition")
nnoremap("r", "lua vim.lsp.buf.references()", "References")
end)
mapx.group({ prefix = "w" }, "Workspace", function()
nnoremap("a", "lua vim.lsp.buf.add_workspace_folder()", "Add folder")
nnoremap("r", "lua vim.lsp.buf.remove_workspace_folder()", "Rm folder")
nnoremap("l", "lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))", "List folders")
end)
end)

-- Would be equivalent to:
mapx.nname("l", "LSP")
mapx.nname("lg", "LSP-Goto")
nnoremap ("lgd", "lua vim.lsp.buf.definition()", "LSP-Goto: Definition")
nnoremap ("lgD", "lua vim.lsp.buf.declaration()", "LSP-Goto: Declaration")
nnoremap ("lgi", "lua vim.lsp.buf.implementation()", "LSP-Goto: Implementation")
nnoremap ("lgt", "lua vim.lsp.buf.type_definition()", "LSP-Goto: Type definition")
nnoremap ("lgr", "lua vim.lsp.buf.references()", "LSP-Goto: References")
mapx.nname("lw", "LSP-Workspace")
nnoremap ("lwa", "lua vim.lsp.buf.add_workspace_folder()", "LSP-Workspace: Add folder")
nnoremap ("lwr", "lua vim.lsp.buf.remove_workspace_folder()", "LSP-Workspace: Rm folder")
nnoremap ("lwl", "lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))", "LSP-Workspace: List folders")
```

- [ ] Better test coverage
- [ ] Support setting default opts in `.setup{}`
- [ ] Benchmarks
- [ ] Performance optimization (especially WhichKey integration)

## Changelog

```
01 Nov 2021 v0.2.2
Added user command support

10 Sep 2021 v0.2.1
Renamed project to Mapx.nvim
Added tests
Added config auto-conversion tool
Fixed bugs

08 Sep 2021 v0.2.0
Breaking: Deprecated config.quiet in favor of `setup({global = "force"})`
or `setup({global = "skip"})`

08 Sep 2021 v0.1.2
Added support for assigning WhichKey group names
Allow wrapping string opts in
Refactored code
Bug fixes

04 Sep 2021 v0.1.1
Added `mapx.group()`
Added debug logging with `mapx-config-debug`
Added support for `mapx-opt-filetype` maps
Added support for Lua functions as a map's `{rhs}`
Added `mapx-config-quiet`
Fixed bugs

01 Sep 2021 v0.1.0
Added `mapx.setup()`
Added `mapx-whichkey-support`
Breaking: Deprecated `mapx.globalize()` in favor of `setup({global = true})`

28 Aug 2021 v0.0.2
Added `mapx.globalize()`

27 Aug 2021 v0.0.1
Initial Release
```

## License

© 2021 Maddison Hellstrom

Released under the MIT License.