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

https://github.com/abdul-hamid-achik/keymaps.nvim

Auto-detect and display all your Neovim keymaps in a beautiful, searchable cheatsheet
https://github.com/abdul-hamid-achik/keymaps.nvim

cheatsheet keymaps lua neovim neovim-plugin nvim telescope

Last synced: 3 days ago
JSON representation

Auto-detect and display all your Neovim keymaps in a beautiful, searchable cheatsheet

Awesome Lists containing this project

README

          


keymaps.nvim


Auto-detect and display all your Neovim keymaps in a beautiful, searchable cheatsheet


by Abdul Hamid Achik



Neovim


Lua


License: MIT


Features
Quick Start
Installation
Configuration
Commands
API

---

## Why keymaps.nvim?

Ever wondered "what was that keymap again?" or wanted to see all your keymaps in one place? **keymaps.nvim** automatically discovers every keymap in your Neovim config and presents them in a searchable, categorized cheatsheet.

- No manual registration required
- Works with any plugin's keymaps
- Knows which plugin defined each keymap
- Export to Markdown, HTML, or JSON for documentation

## ✨ Features

| Feature | Description |
|---------|-------------|
| **Auto-detection** | Scans all keymaps via `nvim_get_keymap()` across all modes (n, i, v, x, s, o, c, t) |
| **Vim Motions Built-in** | Includes 220+ Vim motions with descriptions (h/j/k/l, w/e/b, text objects, operators, and more) |
| **Smart Categorization** | Automatically groups keymaps into categories: LSP, Git, Navigation, Harpoon, Telescope, and more |
| **Source Detection** | Uses `debug.getinfo()` to identify which plugin defined each keymap |
| **Telescope Integration** | Beautiful fuzzy finder with preview (graceful fallback to floating window) |
| **Export** | Generate Markdown, interactive HTML, or JSON documentation |
| **Usage Tracking** | Track which keymaps you actually use and see statistics |
| **Auto-refresh** | Automatically updates when your config files change |
| **Zero Config** | Works out of the box with sensible defaults |

## 🎯 Built-in Vim Motions

keymaps.nvim includes **220+ Vim motions** with clear descriptions, so you get a complete reference alongside your custom keymaps:

| Category | Examples |
|----------|----------|
| **Character/Word** | `h` `j` `k` `l` `w` `e` `b` `W` `E` `B` `ge` |
| **Line** | `0` `^` `$` `g_` `+` `-` `\|` |
| **Vertical** | `gg` `G` `{` `}` `(` `)` `[[` `]]` `%` |
| **Screen** | `H` `M` `L` `` `` `` `` `zz` `zt` `zb` |
| **Search/Find** | `/` `?` `n` `N` `*` `#` `f` `F` `t` `T` `;` `,` |
| **Jumps** | `` `` `gd` `gD` `gf` `` `g;` `g,` |
| **Text Objects** | `iw` `aw` `ip` `ap` `i)` `a)` `i"` `a"` `it` `at` |
| **Operators** | `d` `c` `y` `>` `<` `=` `gq` `gu` `gU` |
| **Commands** | `dd` `yy` `cc` `p` `P` `u` `` `.` `J` |
| **Diff/Spell** | `[c` `]c` `[s` `]s` `z=` `zg` |
| **Folds** | `zo` `zc` `za` `zR` `zM` `zj` `zk` |
| **Windows** | `s` `v` `h/j/k/l` `=` |

> **Smart deduplication**: If you've remapped a motion (e.g., `gd` for LSP), your version takes precedence.

Disable with `include_motions = false` if you prefer a leaner view.

## 🚀 Quick Start

```lua
-- lazy.nvim (recommended)
{
"abdul-hamid-achik/keymaps.nvim",
opts = {},
keys = {
{ "?", "Keymaps", desc = "Show Keymaps" },
},
}
```

Then press `?` to open the cheatsheet!

## 📦 Installation

### [lazy.nvim](https://github.com/folke/lazy.nvim)

```lua
{
"abdul-hamid-achik/keymaps.nvim",
dependencies = {
"nvim-telescope/telescope.nvim", -- optional, for fuzzy finding
},
opts = {
-- your configuration (see below)
},
keys = {
{ "?", "Keymaps", desc = "Show Keymaps" },
},
}
```

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

```lua
use {
"abdul-hamid-achik/keymaps.nvim",
requires = {
"nvim-telescope/telescope.nvim", -- optional
},
config = function()
require("keymaps").setup({
-- your configuration
})
end,
}
```

### [vim-plug](https://github.com/junegunn/vim-plug)

```vim
Plug 'nvim-telescope/telescope.nvim' " optional
Plug 'abdul-hamid-achik/keymaps.nvim'

lua require("keymaps").setup()
```

### Manual

```bash
git clone https://github.com/abdul-hamid-achik/keymaps.nvim \
~/.local/share/nvim/site/pack/plugins/start/keymaps.nvim
```

## ⚙️ Configuration

Click to expand full configuration

```lua
require("keymaps").setup({
-- Main keybinding to open the cheatsheet (set to "" to disable)
key = "?",

-- Use telescope if available, fallback to floating window
telescope = true,

-- Show nerd font icons (requires a nerd font)
icons = true,

-- Include vim builtin keymaps
include_builtins = false,

-- Include buffer-local keymaps (from netrw, help, etc.)
-- Set to false to hide noisy internal keymaps
include_buffer_local = false,

-- Include standard Vim motions and commands (h/j/k/l, w/e/b, text objects, etc.)
-- These are merged with your custom keymaps for a complete reference
include_motions = true,

-- Enable usage tracking
track_usage = false,

-- Auto-refresh when config files change
auto_refresh = true,

-- Cache timeout in seconds (0 = no cache)
cache_timeout = 300,

-- Category patterns for auto-categorization
-- Keys are matched against these patterns to determine category
category_patterns = {
["LSP"] = {
"^g[dDrRiItT]",
"^l",
"^c[aAdDfFrRsS]",
"hover", "diagnostic", "definition", "references",
},
["Git"] = {
"^g",
"^h",
"gitsigns", "fugitive", "neogit", "lazygit",
},
["Navigation"] = {
"^",
"^w",
"^b",
"buffer", "window", "split",
},
["Harpoon"] = { "harpoon", "^a" },
["Telescope"] = { "telescope", "^f", "^s" },
["File Explorer"] = { "^e", "nvim%-tree", "neo%-tree", "oil" },
["Editing"] = { "yank", "paste", "delete", "surround" },
["Comments"] = { "^gc", "^gb", "comment" },
["Debugging"] = { "dap", "debug", "breakpoint" },
["Testing"] = { "^t", "neotest", "test" },
["Terminal"] = { "terminal", "toggleterm" },
-- Add your own!
["Custom"] = { "my_pattern" },
},

-- Patterns to exclude from display
exclude_patterns = {
"^",
"^",
},

-- Icons for categories (requires nerd font)
category_icons = {
["LSP"] = "",
["Git"] = "",
["Navigation"] = "",
["Harpoon"] = "󱡀",
["Telescope"] = "",
["File Explorer"] = "",
["Editing"] = "",
["Comments"] = "",
["Debugging"] = "",
["Testing"] = "",
["Terminal"] = "",
["Other"] = "",
},

-- Icons for modes
mode_icons = {
n = "󰰓", -- Normal
i = "󰰄", -- Insert
v = "󰰫", -- Visual
x = "󰰵", -- Visual Block
s = "󰰢", -- Select
o = "󰰑", -- Operator
c = "󰯲", -- Command
t = "󰰥", -- Terminal
},
})
```

### Minimal Config

```lua
require("keymaps").setup() -- That's it! Uses sensible defaults
```

## 📋 Commands

| Command | Description |
|---------|-------------|
| `:Keymaps` | Open the keymaps cheatsheet |
| `:Keymaps LSP` | Filter by category (with tab completion!) |
| `:KeymapsRefresh` | Refresh the keymaps cache |
| `:KeymapsExport markdown` | Export to `keymaps.md` |
| `:KeymapsExport html` | Export to searchable `keymaps.html` |
| `:KeymapsExport json` | Export to `keymaps.json` |
| `:KeymapsStats` | Show usage statistics |

## ⌨️ Keybindings

### Default

| Key | Action |
|-----|--------|
| `?` | Open keymaps cheatsheet |

### Telescope Picker

| Key | Action |
|-----|--------|
| `` | Copy keymap to clipboard |
| `` | Execute the keymap |
| `` | Close |

### Floating Window

| Key | Action |
|-----|--------|
| `q` / `` | Close |
| `/` | Search |
| `r` | Refresh |

## 🔌 API

```lua
local keymaps = require("keymaps")

-- Get all keymaps
local all = keymaps.get_keymaps()

-- Search keymaps
local results = keymaps.search("telescope")

-- Filter by category or mode
local lsp = keymaps.get_by_category("LSP")
local normal = keymaps.get_by_mode("n")

-- Get available categories
local categories = keymaps.get_categories()

-- Export
keymaps.export_to("markdown", "~/keymaps.md")
keymaps.export_to("html", "~/keymaps.html")
keymaps.export_to("json", "~/keymaps.json")

-- Open UI
keymaps.open() -- all keymaps
keymaps.open("Git") -- filtered

-- Refresh cache
keymaps.refresh()
```

## 🆚 Comparison

### vs which-key.nvim

| | keymaps.nvim | which-key.nvim |
|---|:---:|:---:|
| Auto-detect keymaps | ✅ | ❌ |
| Popup on keypress | ❌ | ✅ |
| Searchable cheatsheet | ✅ | Limited |
| Export to files | ✅ | ❌ |
| Plugin source detection | ✅ | ❌ |
| Usage tracking | ✅ | ❌ |

> **Pro tip**: Use both together! which-key shows hints as you type, keymaps.nvim gives you the full searchable reference.

### vs cheatsheet.nvim

| | keymaps.nvim | cheatsheet.nvim |
|---|:---:|:---:|
| Auto-detect keymaps | ✅ | Partial |
| Bundled cheatsheets | ❌ | ✅ |
| Custom cheatsheet files | ❌ | ✅ |
| HTML export with search | ✅ | ❌ |
| Smart categorization | ✅ | Limited |

## 🍳 Recipes

Track your most used keymaps

```lua
require("keymaps").setup({
track_usage = true,
})

-- Then run :KeymapsStats to see what you actually use!
```

Auto-export on quit

```lua
vim.api.nvim_create_autocmd("VimLeavePre", {
callback = function()
require("keymaps").export_to("markdown", "~/.config/nvim/KEYMAPS.md")
end,
})
```

Add custom categories for AI tools

```lua
require("keymaps").setup({
category_patterns = {
["AI"] = {
"copilot",
"codeium",
"chatgpt",
"^a",
},
},
category_icons = {
["AI"] = "󰚩",
},
})
```

Show only custom keymaps (hide builtins)

```lua
require("keymaps").setup({
include_builtins = false,
exclude_patterns = {
"^",
"^",
"^%w$", -- Single character keys
},
})
```

Use with dashboard

```lua
-- For alpha.nvim or dashboard.nvim
local function get_keymap_count()
return #require("keymaps").get_keymaps()
end

-- Display: "You have 142 keymaps configured"
```

## 🔧 Troubleshooting

Keymaps not showing up?

1. Make sure your plugins are loaded before calling `:Keymaps`
2. Try `:KeymapsRefresh` to clear the cache
3. Check if keymaps are excluded by `exclude_patterns`
4. Run `:lua print(vim.inspect(require("keymaps").get_keymaps()))` to debug

Icons not displaying correctly?

Make sure you have a [Nerd Font](https://www.nerdfonts.com/) installed and configured in your terminal. Alternatively, disable icons:

```lua
require("keymaps").setup({
icons = false,
})
```

Telescope not working?

Ensure telescope.nvim is installed and loaded. The plugin will automatically fall back to a floating window if Telescope isn't available.

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## 📄 License

MIT License - see [LICENSE](LICENSE) for details.

## 🙏 Acknowledgments

- Inspired by [which-key.nvim](https://github.com/folke/which-key.nvim) and [cheatsheet.nvim](https://github.com/sudormrfbin/cheatsheet.nvim)
- Thanks to the amazing Neovim community

---


Made with ❤️ by Abdul Hamid Achik for the Neovim community