Regenerate nvim config
This commit is contained in:
89
config/neovim/store/lazy-plugins/which-key.nvim/.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
89
config/neovim/store/lazy-plugins/which-key.nvim/.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
name: Bug Report
|
||||
description: File a bug/issue
|
||||
title: "bug: "
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Before** reporting an issue, make sure to read the [documentation](https://github.com/folke/which-key.nvim) and search [existing issues](https://github.com/folke/which-key.nvim/issues). Usage questions such as ***"How do I...?"*** belong in [Discussions](https://github.com/folke/which-key.nvim/discussions) and will be closed.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Did you check docs and existing issues?
|
||||
description: Make sure you checked all of the below before submitting an issue
|
||||
options:
|
||||
- label: I have read all the which-key.nvim docs
|
||||
required: true
|
||||
- label: I have searched the existing issues of which-key.nvim
|
||||
required: true
|
||||
- label: I have searched the existing issues of plugins related to this issue
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Neovim version (nvim -v)"
|
||||
placeholder: "0.8.0 commit db1b0ee3b30f"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Operating system/version"
|
||||
placeholder: "MacOS 11.5"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is. Please include any related errors you see in Neovim.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps To Reproduce
|
||||
description: Steps to reproduce the behavior.
|
||||
placeholder: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: A concise description of what you expected to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Repro
|
||||
description: Minimal `init.lua` to reproduce this issue. Save as `repro.lua` and run with `nvim -u repro.lua`
|
||||
value: |
|
||||
-- DO NOT change the paths and don't remove the colorscheme
|
||||
local root = vim.fn.fnamemodify("./.repro", ":p")
|
||||
|
||||
-- set stdpaths to use .repro
|
||||
for _, name in ipairs({ "config", "data", "state", "cache" }) do
|
||||
vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
|
||||
end
|
||||
|
||||
-- bootstrap lazy
|
||||
local lazypath = root .. "/plugins/lazy.nvim"
|
||||
if not vim.loop.fs_stat(lazypath) then
|
||||
vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath, })
|
||||
end
|
||||
vim.opt.runtimepath:prepend(lazypath)
|
||||
|
||||
-- install plugins
|
||||
local plugins = {
|
||||
"folke/tokyonight.nvim",
|
||||
{ "folke/which-key.nvim", config = true },
|
||||
-- add any other plugins here
|
||||
}
|
||||
require("lazy").setup(plugins, {
|
||||
root = root .. "/plugins",
|
||||
})
|
||||
|
||||
vim.cmd.colorscheme("tokyonight")
|
||||
-- add anything else here
|
||||
render: Lua
|
||||
validations:
|
||||
required: false
|
||||
36
config/neovim/store/lazy-plugins/which-key.nvim/.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
36
config/neovim/store/lazy-plugins/which-key.nvim/.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
name: Feature Request
|
||||
description: Suggest a new feature
|
||||
title: "feature: "
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Did you check the docs?
|
||||
description: Make sure you read all the docs before submitting a feature request
|
||||
options:
|
||||
- label: I have read all the which-key.nvim docs
|
||||
required: true
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Is your feature request related to a problem? Please describe.
|
||||
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: A clear and concise description of what you want to happen.
|
||||
- type: textarea
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
- type: textarea
|
||||
validations:
|
||||
required: false
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context or screenshots about the feature request here.
|
||||
72
config/neovim/store/lazy-plugins/which-key.nvim/.github/workflows/ci.yml
vendored
Normal file
72
config/neovim/store/lazy-plugins/which-key.nvim/.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
strategy:
|
||||
matrix:
|
||||
# os: [ubuntu-latest, windows-latest]
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Neovim
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p /tmp/nvim
|
||||
wget -q https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage -O /tmp/nvim/nvim.appimage
|
||||
cd /tmp/nvim
|
||||
chmod a+x ./nvim.appimage
|
||||
./nvim.appimage --appimage-extract
|
||||
echo "/tmp/nvim/squashfs-root/usr/bin/" >> $GITHUB_PATH
|
||||
- name: Run Tests
|
||||
run: |
|
||||
nvim --version
|
||||
[ ! -d tests ] && exit 0
|
||||
nvim --headless -u tests/init.lua -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/init.lua', sequential = true}"
|
||||
docs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: tests
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: panvimdoc
|
||||
uses: kdheepak/panvimdoc@main
|
||||
with:
|
||||
vimdoc: which-key.nvim
|
||||
version: "Neovim >= 0.8.0"
|
||||
demojify: true
|
||||
treesitter: true
|
||||
- name: Push changes
|
||||
uses: stefanzweifel/git-auto-commit-action@v4
|
||||
with:
|
||||
commit_message: "chore(build): auto-generate vimdoc"
|
||||
commit_user_name: "github-actions[bot]"
|
||||
commit_user_email: "github-actions[bot]@users.noreply.github.com"
|
||||
commit_author: "github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
|
||||
release:
|
||||
name: release
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
needs:
|
||||
- docs
|
||||
- tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: google-github-actions/release-please-action@v3
|
||||
id: release
|
||||
with:
|
||||
release-type: simple
|
||||
package-name: which-key.nvim
|
||||
- uses: actions/checkout@v3
|
||||
- name: tag stable versions
|
||||
if: ${{ steps.release.outputs.release_created }}
|
||||
run: |
|
||||
git config user.name github-actions[bot]
|
||||
git config user.email github-actions[bot]@users.noreply.github.com
|
||||
git remote add gh-token "https://${{ secrets.GITHUB_TOKEN }}@github.com/google-github-actions/release-please-action.git"
|
||||
git tag -d stable || true
|
||||
git push origin :stable || true
|
||||
git tag -a stable -m "Last Stable Release"
|
||||
git push origin stable
|
||||
8
config/neovim/store/lazy-plugins/which-key.nvim/.gitignore
vendored
Normal file
8
config/neovim/store/lazy-plugins/which-key.nvim/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
tt.*
|
||||
.tests
|
||||
doc/tags
|
||||
debug
|
||||
.repro
|
||||
foo.*
|
||||
*.log
|
||||
data
|
||||
13
config/neovim/store/lazy-plugins/which-key.nvim/.lua-format
Normal file
13
config/neovim/store/lazy-plugins/which-key.nvim/.lua-format
Normal file
@ -0,0 +1,13 @@
|
||||
# https://github.com/Koihik/LuaFormatter/blob/master/docs/Style-Config.md
|
||||
column_limit: 100
|
||||
indent_width: 2
|
||||
continuation_indent_width: 2
|
||||
use_tab: false
|
||||
chop_down_parameter: true
|
||||
chop_down_table: true
|
||||
chop_down_kv_table: true
|
||||
single_quote_to_double_quote: true
|
||||
spaces_inside_table_braces: true
|
||||
align_parameter: true
|
||||
keep_simple_control_block_one_line: true
|
||||
extra_sep_at_table_end: true
|
||||
@ -0,0 +1,14 @@
|
||||
{
|
||||
"lspconfig": {
|
||||
"sumneko_lua": {
|
||||
"Lua.format.defaultConfig": {
|
||||
"indent_style": "space",
|
||||
"indent_size": "2",
|
||||
"continuation_indent_size": "2"
|
||||
},
|
||||
"Lua.diagnostics.neededFileStatus": {
|
||||
// "codestyle-check": "Any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
334
config/neovim/store/lazy-plugins/which-key.nvim/CHANGELOG.md
Normal file
334
config/neovim/store/lazy-plugins/which-key.nvim/CHANGELOG.md
Normal file
@ -0,0 +1,334 @@
|
||||
# Changelog
|
||||
|
||||
## [1.6.0](https://github.com/folke/which-key.nvim/compare/v1.5.1...v1.6.0) (2023-10-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **presets:** added gt and gT. Fixes [#457](https://github.com/folke/which-key.nvim/issues/457) ([3ba77f0](https://github.com/folke/which-key.nvim/commit/3ba77f0b0961b3fe685397b8d8f34f231b9350a6))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* call config in issue template ([#489](https://github.com/folke/which-key.nvim/issues/489)) ([09a8188](https://github.com/folke/which-key.nvim/commit/09a8188224dc890618dfbc961436b106d912c2c1))
|
||||
* **view:** set modifiable flag for view buffer ([#506](https://github.com/folke/which-key.nvim/issues/506)) ([1d17760](https://github.com/folke/which-key.nvim/commit/1d1776012eda4258985f6f1f0c02b78594a3f37b))
|
||||
|
||||
## [1.5.1](https://github.com/folke/which-key.nvim/compare/v1.5.0...v1.5.1) (2023-07-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* revert: never overwrite actual keymaps with group names. Fixes [#478](https://github.com/folke/which-key.nvim/issues/478) Fixes [#479](https://github.com/folke/which-key.nvim/issues/479) Fixes [#480](https://github.com/folke/which-key.nvim/issues/480) ([fc25407](https://github.com/folke/which-key.nvim/commit/fc25407a360d27c36a30a90ff36861aa20ef2e54))
|
||||
|
||||
## [1.5.0](https://github.com/folke/which-key.nvim/compare/v1.4.3...v1.5.0) (2023-07-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **marks:** show filename as label when no label ([25babc6](https://github.com/folke/which-key.nvim/commit/25babc6add21c17d6391a585302aee5632266622))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **keys:** don't show empty groups ([8503c0d](https://github.com/folke/which-key.nvim/commit/8503c0d725420b37ac31e44753657cde91435597))
|
||||
* never overwrite actual keymaps with group names ([f61da3a](https://github.com/folke/which-key.nvim/commit/f61da3a3a6143b7a42b4b16e983004856ec26bd1))
|
||||
* **registers:** dont trigger on @. Fixes [#466](https://github.com/folke/which-key.nvim/issues/466) ([65b36cc](https://github.com/folke/which-key.nvim/commit/65b36cc258e857dea92fc11cdc0d6e2bb01d3e87))
|
||||
|
||||
## [1.4.3](https://github.com/folke/which-key.nvim/compare/v1.4.2...v1.4.3) (2023-05-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **health:** dont show duplicates between global and buffer-local. It's too confusing ([015fdf3](https://github.com/folke/which-key.nvim/commit/015fdf3e3e052d4a9fee997ca0aa387c2dd3731c))
|
||||
|
||||
## [1.4.2](https://github.com/folke/which-key.nvim/compare/v1.4.1...v1.4.2) (2023-05-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **health:** update the deprecated function ([#453](https://github.com/folke/which-key.nvim/issues/453)) ([12d3b11](https://github.com/folke/which-key.nvim/commit/12d3b11a67b94d65483f10c6ba0a47474039543a))
|
||||
|
||||
## [1.4.1](https://github.com/folke/which-key.nvim/compare/v1.4.0...v1.4.1) (2023-05-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **keys:** dont overwrite existing keymaps with a callback. Fixes [#449](https://github.com/folke/which-key.nvim/issues/449) ([4db6bb0](https://github.com/folke/which-key.nvim/commit/4db6bb080b269ac155e5aa1696d26f2376c749ab))
|
||||
|
||||
## [1.4.0](https://github.com/folke/which-key.nvim/compare/v1.3.0...v1.4.0) (2023-04-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **view:** ensure it's above other floating windows ([#442](https://github.com/folke/which-key.nvim/issues/442)) ([9443778](https://github.com/folke/which-key.nvim/commit/94437786a0d0fde61284f8476ac142896878c2d7))
|
||||
|
||||
## [1.3.0](https://github.com/folke/which-key.nvim/compare/v1.2.3...v1.3.0) (2023-04-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **health:** move health check to separate health file ([b56c512](https://github.com/folke/which-key.nvim/commit/b56c5126752fcd498a81c6d8d1e7f51f251166eb))
|
||||
* **preset:** add `z<CR>` preset ([#346](https://github.com/folke/which-key.nvim/issues/346)) ([ed37330](https://github.com/folke/which-key.nvim/commit/ed3733059ffa281c8144e44f1b4819a771ddf4de))
|
||||
* **preset:** added `zi` and `CTRL-W_o` ([#378](https://github.com/folke/which-key.nvim/issues/378)) ([5e8e6b1](https://github.com/folke/which-key.nvim/commit/5e8e6b1c70d3fcbe2712453ef3ebbf07d0d2aff4))
|
||||
* **view:** allow percentages for margins. Fixes [#436](https://github.com/folke/which-key.nvim/issues/436) ([0b5a653](https://github.com/folke/which-key.nvim/commit/0b5a6537b66ee37d03c6c3f0e21fd147f817422d))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **health:** add OK output to check_health fn ([#375](https://github.com/folke/which-key.nvim/issues/375)) ([c9c430a](https://github.com/folke/which-key.nvim/commit/c9c430ab19a3bf8dd394dd9925a3a219063276b9))
|
||||
* **keys:** allow keymap desc to override preset labels. Fixes [#386](https://github.com/folke/which-key.nvim/issues/386) ([6aa1b2f](https://github.com/folke/which-key.nvim/commit/6aa1b2fa93a2a26a1bd752080ec6a51beb009e75))
|
||||
* **tree:** don't cache plugin nodes. Fixes [#441](https://github.com/folke/which-key.nvim/issues/441) ([20fcd7b](https://github.com/folke/which-key.nvim/commit/20fcd7b602a2c58d634eaa1f1d28b16a6acbfad3))
|
||||
* **util:** clear cache when leader changes ([df3597f](https://github.com/folke/which-key.nvim/commit/df3597f7dc0f379bda865e3c9dd6303fa6e4c959))
|
||||
* **util:** missing return statement ([f6bb21c](https://github.com/folke/which-key.nvim/commit/f6bb21c8c1d72008783466e80e0c993ef056a3a9))
|
||||
* **util:** nil check ([6ab25e2](https://github.com/folke/which-key.nvim/commit/6ab25e24ec2b2a8fb88f43eb13feb21e5042c280))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **keys:** optimized `update_keymaps` ([476d137](https://github.com/folke/which-key.nvim/commit/476d13754db0da7831fc3581fb243cd7f0d3e581))
|
||||
* **tree:** added fast nodes lookup ([8e5e012](https://github.com/folke/which-key.nvim/commit/8e5e0126aaff9bd73eb25a6d5568f6b5bdff58f0))
|
||||
* **util:** cache parse_keys ([8649bf5](https://github.com/folke/which-key.nvim/commit/8649bf5c66b8fa1fa6ee879b9af78e89f886d13c))
|
||||
* **util:** cache replace termcodes ([eaa8027](https://github.com/folke/which-key.nvim/commit/eaa80272ef488c68cd51698c64e795767c6e0624))
|
||||
|
||||
## [1.2.3](https://github.com/folke/which-key.nvim/compare/v1.2.2...v1.2.3) (2023-04-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **util:** dont parse empty lhs ([8d5ab76](https://github.com/folke/which-key.nvim/commit/8d5ab76836d89be1c761a4ed61bf700d98c71e5d))
|
||||
* **util:** only collect valid <> keys ([#438](https://github.com/folke/which-key.nvim/issues/438)) ([4bd6dca](https://github.com/folke/which-key.nvim/commit/4bd6dcaa6d7e1650590303f0066d32aa6762d8f3))
|
||||
* **util:** replace `<lt>` by `<` before parsing ([789ac71](https://github.com/folke/which-key.nvim/commit/789ac718ee7a2b49dd82409e3d7cf45b52ea95ce))
|
||||
* **view:** allow deviating paddings per side ([#400](https://github.com/folke/which-key.nvim/issues/400)) ([3090eaf](https://github.com/folke/which-key.nvim/commit/3090eafb780da76eb4876986081551db80bf35cd))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **util:** simplify and optimize parsers ([#435](https://github.com/folke/which-key.nvim/issues/435)) ([b0ebb67](https://github.com/folke/which-key.nvim/commit/b0ebb6722c77dda1ab1e3ce13521fe7db20cbc79))
|
||||
|
||||
## [1.2.2](https://github.com/folke/which-key.nvim/compare/v1.2.1...v1.2.2) (2023-04-16)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **mappings:** avoid computing error string on hot path ([#429](https://github.com/folke/which-key.nvim/issues/429)) ([6892f16](https://github.com/folke/which-key.nvim/commit/6892f165bb984561f8cac298a6747da338d04668))
|
||||
|
||||
## [1.2.1](https://github.com/folke/which-key.nvim/compare/v1.2.0...v1.2.1) (2023-03-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **icons:** fixed obsolete icons with nerdfix ([151f21d](https://github.com/folke/which-key.nvim/commit/151f21d34d50fc53506ddc9d8ec58234202df795))
|
||||
* **view:** wrong window position when statusline is not set ([#363](https://github.com/folke/which-key.nvim/issues/363)) ([e14f8dc](https://github.com/folke/which-key.nvim/commit/e14f8dc6304e774ce005d09f7feebbd191fe20f9))
|
||||
|
||||
## [1.2.0](https://github.com/folke/which-key.nvim/compare/v1.1.1...v1.2.0) (2023-03-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* enable spelling plugin by default ([6d886f4](https://github.com/folke/which-key.nvim/commit/6d886f4dcaa25d1fe20e332f779fe1edb726d063))
|
||||
* make delay configurable for marks/registers/spelling. Fixes [#379](https://github.com/folke/which-key.nvim/issues/379). Fixes [#152](https://github.com/folke/which-key.nvim/issues/152), Fixes [#220](https://github.com/folke/which-key.nvim/issues/220), Fixes [#334](https://github.com/folke/which-key.nvim/issues/334) ([5649320](https://github.com/folke/which-key.nvim/commit/56493205745597abdd8d3ceb22f502ffe74784f5))
|
||||
|
||||
## [1.1.1](https://github.com/folke/which-key.nvim/compare/v1.1.0...v1.1.1) (2023-02-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* remove duplicate kaymap ([#361](https://github.com/folke/which-key.nvim/issues/361)) ([9a4680e](https://github.com/folke/which-key.nvim/commit/9a4680e95b7026c58f0a377de0f13ee2507ece7a))
|
||||
|
||||
## [1.1.0](https://github.com/folke/which-key.nvim/compare/v1.0.0...v1.1.0) (2023-01-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Hide mapping when `desc = "which_key_ignore"` ([#391](https://github.com/folke/which-key.nvim/issues/391)) ([fd07b61](https://github.com/folke/which-key.nvim/commit/fd07b6137f1e362a66df04f7c7055b99319e3a4d))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* visual-multi compatibility ([#389](https://github.com/folke/which-key.nvim/issues/389)) ([#385](https://github.com/folke/which-key.nvim/issues/385)) ([01334bb](https://github.com/folke/which-key.nvim/commit/01334bb48c53231fc8b2e2932215bfee05474904))
|
||||
|
||||
## 1.0.0 (2023-01-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add <C-w>_ to misc ([#296](https://github.com/folke/which-key.nvim/issues/296)) ([03b8c1d](https://github.com/folke/which-key.nvim/commit/03b8c1dde8c02f187869c56a6019d5e2578f7af7))
|
||||
* add preset key to mappings for API usage ([ed7d6c5](https://github.com/folke/which-key.nvim/commit/ed7d6c523ae8ef7b8059d2fee0836009e71bcd0c))
|
||||
* added a winblend option for the floating window ([#161](https://github.com/folke/which-key.nvim/issues/161)) ([d3032b6](https://github.com/folke/which-key.nvim/commit/d3032b6d3e0adb667975170f626cb693bfc66baa))
|
||||
* added duplicate mapping checks to checkhealth [#34](https://github.com/folke/which-key.nvim/issues/34) ([710c5f8](https://github.com/folke/which-key.nvim/commit/710c5f81da2c34e6e0f361d87cfca27207e1b994))
|
||||
* added healthcheck to check for conflicting keymaps ([44d3c3f](https://github.com/folke/which-key.nvim/commit/44d3c3f9307930ce8c877383d51fca1a353982d8))
|
||||
* added ignore_missing option to hide any keymap for which no label exists [#60](https://github.com/folke/which-key.nvim/issues/60) ([1ccba9d](https://github.com/folke/which-key.nvim/commit/1ccba9d0b553b08feaca9f432386f9c33bd1656f))
|
||||
* added operators plugin ([c7f8496](https://github.com/folke/which-key.nvim/commit/c7f84968e44f1a9ab9687ddf0b3dc5465e48bc75))
|
||||
* added option to configure scroll bindings inside the popup ([#175](https://github.com/folke/which-key.nvim/issues/175)) ([a54ef5f](https://github.com/folke/which-key.nvim/commit/a54ef5f5db5819ee65a5ec3dea9bae64476c5017))
|
||||
* added options to align columns left, center or right [#82](https://github.com/folke/which-key.nvim/issues/82) ([2467fb1](https://github.com/folke/which-key.nvim/commit/2467fb15e8775928fba3d7d20a68b64852f44122))
|
||||
* added settings to disable the WhichKey popup for certain buftypes and filetyes ([fb276a0](https://github.com/folke/which-key.nvim/commit/fb276a07c7dc305e48ecc2683e4bd28cda49499a))
|
||||
* added support for expr mappings ([9d2785c](https://github.com/folke/which-key.nvim/commit/9d2785c4d44b4a8ca1095856cb4ee34a32497cf6))
|
||||
* added triggers_blacklist to blacklist certain whichkey hooks [#73](https://github.com/folke/which-key.nvim/issues/73) ([ec1474b](https://github.com/folke/which-key.nvim/commit/ec1474bb0c373eb583962deff20860c2af54f932))
|
||||
* added WhichKeyBorder highlight group ([9c190ea](https://github.com/folke/which-key.nvim/commit/9c190ea91939eba8c2d45660127e0403a5300b5a))
|
||||
* allow functions to be passed to create keybindings. Implements [#31](https://github.com/folke/which-key.nvim/issues/31) ([cf644cd](https://github.com/folke/which-key.nvim/commit/cf644cd9a0e989ad3e0a6dffb98beced742f3297))
|
||||
* allow manual setup of triggers [#30](https://github.com/folke/which-key.nvim/issues/30) ([423a50c](https://github.com/folke/which-key.nvim/commit/423a50cccfeb8b812e0e89f156316a4bd9d2673a))
|
||||
* allow mapping to have multiple modes as a table ([0d559fa](https://github.com/folke/which-key.nvim/commit/0d559fa5573aa48c4822e8874315316bd075e17e))
|
||||
* allow mode to be set on a single mapping ([2a08d58](https://github.com/folke/which-key.nvim/commit/2a08d58658e1de0fae3b44e21e8ed72399465701))
|
||||
* allow overriding key labels [#77](https://github.com/folke/which-key.nvim/issues/77) ([2be929e](https://github.com/folke/which-key.nvim/commit/2be929e34b2f2b982e6b978c0bd94cd2e1d500e6))
|
||||
* allow to close popup with <c-c> [#33](https://github.com/folke/which-key.nvim/issues/33) ([410523a](https://github.com/folke/which-key.nvim/commit/410523a6d7bcbcab73f8c7b0fc567893d7cd8c44))
|
||||
* better logging ([c39df95](https://github.com/folke/which-key.nvim/commit/c39df95881a6cd8ac27fce5926dc2dc1b4597df9))
|
||||
* better support for plugin actions with custom lua function ([222a8ee](https://github.com/folke/which-key.nvim/commit/222a8eeaf727f9b1b767424198f7c71274c04d43))
|
||||
* builtin key mappings ([0063ceb](https://github.com/folke/which-key.nvim/commit/0063ceb161475097885d567500fe764358983c62))
|
||||
* check for rogue existsing WhichKey mappings and show error. WK handles triggers automatically, no need to define them ([db97a30](https://github.com/folke/which-key.nvim/commit/db97a301fb7691b61cd6c975e3cc060fb53fd980))
|
||||
* easily reset WK with plenary for development of WK ([55b4dab](https://github.com/folke/which-key.nvim/commit/55b4dabab649d59e657917eb17c9d57716817719))
|
||||
* expose registers to customize order ([2b83fe7](https://github.com/folke/which-key.nvim/commit/2b83fe74dee00763e4c037d198c88ff11c843914))
|
||||
* for nvim 0.7.0 or higher, use native keymap callbacks instead of which key functions ([5e96cf9](https://github.com/folke/which-key.nvim/commit/5e96cf950a864a4600512c90f2080b0b6f0eacb7))
|
||||
* group symbol ([5e02b66](https://github.com/folke/which-key.nvim/commit/5e02b66b9e7add373967b798552a7cc9a427efb4))
|
||||
* handle [count] with motion. Implements [#11](https://github.com/folke/which-key.nvim/issues/11) ([d93ef0f](https://github.com/folke/which-key.nvim/commit/d93ef0f2f1a9a6288016a3a82f70399e350a574f))
|
||||
* hide mapping boilerplate ([#6](https://github.com/folke/which-key.nvim/issues/6)) ([b3357de](https://github.com/folke/which-key.nvim/commit/b3357de005f27a3cc6aabe922e8ee308470d9343))
|
||||
* honor timeoutlen when typing an operator followed by i or a instead of showing immediately ([54d1b3a](https://github.com/folke/which-key.nvim/commit/54d1b3ab3ed9132142f2139964cfa68d018b38c5))
|
||||
* initial commit ([970e79f](https://github.com/folke/which-key.nvim/commit/970e79f7016f6cc2a89dad8c50e2e89657684f55))
|
||||
* keyamp functions ([801cc81](https://github.com/folke/which-key.nvim/commit/801cc810f4d57eca029261f383b2483ec21e5824))
|
||||
* make custom operators configurable (fixes [#9](https://github.com/folke/which-key.nvim/issues/9)) ([81875d8](https://github.com/folke/which-key.nvim/commit/81875d875f7428c7a087e0d051744c7b3f9dc1b3))
|
||||
* make help message configurable ([7b1c6aa](https://github.com/folke/which-key.nvim/commit/7b1c6aa23061a9ed1acdfec3d20dc5e361ec01a3))
|
||||
* Make keypress message configuratble ([#351](https://github.com/folke/which-key.nvim/issues/351)) ([fd2422f](https://github.com/folke/which-key.nvim/commit/fd2422fb7030510cf9c3304047e653e8adcd8f20))
|
||||
* motions plugin ([f989fcf](https://github.com/folke/which-key.nvim/commit/f989fcfeafd4fd333a8e87617fce39a449ae81ca))
|
||||
* new keymap dsl ([#352](https://github.com/folke/which-key.nvim/issues/352)) Docs to come ([fbf0381](https://github.com/folke/which-key.nvim/commit/fbf038110edb5e2cbecaac57570aae2c9fa2939c))
|
||||
* option to make some triggers show immediately, regardless of timeoutlen ([3a52dc0](https://github.com/folke/which-key.nvim/commit/3a52dc02b6e542d5cd216381ccfa108943bab17c))
|
||||
* plugin for registers ([5415832](https://github.com/folke/which-key.nvim/commit/541583280fab4ea96900f35fb6b5ffb8de103a4c))
|
||||
* plugin support + first builtin marks plugin ([9d5e631](https://github.com/folke/which-key.nvim/commit/9d5e6311c20970741eaaf7a3950c1a33de5eedaa))
|
||||
* prefer `desc` to `cmd` as the fallback label ([#253](https://github.com/folke/which-key.nvim/issues/253)) ([bd4411a](https://github.com/folke/which-key.nvim/commit/bd4411a2ed4dd8bb69c125e339d837028a6eea71))
|
||||
* preset with misc keybindings ([e610338](https://github.com/folke/which-key.nvim/commit/e61033858b8d5208a49c24d70eb9576cbd22e887))
|
||||
* set keymap desc when creating new mappings based on the WhichKey labels ([f4518ca](https://github.com/folke/which-key.nvim/commit/f4518ca50193a545681ba65ba0c5bb8a8479c5b5))
|
||||
* set popup filetype to WhichKey and buftype to nofile [#86](https://github.com/folke/which-key.nvim/issues/86) ([20682f1](https://github.com/folke/which-key.nvim/commit/20682f189a0c452203f6365f66eccb0407b20936))
|
||||
* show a warning if <leader> is already mapped, even if it's <nop> ([ac56f45](https://github.com/folke/which-key.nvim/commit/ac56f45095e414c820f621423611aac4027f74bd))
|
||||
* show breadcrumb and help on command line ([c27535c](https://github.com/folke/which-key.nvim/commit/c27535ca085c05ade1e23b3b347e39e53c24d33a))
|
||||
* show keys and help in float when cmdheight == 0 ([f645017](https://github.com/folke/which-key.nvim/commit/f64501787bebe9ff28c10dbe470ffad5dd017769))
|
||||
* show/hide a fake cursor when WK is open ([0f53f40](https://github.com/folke/which-key.nvim/commit/0f53f40c1b827d35771c82a5c47c5a54d9408f7c))
|
||||
* spelling suggestion plugin ([4b74f21](https://github.com/folke/which-key.nvim/commit/4b74f218f4541991a40719286f96cce9447a89c4))
|
||||
* support for custom text object completion. Fixes [#10](https://github.com/folke/which-key.nvim/issues/10) ([394ff5a](https://github.com/folke/which-key.nvim/commit/394ff5a37bab051857de4216ee25db2284de2196))
|
||||
* support opts.remap for keymap ([#339](https://github.com/folke/which-key.nvim/issues/339)) ([6885b66](https://github.com/folke/which-key.nvim/commit/6885b669523ff4238de99a7c653d47b081b5506d))
|
||||
* support using lua function for expr ([#110](https://github.com/folke/which-key.nvim/issues/110)) ([e0dce15](https://github.com/folke/which-key.nvim/commit/e0dce1552ea37964ae6ac7144709867544eae7f3))
|
||||
* text objects ([d255b71](https://github.com/folke/which-key.nvim/commit/d255b71992494ce4998caae7fe281144fb669abb))
|
||||
* WhichKey vim command to show arbitrary keymaps ([df615d4](https://github.com/folke/which-key.nvim/commit/df615d44987a8bfe8910c618164f696e227ecfd4))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* :norm .. commands keep feeding <esc> at the end of the command [#58](https://github.com/folke/which-key.nvim/issues/58) ([d66ffdd](https://github.com/folke/which-key.nvim/commit/d66ffdd5a845c713f581ac6da36173e88096e0fa))
|
||||
* add delay option to macro key ([#152](https://github.com/folke/which-key.nvim/issues/152)) ([#156](https://github.com/folke/which-key.nvim/issues/156)) ([bd226c4](https://github.com/folke/which-key.nvim/commit/bd226c4d02d7f360747364a59cc5f0da50524f2c))
|
||||
* add remaining <esc> to pending in case there's no other characters ([29a82b5](https://github.com/folke/which-key.nvim/commit/29a82b575b9752a45b005327030948ce8cb513a0))
|
||||
* add triggers for other modes in marks and register plugin ([#116](https://github.com/folke/which-key.nvim/issues/116)) ([bbfc640](https://github.com/folke/which-key.nvim/commit/bbfc640c44612d705f4b0670ec1387c8a6ff2c7c))
|
||||
* added @ trigger for showing registers ([01b6676](https://github.com/folke/which-key.nvim/commit/01b66769480fac14f6efa7c31327234398d05837))
|
||||
* added builtin plugins to config ([6e461ca](https://github.com/folke/which-key.nvim/commit/6e461caec3d3aa43f1fa2b7890b299705bccfe8d))
|
||||
* added hidden option to disable the popup on motion counts (motions.count) ([ea975ef](https://github.com/folke/which-key.nvim/commit/ea975ef254f10c4938cd663a7c4fb14e2d7514c0))
|
||||
* added support for operator pending keymaps ([1f6b510](https://github.com/folke/which-key.nvim/commit/1f6b510f6ef0c223b51f3599200bbf6abc30f909))
|
||||
* added z= for spelling correction ([59603de](https://github.com/folke/which-key.nvim/commit/59603dee2f67f623a520148d60c634f6f56f6017))
|
||||
* always escape <leader> when it's a backslash ([41636a3](https://github.com/folke/which-key.nvim/commit/41636a3be909af5d20d811f8ce6a304a5ee3cc21))
|
||||
* always execute keys with remap, but unhook / hook WK triggers (Fixes [#8](https://github.com/folke/which-key.nvim/issues/8)) ([bf329df](https://github.com/folke/which-key.nvim/commit/bf329df0ee11d6c80c7208b40eab74368e963245))
|
||||
* always map <leader>, even without register ([512631c](https://github.com/folke/which-key.nvim/commit/512631c1bdce96dd048115cb139ea3a8452a931a))
|
||||
* always unhook and ignore errors ([01a60cd](https://github.com/folke/which-key.nvim/commit/01a60cd5929b395042c8ba3d872f6f25ccd55ecb))
|
||||
* always use noremap=false for <plug> commands ([9b9cece](https://github.com/folke/which-key.nvim/commit/9b9cece006b78ff7527a35285a4b5c1359d70fd8))
|
||||
* always use word under the cursor for spelling suggestions ([c5b19ec](https://github.com/folke/which-key.nvim/commit/c5b19ecf4d1d8f8c77ee982caf9792740f6d5e53))
|
||||
* better handling of weird norm and getchar endless <esc> bug [#68](https://github.com/folke/which-key.nvim/issues/68) ([bfd37e9](https://github.com/folke/which-key.nvim/commit/bfd37e93761d622328c673828b537d5671389413))
|
||||
* better sorting ([99e8940](https://github.com/folke/which-key.nvim/commit/99e894032afbe2543dbbf9bba05518d96b852aa0))
|
||||
* center alignemnt should be an integer ([db85198](https://github.com/folke/which-key.nvim/commit/db851981595fc360e9b6196a7c3995611aceac3b))
|
||||
* check for FloatBorder before setting winhighlight ([af6b91d](https://github.com/folke/which-key.nvim/commit/af6b91dc09e4ed830d8cd4a3652a5b3f80ccefac))
|
||||
* check is hook exists before unhooking ([f6cf3a2](https://github.com/folke/which-key.nvim/commit/f6cf3a2e49c09aba739c0f6fc85d3aebf2b96cb6))
|
||||
* cmd can be nil ([060a574](https://github.com/folke/which-key.nvim/commit/060a574c228433e9b17960fa0eafca0a975381e8))
|
||||
* **colors:** Separator links to DiffAdd ([#302](https://github.com/folke/which-key.nvim/issues/302)) ([a2749c5](https://github.com/folke/which-key.nvim/commit/a2749c5b039ad34734c98f8752b9fb5da7ceac55))
|
||||
* Compatibility with Visual Multi plug ([#278](https://github.com/folke/which-key.nvim/issues/278)) ([92916b6](https://github.com/folke/which-key.nvim/commit/92916b6cede0ffd7d5c1ce9abad93ec0c4d9635e))
|
||||
* convert trings with strtrans to properly render non printable characters ([d85ce36](https://github.com/folke/which-key.nvim/commit/d85ce3627f4060f622e4c0a9657f26c0151829de))
|
||||
* correct floating window position in Neovim 0.6 nightly ([#176](https://github.com/folke/which-key.nvim/issues/176)) ([a35a910](https://github.com/folke/which-key.nvim/commit/a35a910d28683294fd23d35dd03c06f6f7c37b17))
|
||||
* correctly handle counts before commands [#17](https://github.com/folke/which-key.nvim/issues/17) ([4feb319](https://github.com/folke/which-key.nvim/commit/4feb319ff89fb8659efa2a788f808bc390afa490))
|
||||
* correctly unhook buffer local mappings before executing keys ([4f98b47](https://github.com/folke/which-key.nvim/commit/4f98b4713ea9d4534662ceb7b542b0626eeb9ea8))
|
||||
* disable folding on whichkey popup. Fixes [#99](https://github.com/folke/which-key.nvim/issues/99) ([78821de](https://github.com/folke/which-key.nvim/commit/78821de0b633275d6934660e67989639bc7a784c))
|
||||
* disable operator pending maps for now ([#2](https://github.com/folke/which-key.nvim/issues/2)) ([0cd66a8](https://github.com/folke/which-key.nvim/commit/0cd66a84520fc0e7e3eec81f081157541cb48dbd))
|
||||
* do feedkeys in correct mode when dealing with operator pending commands. Fixes [#8](https://github.com/folke/which-key.nvim/issues/8) ([cf30788](https://github.com/folke/which-key.nvim/commit/cf307886b68ed53334ffdcee809a751376269e33))
|
||||
* don't show <esc> mappings since <esc> closes the popup ([09db756](https://github.com/folke/which-key.nvim/commit/09db756b5d357767a635a4d169e2e820b2962ea8))
|
||||
* don't show spelling when the command was started with a count [#80](https://github.com/folke/which-key.nvim/issues/80) ([20a85bd](https://github.com/folke/which-key.nvim/commit/20a85bd8bc54a11cf040aafa5d60f8a735eecfbd))
|
||||
* dont do feedkeys when user uses WhichKey command with non existing prefix ([f9537ce](https://github.com/folke/which-key.nvim/commit/f9537ce0f7457665e3b90d82c5f3f2c37fe0506f))
|
||||
* dont pass zero counts ([0c3cfb0](https://github.com/folke/which-key.nvim/commit/0c3cfb0064ceec5b182bac580033e0654d9575e6))
|
||||
* dont show errors about loading order of setup and register ([2adbc17](https://github.com/folke/which-key.nvim/commit/2adbc17e00061073f2c2a40b6420ee2a80ea458d))
|
||||
* explicitely check if we try to execute an auto which-key mapping. shouldn't happen, but still safer to check ([30fdd46](https://github.com/folke/which-key.nvim/commit/30fdd465433d48cab3b1f894daf52fa0005cf7ac))
|
||||
* expose presets so one can change them if needed [#70](https://github.com/folke/which-key.nvim/issues/70) ([46ea686](https://github.com/folke/which-key.nvim/commit/46ea686c6cc9bfc96bc492c76a76d43548a587c4))
|
||||
* feed CTRL-O again if called from CTRL-O ([#145](https://github.com/folke/which-key.nvim/issues/145)) ([833b5ea](https://github.com/folke/which-key.nvim/commit/833b5ea1a0d4b3bddf4b5c68fc89f1234960edec))
|
||||
* feed the keys as typed ([#333](https://github.com/folke/which-key.nvim/issues/333)) ([33b4e72](https://github.com/folke/which-key.nvim/commit/33b4e72a07546bc4798b4bafb99ae06df47bd790))
|
||||
* fix flickering on tmux ([f112602](https://github.com/folke/which-key.nvim/commit/f11260251ad942ba1635db9bc25c2efaf75caf0a))
|
||||
* fix issue when cmdheight=0 [#301](https://github.com/folke/which-key.nvim/issues/301) ([#305](https://github.com/folke/which-key.nvim/issues/305)) ([9cd09ca](https://github.com/folke/which-key.nvim/commit/9cd09ca6bbe5acfbce86ca023fdc720f6aa132d6))
|
||||
* fixed 0 after an operator. Wrongly assumed any number to be a count for following op mode, but not the case for 0 [#59](https://github.com/folke/which-key.nvim/issues/59) [#61](https://github.com/folke/which-key.nvim/issues/61) ([36616ca](https://github.com/folke/which-key.nvim/commit/36616cacba5d9eb716017bf23b7bbbe4cb4a6822))
|
||||
* fixed possible nil error when showing marks ([b44fc09](https://github.com/folke/which-key.nvim/commit/b44fc095f6d0144278f3413533ad2d40ae664229))
|
||||
* for sporadic loss of lua function for mapping ([#216](https://github.com/folke/which-key.nvim/issues/216)) ([312c386](https://github.com/folke/which-key.nvim/commit/312c386ee0eafc925c27869d2be9c11ebdb807eb))
|
||||
* formatting of text-objects plugin ([442d2d3](https://github.com/folke/which-key.nvim/commit/442d2d383284390c5ee1b922036fc10fff530b2d))
|
||||
* get value of register '=' with getreg('=',1) ([#114](https://github.com/folke/which-key.nvim/issues/114)) ([6224ea8](https://github.com/folke/which-key.nvim/commit/6224ea81f505c66a9644f89129149b108f722e56))
|
||||
* handle backslash as localleader [#47](https://github.com/folke/which-key.nvim/issues/47) ([cd23fdc](https://github.com/folke/which-key.nvim/commit/cd23fdc1b0cbdb22769bed5cb275a6d1c4bd9bfc))
|
||||
* handle baskslashes when leader or localleader isn't set ([d155ab3](https://github.com/folke/which-key.nvim/commit/d155ab3bef11a8156995b47d5552586e5c9f66a3))
|
||||
* handle keymaps with a <nop> rhs as non existing and possibly overwrite them with WK hooks [#35](https://github.com/folke/which-key.nvim/issues/35) ([402be18](https://github.com/folke/which-key.nvim/commit/402be18dc656897b1dc68c88fab4ffe8635b8209))
|
||||
* handle nvim_{buf_}get_keymap return no rhs due to 'callback' mapping ([#223](https://github.com/folke/which-key.nvim/issues/223)) ([28d2bd1](https://github.com/folke/which-key.nvim/commit/28d2bd129575b5e9ebddd88506601290bb2bb221))
|
||||
* handle possible errors when getting last expression register [#64](https://github.com/folke/which-key.nvim/issues/64) ([7a1be6f](https://github.com/folke/which-key.nvim/commit/7a1be6ff950c7fb94a4f9e9bdb428a514e569503))
|
||||
* highlighting of line number in marks ([9997d93](https://github.com/folke/which-key.nvim/commit/9997d93e5adcf0352aa73c42d3c395ba775600e9))
|
||||
* immediately show registers and marks. Fixes [#144](https://github.com/folke/which-key.nvim/issues/144) ([653ce71](https://github.com/folke/which-key.nvim/commit/653ce711e6c27416ac79c4811ff814e9a38fddcf))
|
||||
* link default WhichKeyBorder to FloatBorder. Fixes [#331](https://github.com/folke/which-key.nvim/issues/331) ([1698d6d](https://github.com/folke/which-key.nvim/commit/1698d6d0ff0b00b8499d9aea8715d120dc526900))
|
||||
* make register selection work in INSERT mode ([d4315f8](https://github.com/folke/which-key.nvim/commit/d4315f8991da816c30e9387a891c02774552dc36))
|
||||
* make spelling suggestions also work for correctly spelled words ([d02dc34](https://github.com/folke/which-key.nvim/commit/d02dc344bdaf273dfde7672f3f8e70a307593f62))
|
||||
* make sure we never accidentally show WK triggers ([197b4d3](https://github.com/folke/which-key.nvim/commit/197b4d3403c04c0045e8d541e8cd2504aba5f168))
|
||||
* make which-key's lazy loading work when it is also lazy-loaded ([7d929b9](https://github.com/folke/which-key.nvim/commit/7d929b96e2588fe9710ad795402eaead1aa0f70f))
|
||||
* manual command now uses proper escaping for prefix ([334fcca](https://github.com/folke/which-key.nvim/commit/334fcca64611dbca8c0c669260f4fb2a8ff81509))
|
||||
* mapleader=\ ([b5c8985](https://github.com/folke/which-key.nvim/commit/b5c89851d580459c1dd33ecbda611ae06e22eec4))
|
||||
* mapping when right-hand side is `nil` ([#323](https://github.com/folke/which-key.nvim/issues/323)) ([1d449d4](https://github.com/folke/which-key.nvim/commit/1d449d44e01787ef17dc7b0672eec01a8121b36e))
|
||||
* never hook in SELECT mode and properly handle v, x, s [#45](https://github.com/folke/which-key.nvim/issues/45) [#46](https://github.com/folke/which-key.nvim/issues/46) ([2844e1c](https://github.com/folke/which-key.nvim/commit/2844e1cbf298129afa58c13a90f91be907232dbf))
|
||||
* never hook j and k in INSERT mode automatcally to prevent jk kj <ESC> mappings to work as intended ([9a2faed](https://github.com/folke/which-key.nvim/commit/9a2faed055459d3226634344468f78bf85d77fa8))
|
||||
* never hook numbers. locks up due to v:count. Fixes [#118](https://github.com/folke/which-key.nvim/issues/118) ([2d2954a](https://github.com/folke/which-key.nvim/commit/2d2954a1d05b4f074e022e64db9aa6093d439bb0))
|
||||
* never hook on <esc> ([fd08322](https://github.com/folke/which-key.nvim/commit/fd0832233bd0c733618fab1c3df92f261c13d6b3))
|
||||
* never hook q [#63](https://github.com/folke/which-key.nvim/issues/63) ([95ae9d2](https://github.com/folke/which-key.nvim/commit/95ae9d2d00e8714379e64994e69ae17fc540a7d6))
|
||||
* never hook to operators in visual mode [#61](https://github.com/folke/which-key.nvim/issues/61) ([43d799a](https://github.com/folke/which-key.nvim/commit/43d799ad0e6218964e802ff342ca5f9352105175))
|
||||
* nil in health check ([5c018ae](https://github.com/folke/which-key.nvim/commit/5c018ae412b235abe17e24b46057564db0944dc4))
|
||||
* nvim_win_close force = true ([ca73a0e](https://github.com/folke/which-key.nvim/commit/ca73a0e03f142067a16891b712c7ea73ac646dff))
|
||||
* nvim-0.7.0 check ([#338](https://github.com/folke/which-key.nvim/issues/338)) ([1491c35](https://github.com/folke/which-key.nvim/commit/1491c355ec9bb0ec4c8e71c8625bc5f55a54b925))
|
||||
* only create mappings for builtin operators. plugings will always have their own mappings ([1b2ec76](https://github.com/folke/which-key.nvim/commit/1b2ec760d65ce9eda473879bec5c31c4771079e7))
|
||||
* only enable plugins that are specified in the configuration ([b8ed0e8](https://github.com/folke/which-key.nvim/commit/b8ed0e8e675b747ce21aa830c38ddf4fb2458e05))
|
||||
* only show message about existing <leader> mapping in NORMAL mode [#75](https://github.com/folke/which-key.nvim/issues/75) ([bcc8297](https://github.com/folke/which-key.nvim/commit/bcc829775b7d366f61bd2db1753e2c6b3d1ec4d3))
|
||||
* only show up/down when scrolling is posible (fixes [#4](https://github.com/folke/which-key.nvim/issues/4)) ([9e7986d](https://github.com/folke/which-key.nvim/commit/9e7986d8726291ee93ef448ae8c452981f1fc75f))
|
||||
* override <leader> if it's mapped to <nop> ([928288b](https://github.com/folke/which-key.nvim/commit/928288b543d77c38ade936ee8bdef32a769ebe3a))
|
||||
* pass + and * regsiters to feedkeys [#36](https://github.com/folke/which-key.nvim/issues/36) ([ce37f41](https://github.com/folke/which-key.nvim/commit/ce37f41641edb90bf51b975999553d13961ed8fa))
|
||||
* pass 0 instead of nil for current buffer ([#227](https://github.com/folke/which-key.nvim/issues/227)) ([387fd67](https://github.com/folke/which-key.nvim/commit/387fd676d3f9b419d38890820f6e262dc0fadb46))
|
||||
* passing registers in INSERT mode, is not by pasting them 😅 [#62](https://github.com/folke/which-key.nvim/issues/62) ([342c8cd](https://github.com/folke/which-key.nvim/commit/342c8cdb3651967c96c356eb2d79561c0c9273ee))
|
||||
* place popup correctly respecting cmdheight [#28](https://github.com/folke/which-key.nvim/issues/28) ([490e4d5](https://github.com/folke/which-key.nvim/commit/490e4d55315b74c63a63ada89ecf0e660a94db9a))
|
||||
* possible nil value in health check ([b1627ca](https://github.com/folke/which-key.nvim/commit/b1627caa25e24c580bbc88377942353875f93a41))
|
||||
* possible recursion ([f7fef32](https://github.com/folke/which-key.nvim/commit/f7fef32701aba0a822ac0a82679aea454bec702f))
|
||||
* prevent double escaping of key codes ([1676611](https://github.com/folke/which-key.nvim/commit/167661151204ea7da2d365113a76ab223b3dc880))
|
||||
* properly escape sequence ([2473329](https://github.com/folke/which-key.nvim/commit/24733293bb7b28f3d98d4a88323eb13cbe5b46f2))
|
||||
* properly escape terminal chars to see if we already hooked a trigger ([1bee8a1](https://github.com/folke/which-key.nvim/commit/1bee8a151e72e5738d813964492248c9bbc4c5ba))
|
||||
* properly format unicode text in columns (fixes [#66](https://github.com/folke/which-key.nvim/issues/66)) ([e3066fa](https://github.com/folke/which-key.nvim/commit/e3066facb6ed91ac013e4ff8faf24997ed44459c))
|
||||
* properly handle < chatracters (should be <lt>) ([e618f84](https://github.com/folke/which-key.nvim/commit/e618f8403e615d4344f2964839ee0e2013b4253e))
|
||||
* properly handle < when loading WK [#16](https://github.com/folke/which-key.nvim/issues/16) ([6cf68b4](https://github.com/folke/which-key.nvim/commit/6cf68b49d48f2e07b82aee18ad01c4115d9ce0e5))
|
||||
* properly handle <lt> when executing keys (fixes [#16](https://github.com/folke/which-key.nvim/issues/16) again) ([8500ebf](https://github.com/folke/which-key.nvim/commit/8500ebf69e30629fc0e00f4b52afefc0cfe38379))
|
||||
* properly handle buffer=0 as the current buffer. Fixes [#91](https://github.com/folke/which-key.nvim/issues/91) ([9ea98e5](https://github.com/folke/which-key.nvim/commit/9ea98e59ddeeafc9181815dd714bea513b298e33))
|
||||
* properly handle selected regsiters when executing keys [#36](https://github.com/folke/which-key.nvim/issues/36) ([5248a2d](https://github.com/folke/which-key.nvim/commit/5248a2db7e46803e8d8786f84b05280116cec707))
|
||||
* properly parse internal key codes and key notation ([535703c](https://github.com/folke/which-key.nvim/commit/535703cd4f08623e12458b5522be1f4ec2a878e7))
|
||||
* redraw after nvim_echo to fix issue with cmdheight=0 ([abcc2c6](https://github.com/folke/which-key.nvim/commit/abcc2c63f723b69c0b31ccacdfddbaf3a03e2c12))
|
||||
* registers plugin for visual mode ([86a58ea](https://github.com/folke/which-key.nvim/commit/86a58eac6a3bc69f5aa373b29df993d14fda3307))
|
||||
* remove unnecessary replacement of backslash ([#284](https://github.com/folke/which-key.nvim/issues/284)) ([7afe584](https://github.com/folke/which-key.nvim/commit/7afe58460305bc68515858c22d39368bc75984b3))
|
||||
* removed debug code ([2f823b8](https://github.com/folke/which-key.nvim/commit/2f823b87293657b5c34cf94a0ef72af02d0117e7))
|
||||
* removed feedkeys as typed, since some normal mappings stop working ([e6a63ec](https://github.com/folke/which-key.nvim/commit/e6a63ec73efffdc63ee9da84d8a1dd1cbdff4650))
|
||||
* removed triggers_nowait from README since this really only makes sense for plugins ([69fcfff](https://github.com/folke/which-key.nvim/commit/69fcfffe48f859b4192c111756221f967c8876b5))
|
||||
* Reset `+` and `*` to default register when clipboard is set ([#233](https://github.com/folke/which-key.nvim/issues/233)) ([8154e65](https://github.com/folke/which-key.nvim/commit/8154e6552ef3188efb6c68d968791ac90e8f2b76))
|
||||
* reset op_count when it's 0 ([e3ad7c9](https://github.com/folke/which-key.nvim/commit/e3ad7c92743b9168abbe974100909e7e761bdacd))
|
||||
* set noautocmd on the WhichKey window, so it works properly for other floats like Telescope ([36fdfe8](https://github.com/folke/which-key.nvim/commit/36fdfe833207c120997c669a2c51060813f2f8a7))
|
||||
* set scheduled instantly ([dc9c3be](https://github.com/folke/which-key.nvim/commit/dc9c3be7acae2a486c117f5a9f6ada62b2243336))
|
||||
* show correct level and sort on keys / group ([a372c63](https://github.com/folke/which-key.nvim/commit/a372c63d5551a3656b7fa4388bdaf456d0d2cbb5))
|
||||
* show error when setup was not run ([194f788](https://github.com/folke/which-key.nvim/commit/194f788cae6b41fe7edf362b6030237a1c221beb))
|
||||
* sort keys case insensitive [#25](https://github.com/folke/which-key.nvim/issues/25) ([e26be8c](https://github.com/folke/which-key.nvim/commit/e26be8c3cb876d634545ed7013c69f45f4e9375c))
|
||||
* special handling needed when <leader> = <bslash> [#40](https://github.com/folke/which-key.nvim/issues/40) ([c4a59d7](https://github.com/folke/which-key.nvim/commit/c4a59d76135563ea73beb87cf0d6d7a3302563be))
|
||||
* start of visual selection mark should be <lt> instead of < [#69](https://github.com/folke/which-key.nvim/issues/69) ([840311c](https://github.com/folke/which-key.nvim/commit/840311c272eda2c4fc0d92070e9ef2dd13f884e7))
|
||||
* typo ([4bacbfd](https://github.com/folke/which-key.nvim/commit/4bacbfdacb9eebee339d36243fe17b9185ccbb74))
|
||||
* use buffer instead of bufnr + added warning ([df49a59](https://github.com/folke/which-key.nvim/commit/df49a59efdfd6a90f412aa251914183fec8593af))
|
||||
* use Comment as fallback color for the Separator ([7ee35a7](https://github.com/folke/which-key.nvim/commit/7ee35a7614e34e562fd3f815ad35bd6d7e456093))
|
||||
* use config.key_labels for cmdline trail as well (Fixes [#108](https://github.com/folke/which-key.nvim/issues/108)) ([1872dd8](https://github.com/folke/which-key.nvim/commit/1872dd8ca9daa0f6478a7771087aedae8518cb97))
|
||||
* use mode instead of redraw when cmdheight=0. (Fixes [#327](https://github.com/folke/which-key.nvim/issues/327)) ([c966279](https://github.com/folke/which-key.nvim/commit/c96627900191355e6788629bbf5239d7295221f0))
|
||||
* use secret nop bindings to make sure timeoutlen is always respected ([eccd5f8](https://github.com/folke/which-key.nvim/commit/eccd5f8bf22e60620eee833946638b90552c9b69))
|
||||
* use strwidth instead of strdisplaywidth ([386591e](https://github.com/folke/which-key.nvim/commit/386591e24afe88c1c52c2291d450e7d7ad9cf02a))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* as long as we didnt finish loading, queue registers ([1bac978](https://github.com/folke/which-key.nvim/commit/1bac978464fd00dddbeee9c5584120f553b1a660))
|
||||
* defer loading to VimEnter and only process hooks once when ready ([84ddcdc](https://github.com/folke/which-key.nvim/commit/84ddcdcd862c4bb6dcac84a876f66f9777ecef7c))
|
||||
* no need to create triggers for all levels. first level that is not a cmd is enough ([3cc0424](https://github.com/folke/which-key.nvim/commit/3cc042498db5792b8f3b081310926c779c7aac07))
|
||||
* no need to hook buffer-local if we have a global hook for a certain prefix ([bb5e0d9](https://github.com/folke/which-key.nvim/commit/bb5e0d9be9c73b7d343ff4bf0ffbb9b6b4696811))
|
||||
* only load modules when needed ([6f8ae23](https://github.com/folke/which-key.nvim/commit/6f8ae23540bc5f980862d2d5aa6d3c02bb1e2da0))
|
||||
201
config/neovim/store/lazy-plugins/which-key.nvim/LICENSE
Normal file
201
config/neovim/store/lazy-plugins/which-key.nvim/LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
367
config/neovim/store/lazy-plugins/which-key.nvim/README.md
Normal file
367
config/neovim/store/lazy-plugins/which-key.nvim/README.md
Normal file
@ -0,0 +1,367 @@
|
||||
# 💥 Which Key
|
||||
|
||||
**WhichKey** is a lua plugin for Neovim 0.5 that displays a popup with possible key bindings of
|
||||
the command you started typing. Heavily inspired by the original [emacs-which-key](https://github.com/justbur/emacs-which-key) and [vim-which-key](https://github.com/liuchengxu/vim-which-key).
|
||||
|
||||

|
||||
|
||||
## ✨ Features
|
||||
|
||||
- for Neovim 0.7 and higher, it uses the `desc` attributes of your mappings as the default label
|
||||
- for Neovim 0.7 and higher, new mappings will be created with a `desc` attribute
|
||||
- opens a popup with suggestions to complete a key binding
|
||||
- works with any setting for [timeoutlen](https://neovim.io/doc/user/options.html#'timeoutlen'), including instantly (`timeoutlen=0`)
|
||||
- works correctly with built-in key bindings
|
||||
- works correctly with buffer-local mappings
|
||||
- extensible plugin architecture
|
||||
- built-in plugins:
|
||||
- **marks:** shows your marks when you hit one of the jump keys.
|
||||
- **registers:** shows the contents of your registers
|
||||
- **presets:** built-in key binding help for `motions`, `text-objects`, `operators`, `windows`, `nav`, `z` and `g`
|
||||
- **spelling:** spelling suggestions inside the which-key popup
|
||||
|
||||
## ⚡️ Requirements
|
||||
|
||||
- Neovim >= 0.5.0
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
Install the plugin with your preferred package manager:
|
||||
|
||||
### [lazy.nvim](https://github.com/folke/lazy.nvim)
|
||||
|
||||
```lua
|
||||
{
|
||||
"folke/which-key.nvim",
|
||||
event = "VeryLazy",
|
||||
init = function()
|
||||
vim.o.timeout = true
|
||||
vim.o.timeoutlen = 300
|
||||
end,
|
||||
opts = {
|
||||
-- your configuration comes here
|
||||
-- or leave it empty to use the default settings
|
||||
-- refer to the configuration section below
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### [packer](https://github.com/wbthomason/packer.nvim)
|
||||
|
||||
```lua
|
||||
-- Lua
|
||||
use {
|
||||
"folke/which-key.nvim",
|
||||
config = function()
|
||||
vim.o.timeout = true
|
||||
vim.o.timeoutlen = 300
|
||||
require("which-key").setup {
|
||||
-- your configuration comes here
|
||||
-- or leave it empty to use the default settings
|
||||
-- refer to the configuration section below
|
||||
}
|
||||
end
|
||||
}
|
||||
```
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
> ❗️ IMPORTANT: the [timeout](https://neovim.io/doc/user/options.html#'timeout') when **WhichKey** opens is controlled by the vim setting [timeoutlen](https://neovim.io/doc/user/options.html#'timeoutlen').
|
||||
> Please refer to the documentation to properly set it up. Setting it to `0`, will effectively
|
||||
> always show **WhichKey** immediately, but a setting of `500` (500ms) is probably more appropriate.
|
||||
|
||||
> ❗️ don't create any keymappings yourself to trigger WhichKey. Unlike with _vim-which-key_, we do this fully automatically.
|
||||
> Please remove any left-over triggers you might have from using _vim-which-key_.
|
||||
|
||||
> 🚑 You can run `:checkhealth which-key` to see if there's any conflicting keymaps that will prevent triggering **WhichKey**
|
||||
|
||||
WhichKey comes with the following defaults:
|
||||
|
||||
```lua
|
||||
{
|
||||
plugins = {
|
||||
marks = true, -- shows a list of your marks on ' and `
|
||||
registers = true, -- shows your registers on " in NORMAL or <C-r> in INSERT mode
|
||||
-- the presets plugin, adds help for a bunch of default keybindings in Neovim
|
||||
-- No actual key bindings are created
|
||||
spelling = {
|
||||
enabled = true, -- enabling this will show WhichKey when pressing z= to select spelling suggestions
|
||||
suggestions = 20, -- how many suggestions should be shown in the list?
|
||||
},
|
||||
presets = {
|
||||
operators = true, -- adds help for operators like d, y, ...
|
||||
motions = true, -- adds help for motions
|
||||
text_objects = true, -- help for text objects triggered after entering an operator
|
||||
windows = true, -- default bindings on <c-w>
|
||||
nav = true, -- misc bindings to work with windows
|
||||
z = true, -- bindings for folds, spelling and others prefixed with z
|
||||
g = true, -- bindings for prefixed with g
|
||||
},
|
||||
},
|
||||
-- add operators that will trigger motion and text object completion
|
||||
-- to enable all native operators, set the preset / operators plugin above
|
||||
operators = { gc = "Comments" },
|
||||
key_labels = {
|
||||
-- override the label used to display some keys. It doesn't effect WK in any other way.
|
||||
-- For example:
|
||||
-- ["<space>"] = "SPC",
|
||||
-- ["<cr>"] = "RET",
|
||||
-- ["<tab>"] = "TAB",
|
||||
},
|
||||
motions = {
|
||||
count = true,
|
||||
},
|
||||
icons = {
|
||||
breadcrumb = "»", -- symbol used in the command line area that shows your active key combo
|
||||
separator = "➜", -- symbol used between a key and it's label
|
||||
group = "+", -- symbol prepended to a group
|
||||
},
|
||||
popup_mappings = {
|
||||
scroll_down = "<c-d>", -- binding to scroll down inside the popup
|
||||
scroll_up = "<c-u>", -- binding to scroll up inside the popup
|
||||
},
|
||||
window = {
|
||||
border = "none", -- none, single, double, shadow
|
||||
position = "bottom", -- bottom, top
|
||||
margin = { 1, 0, 1, 0 }, -- extra window margin [top, right, bottom, left]. When between 0 and 1, will be treated as a percentage of the screen size.
|
||||
padding = { 1, 2, 1, 2 }, -- extra window padding [top, right, bottom, left]
|
||||
winblend = 0, -- value between 0-100 0 for fully opaque and 100 for fully transparent
|
||||
zindex = 1000, -- positive value to position WhichKey above other floating windows.
|
||||
},
|
||||
layout = {
|
||||
height = { min = 4, max = 25 }, -- min and max height of the columns
|
||||
width = { min = 20, max = 50 }, -- min and max width of the columns
|
||||
spacing = 3, -- spacing between columns
|
||||
align = "left", -- align columns left, center or right
|
||||
},
|
||||
ignore_missing = false, -- enable this to hide mappings for which you didn't specify a label
|
||||
hidden = { "<silent>", "<cmd>", "<Cmd>", "<CR>", "^:", "^ ", "^call ", "^lua " }, -- hide mapping boilerplate
|
||||
show_help = true, -- show a help message in the command line for using WhichKey
|
||||
show_keys = true, -- show the currently pressed key and its label as a message in the command line
|
||||
triggers = "auto", -- automatically setup triggers
|
||||
-- triggers = {"<leader>"} -- or specifiy a list manually
|
||||
-- list of triggers, where WhichKey should not wait for timeoutlen and show immediately
|
||||
triggers_nowait = {
|
||||
-- marks
|
||||
"`",
|
||||
"'",
|
||||
"g`",
|
||||
"g'",
|
||||
-- registers
|
||||
'"',
|
||||
"<c-r>",
|
||||
-- spelling
|
||||
"z=",
|
||||
},
|
||||
triggers_blacklist = {
|
||||
-- list of mode / prefixes that should never be hooked by WhichKey
|
||||
-- this is mostly relevant for keymaps that start with a native binding
|
||||
i = { "j", "k" },
|
||||
v = { "j", "k" },
|
||||
},
|
||||
-- disable the WhichKey popup for certain buf types and file types.
|
||||
-- Disabled by default for Telescope
|
||||
disable = {
|
||||
buftypes = {},
|
||||
filetypes = {},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## 🪄 Setup
|
||||
|
||||
With the default settings, **WhichKey** will work out of the box for most builtin keybindings,
|
||||
but the real power comes from documenting and organizing your own keybindings.
|
||||
|
||||
To document and/or setup your own mappings, you need to call the `register` method
|
||||
|
||||
```lua
|
||||
local wk = require("which-key")
|
||||
wk.register(mappings, opts)
|
||||
```
|
||||
|
||||
Default options for `opts`
|
||||
|
||||
```lua
|
||||
{
|
||||
mode = "n", -- NORMAL mode
|
||||
-- prefix: use "<leader>f" for example for mapping everything related to finding files
|
||||
-- the prefix is prepended to every mapping part of `mappings`
|
||||
prefix = "",
|
||||
buffer = nil, -- Global mappings. Specify a buffer number for buffer local mappings
|
||||
silent = true, -- use `silent` when creating keymaps
|
||||
noremap = true, -- use `noremap` when creating keymaps
|
||||
nowait = false, -- use `nowait` when creating keymaps
|
||||
expr = false, -- use `expr` when creating keymaps
|
||||
}
|
||||
```
|
||||
|
||||
> ❕ When you specify a command in your mapping that starts with `<Plug>`, then we automatically set `noremap=false`, since you always want recursive keybindings in this case
|
||||
|
||||
### ⌨️ Mappings
|
||||
|
||||
> ⌨ for **Neovim 0.7** and higher, which key will use the `desc` attribute of existing mappings as the default label
|
||||
|
||||
Group names use the special `name` key in the tables. There's multiple ways to define the mappings. `wk.register` can be called multiple times from anywhere in your config files.
|
||||
|
||||
```lua
|
||||
local wk = require("which-key")
|
||||
-- As an example, we will create the following mappings:
|
||||
-- * <leader>ff find files
|
||||
-- * <leader>fr show recent files
|
||||
-- * <leader>fb Foobar
|
||||
-- we'll document:
|
||||
-- * <leader>fn new file
|
||||
-- * <leader>fe edit file
|
||||
-- and hide <leader>1
|
||||
|
||||
wk.register({
|
||||
f = {
|
||||
name = "file", -- optional group name
|
||||
f = { "<cmd>Telescope find_files<cr>", "Find File" }, -- create a binding with label
|
||||
r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File", noremap=false, buffer = 123 }, -- additional options for creating the keymap
|
||||
n = { "New File" }, -- just a label. don't create any mapping
|
||||
e = "Edit File", -- same as above
|
||||
["1"] = "which_key_ignore", -- special label to hide it in the popup
|
||||
b = { function() print("bar") end, "Foobar" } -- you can also pass functions!
|
||||
},
|
||||
}, { prefix = "<leader>" })
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Click to see more examples</summary>
|
||||
|
||||
```lua
|
||||
-- all of the mappings below are equivalent
|
||||
|
||||
-- method 2
|
||||
wk.register({
|
||||
["<leader>"] = {
|
||||
f = {
|
||||
name = "+file",
|
||||
f = { "<cmd>Telescope find_files<cr>", "Find File" },
|
||||
r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },
|
||||
n = { "<cmd>enew<cr>", "New File" },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- method 3
|
||||
wk.register({
|
||||
["<leader>f"] = {
|
||||
name = "+file",
|
||||
f = { "<cmd>Telescope find_files<cr>", "Find File" },
|
||||
r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },
|
||||
n = { "<cmd>enew<cr>", "New File" },
|
||||
},
|
||||
})
|
||||
|
||||
-- method 4
|
||||
wk.register({
|
||||
["<leader>f"] = { name = "+file" },
|
||||
["<leader>ff"] = { "<cmd>Telescope find_files<cr>", "Find File" },
|
||||
["<leader>fr"] = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },
|
||||
["<leader>fn"] = { "<cmd>enew<cr>", "New File" },
|
||||
})
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
**Tips:** The default label is `keymap.desc` or `keymap.rhs` or `""`,
|
||||
`:h nvim_set_keymap()` to get more details about `desc` and `rhs`.
|
||||
|
||||
### 🚙 Operators, Motions and Text Objects
|
||||
|
||||
**WhichKey** provides help to work with operators, motions and text objects.
|
||||
|
||||
> `[count]operator[count][text-object]`
|
||||
|
||||
- operators can be configured with the `operators` option
|
||||
- set `plugins.presets.operators` to `true` to automatically configure vim built-in operators
|
||||
- set this to `false`, to only include the list you configured in the `operators` option.
|
||||
- see [here](https://github.com/folke/which-key.nvim/blob/main/lua/which-key/plugins/presets/init.lua#L5) for the full list part of the preset
|
||||
- text objects are automatically retrieved from **operator pending** key maps (`omap`)
|
||||
- set `plugins.presets.text_objects` to `true` to configure built-in text objects
|
||||
- see [here](https://github.com/folke/which-key.nvim/blob/main/lua/which-key/plugins/presets/init.lua#L43)
|
||||
- motions are part of the preset `plugins.presets.motions` setting
|
||||
- see [here](https://github.com/folke/which-key.nvim/blob/main/lua/which-key/plugins/presets/init.lua#L20)
|
||||
|
||||
<details>
|
||||
<summary>How to disable some operators? (like v)</summary>
|
||||
|
||||
```lua
|
||||
-- make sure to run this code before calling setup()
|
||||
-- refer to the full lists at https://github.com/folke/which-key.nvim/blob/main/lua/which-key/plugins/presets/init.lua
|
||||
local presets = require("which-key.plugins.presets")
|
||||
presets.operators["v"] = nil
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## 🚀 Usage
|
||||
|
||||
When the **WhichKey** popup is open, you can use the following key bindings (they are also displayed at the bottom of the screen):
|
||||
|
||||
- hit one of the keys to open a group or execute a key binding
|
||||
- `<esc>` to cancel and close the popup
|
||||
- `<bs>` go up one level
|
||||
- `<c-d>` scroll down
|
||||
- `<c-u>` scroll up
|
||||
|
||||
Apart from the automatic opening, you can also manually open **WhichKey** for a certain `prefix`:
|
||||
|
||||
> ❗️ don't create any keymappings yourself to trigger WhichKey. Unlike with _vim-which-key_, we do this fully automatically.
|
||||
> Please remove any left-over triggers you might have from using _vim-which-key_.
|
||||
|
||||
```vim
|
||||
:WhichKey " show all mappings
|
||||
:WhichKey <leader> " show all <leader> mappings
|
||||
:WhichKey <leader> v " show all <leader> mappings for VISUAL mode
|
||||
:WhichKey '' v " show ALL mappings for VISUAL mode
|
||||
```
|
||||
|
||||
## 🔥 Plugins
|
||||
|
||||
Four built-in plugins are included with **WhichKey**.
|
||||
|
||||
### Marks
|
||||
|
||||
Shows a list of your buffer local and global marks when you hit \` or '
|
||||
|
||||

|
||||
|
||||
### Registers
|
||||
|
||||
Shows a list of your buffer local and global registers when you hit " in _NORMAL_ mode, or `<c-r>` in _INSERT_ mode.
|
||||
|
||||

|
||||
|
||||
### Presets
|
||||
|
||||
Built-in key binding help for `motions`, `text-objects`, `operators`, `windows`, `nav`, `z` and `g`
|
||||
|
||||

|
||||
|
||||
### Spelling
|
||||
|
||||
When enabled, this plugin hooks into `z=` and replaces the full-screen spelling suggestions window by a list of suggestions within **WhichKey**.
|
||||
|
||||

|
||||
|
||||
## 🎨 Colors
|
||||
|
||||
The table below shows all the highlight groups defined for **WhichKey** with their default link.
|
||||
|
||||
| Highlight Group | Defaults to | Description |
|
||||
| ------------------- | ----------- | ------------------------------------------- |
|
||||
| _WhichKey_ | Function | the key |
|
||||
| _WhichKeyGroup_ | Keyword | a group |
|
||||
| _WhichKeySeparator_ | DiffAdd | the separator between the key and its label |
|
||||
| _WhichKeyDesc_ | Identifier | the label of the key |
|
||||
| _WhichKeyFloat_ | NormalFloat | Normal in the popup window |
|
||||
| _WhichKeyBorder_ | FloatBorder | Normal in the popup window |
|
||||
| _WhichKeyValue_ | Comment | used by plugins that provide values |
|
||||
|
||||
<!-- markdownlint-disable-file MD033 -->
|
||||
<!-- markdownlint-configure-file { "MD013": { "line_length": 120 } } -->
|
||||
<!-- markdownlint-configure-file { "MD004": { "style": "sublist" } } -->
|
||||
21
config/neovim/store/lazy-plugins/which-key.nvim/TODO.md
Normal file
21
config/neovim/store/lazy-plugins/which-key.nvim/TODO.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Todo
|
||||
|
||||
* [x] hook into all groups
|
||||
* [x] show mappings without keymap (zz etc)
|
||||
* [x] plugin support for marks, registers, text objects
|
||||
* [x] `<bs>` to go up a level
|
||||
* [x] config modes
|
||||
* [x] update buf only
|
||||
* [x] + thingy for groups
|
||||
* [x] text objects
|
||||
* [x] get label from global when not found for buffer
|
||||
* [x] operators & motions
|
||||
* [x] show window after timeout?
|
||||
* [x] make plugins a list of key value with config in value
|
||||
* [x] cleanup text objects text
|
||||
* [x] buf local mappings seems to interfere with global mappings (push K in help)
|
||||
* [x] fix help in visual mode
|
||||
* [x] Plug>whichkey nop
|
||||
* [x] preset plugin
|
||||
* [x] command should auto stuff
|
||||
* [x] timeoutlen is always respected and should still work when zero
|
||||
@ -0,0 +1,419 @@
|
||||
*which-key.nvim.txt* For Neovim >= 0.8.0 Last change: 2023 October 20
|
||||
|
||||
==============================================================================
|
||||
Table of Contents *which-key.nvim-table-of-contents*
|
||||
|
||||
1. Which Key |which-key.nvim-which-key|
|
||||
- Features |which-key.nvim-which-key-features|
|
||||
- Requirements |which-key.nvim-which-key-requirements|
|
||||
- Installation |which-key.nvim-which-key-installation|
|
||||
- Configuration |which-key.nvim-which-key-configuration|
|
||||
- Setup |which-key.nvim-which-key-setup|
|
||||
- Usage |which-key.nvim-which-key-usage|
|
||||
- Plugins |which-key.nvim-which-key-plugins|
|
||||
- Colors |which-key.nvim-which-key-colors|
|
||||
|
||||
==============================================================================
|
||||
1. Which Key *which-key.nvim-which-key*
|
||||
|
||||
**WhichKey** is a lua plugin for Neovim 0.5 that displays a popup with possible
|
||||
key bindings of the command you started typing. Heavily inspired by the
|
||||
original emacs-which-key <https://github.com/justbur/emacs-which-key> and
|
||||
vim-which-key <https://github.com/liuchengxu/vim-which-key>.
|
||||
|
||||
|
||||
FEATURES *which-key.nvim-which-key-features*
|
||||
|
||||
- for Neovim 0.7 and higher, it uses the `desc` attributes of your mappings as the default label
|
||||
- for Neovim 0.7 and higher, new mappings will be created with a `desc` attribute
|
||||
- opens a popup with suggestions to complete a key binding
|
||||
- works with any setting for |timeoutlen|, including instantly (`timeoutlen=0`)
|
||||
- works correctly with built-in key bindings
|
||||
- works correctly with buffer-local mappings
|
||||
- extensible plugin architecture
|
||||
- built-in plugins:
|
||||
- **marks:** shows your marks when you hit one of the jump keys.
|
||||
- **registers:** shows the contents of your registers
|
||||
- **presets:** built-in key binding help for `motions`, `text-objects`, `operators`, `windows`, `nav`, `z` and `g`
|
||||
- **spelling:** spelling suggestions inside the which-key popup
|
||||
|
||||
|
||||
REQUIREMENTS *which-key.nvim-which-key-requirements*
|
||||
|
||||
- Neovim >= 0.5.0
|
||||
|
||||
|
||||
INSTALLATION *which-key.nvim-which-key-installation*
|
||||
|
||||
Install the plugin with your preferred package manager:
|
||||
|
||||
|
||||
LAZY.NVIM ~
|
||||
|
||||
>lua
|
||||
{
|
||||
"folke/which-key.nvim",
|
||||
event = "VeryLazy",
|
||||
init = function()
|
||||
vim.o.timeout = true
|
||||
vim.o.timeoutlen = 300
|
||||
end,
|
||||
opts = {
|
||||
-- your configuration comes here
|
||||
-- or leave it empty to use the default settings
|
||||
-- refer to the configuration section below
|
||||
}
|
||||
}
|
||||
<
|
||||
|
||||
|
||||
PACKER ~
|
||||
|
||||
>lua
|
||||
-- Lua
|
||||
use {
|
||||
"folke/which-key.nvim",
|
||||
config = function()
|
||||
vim.o.timeout = true
|
||||
vim.o.timeoutlen = 300
|
||||
require("which-key").setup {
|
||||
-- your configuration comes here
|
||||
-- or leave it empty to use the default settings
|
||||
-- refer to the configuration section below
|
||||
}
|
||||
end
|
||||
}
|
||||
<
|
||||
|
||||
|
||||
CONFIGURATION *which-key.nvim-which-key-configuration*
|
||||
|
||||
|
||||
IMPORTANT: the |timeout| when **WhichKey** opens is controlled by the vim
|
||||
setting |timeoutlen|. Please refer to the documentation to properly set it up.
|
||||
Setting it to `0`, will effectively always show **WhichKey** immediately, but a
|
||||
setting of `500` (500ms) is probably more appropriate.
|
||||
|
||||
don’t create any keymappings yourself to trigger WhichKey. Unlike with
|
||||
_vim-which-key_, we do this fully automatically. Please remove any left-over
|
||||
triggers you might have from using _vim-which-key_.
|
||||
|
||||
You can run `:checkhealth which-key` to see if there’s any conflicting
|
||||
keymaps that will prevent triggering **WhichKey**
|
||||
WhichKey comes with the following defaults:
|
||||
|
||||
>lua
|
||||
{
|
||||
plugins = {
|
||||
marks = true, -- shows a list of your marks on ' and `
|
||||
registers = true, -- shows your registers on " in NORMAL or <C-r> in INSERT mode
|
||||
-- the presets plugin, adds help for a bunch of default keybindings in Neovim
|
||||
-- No actual key bindings are created
|
||||
spelling = {
|
||||
enabled = true, -- enabling this will show WhichKey when pressing z= to select spelling suggestions
|
||||
suggestions = 20, -- how many suggestions should be shown in the list?
|
||||
},
|
||||
presets = {
|
||||
operators = true, -- adds help for operators like d, y, ...
|
||||
motions = true, -- adds help for motions
|
||||
text_objects = true, -- help for text objects triggered after entering an operator
|
||||
windows = true, -- default bindings on <c-w>
|
||||
nav = true, -- misc bindings to work with windows
|
||||
z = true, -- bindings for folds, spelling and others prefixed with z
|
||||
g = true, -- bindings for prefixed with g
|
||||
},
|
||||
},
|
||||
-- add operators that will trigger motion and text object completion
|
||||
-- to enable all native operators, set the preset / operators plugin above
|
||||
operators = { gc = "Comments" },
|
||||
key_labels = {
|
||||
-- override the label used to display some keys. It doesn't effect WK in any other way.
|
||||
-- For example:
|
||||
-- ["<space>"] = "SPC",
|
||||
-- ["<cr>"] = "RET",
|
||||
-- ["<tab>"] = "TAB",
|
||||
},
|
||||
motions = {
|
||||
count = true,
|
||||
},
|
||||
icons = {
|
||||
breadcrumb = "»", -- symbol used in the command line area that shows your active key combo
|
||||
separator = "➜", -- symbol used between a key and it's label
|
||||
group = "+", -- symbol prepended to a group
|
||||
},
|
||||
popup_mappings = {
|
||||
scroll_down = "<c-d>", -- binding to scroll down inside the popup
|
||||
scroll_up = "<c-u>", -- binding to scroll up inside the popup
|
||||
},
|
||||
window = {
|
||||
border = "none", -- none, single, double, shadow
|
||||
position = "bottom", -- bottom, top
|
||||
margin = { 1, 0, 1, 0 }, -- extra window margin [top, right, bottom, left]. When between 0 and 1, will be treated as a percentage of the screen size.
|
||||
padding = { 1, 2, 1, 2 }, -- extra window padding [top, right, bottom, left]
|
||||
winblend = 0, -- value between 0-100 0 for fully opaque and 100 for fully transparent
|
||||
zindex = 1000, -- positive value to position WhichKey above other floating windows.
|
||||
},
|
||||
layout = {
|
||||
height = { min = 4, max = 25 }, -- min and max height of the columns
|
||||
width = { min = 20, max = 50 }, -- min and max width of the columns
|
||||
spacing = 3, -- spacing between columns
|
||||
align = "left", -- align columns left, center or right
|
||||
},
|
||||
ignore_missing = false, -- enable this to hide mappings for which you didn't specify a label
|
||||
hidden = { "<silent>", "<cmd>", "<Cmd>", "<CR>", "^:", "^ ", "^call ", "^lua " }, -- hide mapping boilerplate
|
||||
show_help = true, -- show a help message in the command line for using WhichKey
|
||||
show_keys = true, -- show the currently pressed key and its label as a message in the command line
|
||||
triggers = "auto", -- automatically setup triggers
|
||||
-- triggers = {"<leader>"} -- or specifiy a list manually
|
||||
-- list of triggers, where WhichKey should not wait for timeoutlen and show immediately
|
||||
triggers_nowait = {
|
||||
-- marks
|
||||
"`",
|
||||
"'",
|
||||
"g`",
|
||||
"g'",
|
||||
-- registers
|
||||
'"',
|
||||
"<c-r>",
|
||||
-- spelling
|
||||
"z=",
|
||||
},
|
||||
triggers_blacklist = {
|
||||
-- list of mode / prefixes that should never be hooked by WhichKey
|
||||
-- this is mostly relevant for keymaps that start with a native binding
|
||||
i = { "j", "k" },
|
||||
v = { "j", "k" },
|
||||
},
|
||||
-- disable the WhichKey popup for certain buf types and file types.
|
||||
-- Disabled by default for Telescope
|
||||
disable = {
|
||||
buftypes = {},
|
||||
filetypes = {},
|
||||
},
|
||||
}
|
||||
<
|
||||
|
||||
|
||||
SETUP *which-key.nvim-which-key-setup*
|
||||
|
||||
With the default settings, **WhichKey** will work out of the box for most
|
||||
builtin keybindings, but the real power comes from documenting and organizing
|
||||
your own keybindings.
|
||||
|
||||
To document and/or setup your own mappings, you need to call the `register`
|
||||
method
|
||||
|
||||
>lua
|
||||
local wk = require("which-key")
|
||||
wk.register(mappings, opts)
|
||||
<
|
||||
|
||||
Default options for `opts`
|
||||
|
||||
>lua
|
||||
{
|
||||
mode = "n", -- NORMAL mode
|
||||
-- prefix: use "<leader>f" for example for mapping everything related to finding files
|
||||
-- the prefix is prepended to every mapping part of `mappings`
|
||||
prefix = "",
|
||||
buffer = nil, -- Global mappings. Specify a buffer number for buffer local mappings
|
||||
silent = true, -- use `silent` when creating keymaps
|
||||
noremap = true, -- use `noremap` when creating keymaps
|
||||
nowait = false, -- use `nowait` when creating keymaps
|
||||
expr = false, -- use `expr` when creating keymaps
|
||||
}
|
||||
<
|
||||
|
||||
|
||||
When you specify a command in your mapping that starts with `<Plug>`, then we
|
||||
automatically set `noremap=false`, since you always want recursive keybindings
|
||||
in this case
|
||||
|
||||
MAPPINGS ~
|
||||
|
||||
|
||||
for **Neovim 0.7** and higher, which key will use the `desc` attribute of
|
||||
existing mappings as the default label
|
||||
Group names use the special `name` key in the tables. There’s multiple ways
|
||||
to define the mappings. `wk.register` can be called multiple times from
|
||||
anywhere in your config files.
|
||||
|
||||
>lua
|
||||
local wk = require("which-key")
|
||||
-- As an example, we will create the following mappings:
|
||||
-- * <leader>ff find files
|
||||
-- * <leader>fr show recent files
|
||||
-- * <leader>fb Foobar
|
||||
-- we'll document:
|
||||
-- * <leader>fn new file
|
||||
-- * <leader>fe edit file
|
||||
-- and hide <leader>1
|
||||
|
||||
wk.register({
|
||||
f = {
|
||||
name = "file", -- optional group name
|
||||
f = { "<cmd>Telescope find_files<cr>", "Find File" }, -- create a binding with label
|
||||
r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File", noremap=false, buffer = 123 }, -- additional options for creating the keymap
|
||||
n = { "New File" }, -- just a label. don't create any mapping
|
||||
e = "Edit File", -- same as above
|
||||
["1"] = "which_key_ignore", -- special label to hide it in the popup
|
||||
b = { function() print("bar") end, "Foobar" } -- you can also pass functions!
|
||||
},
|
||||
}, { prefix = "<leader>" })
|
||||
<
|
||||
|
||||
Click to see more examples ~
|
||||
|
||||
>lua
|
||||
-- all of the mappings below are equivalent
|
||||
|
||||
-- method 2
|
||||
wk.register({
|
||||
["<leader>"] = {
|
||||
f = {
|
||||
name = "+file",
|
||||
f = { "<cmd>Telescope find_files<cr>", "Find File" },
|
||||
r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },
|
||||
n = { "<cmd>enew<cr>", "New File" },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- method 3
|
||||
wk.register({
|
||||
["<leader>f"] = {
|
||||
name = "+file",
|
||||
f = { "<cmd>Telescope find_files<cr>", "Find File" },
|
||||
r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },
|
||||
n = { "<cmd>enew<cr>", "New File" },
|
||||
},
|
||||
})
|
||||
|
||||
-- method 4
|
||||
wk.register({
|
||||
["<leader>f"] = { name = "+file" },
|
||||
["<leader>ff"] = { "<cmd>Telescope find_files<cr>", "Find File" },
|
||||
["<leader>fr"] = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },
|
||||
["<leader>fn"] = { "<cmd>enew<cr>", "New File" },
|
||||
})
|
||||
<
|
||||
|
||||
**Tips:** The default label is `keymap.desc` or `keymap.rhs` or `""`,
|
||||
|nvim_set_keymap()| to get more details about `desc` and `rhs`.
|
||||
|
||||
|
||||
OPERATORS, MOTIONS AND TEXT OBJECTS ~
|
||||
|
||||
**WhichKey** provides help to work with operators, motions and text objects.
|
||||
|
||||
|
||||
`[count]operator[count][text-object]`
|
||||
- operators can be configured with the `operators` option
|
||||
- set `plugins.presets.operators` to `true` to automatically configure vim built-in operators
|
||||
- set this to `false`, to only include the list you configured in the `operators` option.
|
||||
- see here <https://github.com/folke/which-key.nvim/blob/main/lua/which-key/plugins/presets/init.lua#L5> for the full list part of the preset
|
||||
- text objects are automatically retrieved from **operator pending** key maps (`omap`)
|
||||
- set `plugins.presets.text_objects` to `true` to configure built-in text objects
|
||||
- see here <https://github.com/folke/which-key.nvim/blob/main/lua/which-key/plugins/presets/init.lua#L43>
|
||||
- motions are part of the preset `plugins.presets.motions` setting
|
||||
- see here <https://github.com/folke/which-key.nvim/blob/main/lua/which-key/plugins/presets/init.lua#L20>
|
||||
|
||||
How to disable some operators? (like v) ~
|
||||
|
||||
>lua
|
||||
-- make sure to run this code before calling setup()
|
||||
-- refer to the full lists at https://github.com/folke/which-key.nvim/blob/main/lua/which-key/plugins/presets/init.lua
|
||||
local presets = require("which-key.plugins.presets")
|
||||
presets.operators["v"] = nil
|
||||
<
|
||||
|
||||
|
||||
USAGE *which-key.nvim-which-key-usage*
|
||||
|
||||
When the **WhichKey** popup is open, you can use the following key bindings
|
||||
(they are also displayed at the bottom of the screen):
|
||||
|
||||
- hit one of the keys to open a group or execute a key binding
|
||||
- `<esc>` to cancel and close the popup
|
||||
- `<bs>` go up one level
|
||||
- `<c-d>` scroll down
|
||||
- `<c-u>` scroll up
|
||||
|
||||
Apart from the automatic opening, you can also manually open **WhichKey** for a
|
||||
certain `prefix`
|
||||
|
||||
|
||||
don’t create any keymappings yourself to trigger WhichKey. Unlike with
|
||||
_vim-which-key_, we do this fully automatically. Please remove any left-over
|
||||
triggers you might have from using _vim-which-key_.
|
||||
>vim
|
||||
:WhichKey " show all mappings
|
||||
:WhichKey <leader> " show all <leader> mappings
|
||||
:WhichKey <leader> v " show all <leader> mappings for VISUAL mode
|
||||
:WhichKey '' v " show ALL mappings for VISUAL mode
|
||||
<
|
||||
|
||||
|
||||
PLUGINS *which-key.nvim-which-key-plugins*
|
||||
|
||||
Four built-in plugins are included with **WhichKey**.
|
||||
|
||||
|
||||
MARKS ~
|
||||
|
||||
Shows a list of your buffer local and global marks when you hit ` or ’
|
||||
|
||||
|
||||
REGISTERS ~
|
||||
|
||||
Shows a list of your buffer local and global registers when you hit ” in
|
||||
_NORMAL_ mode, or `<c-r>` in _INSERT_ mode.
|
||||
|
||||
|
||||
PRESETS ~
|
||||
|
||||
Built-in key binding help for `motions`, `text-objects`, `operators`,
|
||||
`windows`, `nav`, `z` and `g`
|
||||
|
||||
|
||||
SPELLING ~
|
||||
|
||||
When enabled, this plugin hooks into `z=` and replaces the full-screen spelling
|
||||
suggestions window by a list of suggestions within **WhichKey**.
|
||||
|
||||
|
||||
COLORS *which-key.nvim-which-key-colors*
|
||||
|
||||
The table below shows all the highlight groups defined for **WhichKey** with
|
||||
their default link.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Highlight Group Defaults to Description
|
||||
------------------- ------------- -----------------------------------------
|
||||
WhichKey Function the key
|
||||
|
||||
WhichKeyGroup Keyword a group
|
||||
|
||||
WhichKeySeparator DiffAdd the separator between the key and its
|
||||
label
|
||||
|
||||
WhichKeyDesc Identifier the label of the key
|
||||
|
||||
WhichKeyFloat NormalFloat Normal in the popup window
|
||||
|
||||
WhichKeyBorder FloatBorder Normal in the popup window
|
||||
|
||||
WhichKeyValue Comment used by plugins that provide values
|
||||
---------------------------------------------------------------------------
|
||||
==============================================================================
|
||||
2. Links *which-key.nvim-links*
|
||||
|
||||
1. *image*: https://user-images.githubusercontent.com/292349/116439438-669f8d00-a804-11eb-9b5b-c7122bd9acac.png
|
||||
2. *image*: https://user-images.githubusercontent.com/292349/116439573-8f278700-a804-11eb-80ca-bb9263e6d937.png
|
||||
3. *image*: https://user-images.githubusercontent.com/292349/116439609-98b0ef00-a804-11eb-9385-97c7d5ff4113.png
|
||||
4. *image*: https://user-images.githubusercontent.com/292349/116439871-df9ee480-a804-11eb-9529-800e167db65c.png
|
||||
5. *image*: https://user-images.githubusercontent.com/292349/118102022-1c361880-b38d-11eb-8e82-79ad266d9bb8.png
|
||||
|
||||
Generated by panvimdoc <https://github.com/kdheepak/panvimdoc>
|
||||
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
@ -0,0 +1,19 @@
|
||||
local M = {}
|
||||
|
||||
local links = {
|
||||
[""] = "Function",
|
||||
Separator = "Comment",
|
||||
Group = "Keyword",
|
||||
Desc = "Identifier",
|
||||
Float = "NormalFloat",
|
||||
Border = "FloatBorder",
|
||||
Value = "Comment",
|
||||
}
|
||||
|
||||
function M.setup()
|
||||
for k, v in pairs(links) do
|
||||
vim.api.nvim_set_hl(0, "WhichKey" .. k, { link = v, default = true })
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,105 @@
|
||||
local M = {}
|
||||
|
||||
M.namespace = vim.api.nvim_create_namespace("WhichKey")
|
||||
|
||||
---@class Options
|
||||
local defaults = {
|
||||
plugins = {
|
||||
marks = true, -- shows a list of your marks on ' and `
|
||||
registers = true, -- shows your registers on " in NORMAL or <C-r> in INSERT mode
|
||||
-- the presets plugin, adds help for a bunch of default keybindings in Neovim
|
||||
-- No actual key bindings are created
|
||||
spelling = {
|
||||
enabled = true, -- enabling this will show WhichKey when pressing z= to select spelling suggestions
|
||||
suggestions = 20, -- how many suggestions should be shown in the list?
|
||||
},
|
||||
presets = {
|
||||
operators = true, -- adds help for operators like d, y, ...
|
||||
motions = true, -- adds help for motions
|
||||
text_objects = true, -- help for text objects triggered after entering an operator
|
||||
windows = true, -- default bindings on <c-w>
|
||||
nav = true, -- misc bindings to work with windows
|
||||
z = true, -- bindings for folds, spelling and others prefixed with z
|
||||
g = true, -- bindings for prefixed with g
|
||||
},
|
||||
},
|
||||
-- add operators that will trigger motion and text object completion
|
||||
-- to enable all native operators, set the preset / operators plugin above
|
||||
operators = { gc = "Comments" },
|
||||
key_labels = {
|
||||
-- override the label used to display some keys. It doesn't effect WK in any other way.
|
||||
-- For example:
|
||||
-- ["<space>"] = "SPC",
|
||||
-- ["<cr>"] = "RET",
|
||||
-- ["<tab>"] = "TAB",
|
||||
},
|
||||
motions = {
|
||||
count = true,
|
||||
},
|
||||
icons = {
|
||||
breadcrumb = "»", -- symbol used in the command line area that shows your active key combo
|
||||
separator = "➜", -- symbol used between a key and it's label
|
||||
group = "+", -- symbol prepended to a group
|
||||
},
|
||||
popup_mappings = {
|
||||
scroll_down = "<c-d>", -- binding to scroll down inside the popup
|
||||
scroll_up = "<c-u>", -- binding to scroll up inside the popup
|
||||
},
|
||||
window = {
|
||||
border = "none", -- none, single, double, shadow
|
||||
position = "bottom", -- bottom, top
|
||||
margin = { 1, 0, 1, 0 }, -- extra window margin [top, right, bottom, left]. When between 0 and 1, will be treated as a percentage of the screen size.
|
||||
padding = { 1, 2, 1, 2 }, -- extra window padding [top, right, bottom, left]
|
||||
winblend = 0, -- value between 0-100 0 for fully opaque and 100 for fully transparent
|
||||
zindex = 1000, -- positive value to position WhichKey above other floating windows.
|
||||
},
|
||||
layout = {
|
||||
height = { min = 4, max = 25 }, -- min and max height of the columns
|
||||
width = { min = 20, max = 50 }, -- min and max width of the columns
|
||||
spacing = 3, -- spacing between columns
|
||||
align = "left", -- align columns left, center or right
|
||||
},
|
||||
ignore_missing = false, -- enable this to hide mappings for which you didn't specify a label
|
||||
hidden = { "<silent>", "<cmd>", "<Cmd>", "<CR>", "^:", "^ ", "^call ", "^lua " }, -- hide mapping boilerplate
|
||||
show_help = true, -- show a help message in the command line for using WhichKey
|
||||
show_keys = true, -- show the currently pressed key and its label as a message in the command line
|
||||
triggers = "auto", -- automatically setup triggers
|
||||
-- triggers = {"<leader>"} -- or specifiy a list manually
|
||||
-- list of triggers, where WhichKey should not wait for timeoutlen and show immediately
|
||||
triggers_nowait = {
|
||||
-- marks
|
||||
"`",
|
||||
"'",
|
||||
"g`",
|
||||
"g'",
|
||||
-- registers
|
||||
'"',
|
||||
"<c-r>",
|
||||
-- spelling
|
||||
"z=",
|
||||
},
|
||||
triggers_blacklist = {
|
||||
-- list of mode / prefixes that should never be hooked by WhichKey
|
||||
-- this is mostly relevant for keymaps that start with a native binding
|
||||
i = { "j", "k" },
|
||||
v = { "j", "k" },
|
||||
},
|
||||
-- disable the WhichKey popup for certain buf types and file types.
|
||||
-- Disabled by deafult for Telescope
|
||||
disable = {
|
||||
buftypes = {},
|
||||
filetypes = {},
|
||||
},
|
||||
}
|
||||
|
||||
---@type Options
|
||||
M.options = {}
|
||||
|
||||
---@param options? Options
|
||||
function M.setup(options)
|
||||
M.options = vim.tbl_deep_extend("force", {}, defaults, options or {})
|
||||
end
|
||||
|
||||
M.setup()
|
||||
|
||||
return M
|
||||
@ -0,0 +1,57 @@
|
||||
local Keys = require("which-key.keys")
|
||||
|
||||
local M = {}
|
||||
|
||||
local start = vim.health.start or vim.health.report_start
|
||||
local ok = vim.health.ok or vim.health.report_ok
|
||||
local warn = vim.health.warn or vim.health.report_warn
|
||||
local error = vim.health.error or vim.health.report_error
|
||||
local info = vim.health.info or vim.health.report_info
|
||||
|
||||
function M.check()
|
||||
start("WhichKey: checking conflicting keymaps")
|
||||
local conflicts = 0
|
||||
for _, tree in pairs(Keys.mappings) do
|
||||
Keys.update_keymaps(tree.mode, tree.buf)
|
||||
tree.tree:walk(
|
||||
---@param node Node
|
||||
function(node)
|
||||
local count = 0
|
||||
for _ in pairs(node.children) do
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
local auto_prefix = not node.mapping or (node.mapping.group == true and not node.mapping.cmd)
|
||||
if node.prefix_i ~= "" and count > 0 and not auto_prefix then
|
||||
conflicts = conflicts + 1
|
||||
local msg = ("conflicting keymap exists for mode **%q**, lhs: **%q**"):format(tree.mode, node.mapping.prefix)
|
||||
warn(msg)
|
||||
local cmd = node.mapping.cmd or " "
|
||||
info(("rhs: `%s`"):format(cmd))
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
if conflicts == 0 then
|
||||
ok("No conflicting keymaps found")
|
||||
return
|
||||
end
|
||||
for _, dup in ipairs(Keys.duplicates) do
|
||||
local msg = ""
|
||||
if dup.buf == dup.other.buffer then
|
||||
msg = "duplicate keymap"
|
||||
else
|
||||
msg = "buffer-local keymap overriding global"
|
||||
end
|
||||
msg = (msg .. " for mode **%q**, buf: %d, lhs: **%q**"):format(dup.mode, dup.buf or 0, dup.prefix)
|
||||
if dup.buf == dup.other.buffer then
|
||||
error(msg)
|
||||
else
|
||||
warn(msg)
|
||||
end
|
||||
info(("old rhs: `%s`"):format(dup.other.rhs or ""))
|
||||
info(("new rhs: `%s`"):format(dup.cmd or ""))
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,108 @@
|
||||
local Keys = require("which-key.keys")
|
||||
local Util = require("which-key.util")
|
||||
|
||||
---@class WhichKey
|
||||
local M = {}
|
||||
|
||||
local loaded = false -- once we loaded everything
|
||||
local scheduled = false
|
||||
|
||||
local function schedule_load()
|
||||
if scheduled then
|
||||
return
|
||||
end
|
||||
scheduled = true
|
||||
if vim.v.vim_did_enter == 0 then
|
||||
vim.cmd([[au VimEnter * ++once lua require("which-key").load()]])
|
||||
else
|
||||
M.load()
|
||||
end
|
||||
end
|
||||
|
||||
---@param options? Options
|
||||
function M.setup(options)
|
||||
require("which-key.config").setup(options)
|
||||
schedule_load()
|
||||
end
|
||||
|
||||
function M.execute(id)
|
||||
local func = Keys.functions[id]
|
||||
return func()
|
||||
end
|
||||
|
||||
function M.show(keys, opts)
|
||||
opts = opts or {}
|
||||
if type(opts) == "string" then
|
||||
opts = { mode = opts }
|
||||
end
|
||||
|
||||
keys = keys or ""
|
||||
|
||||
opts.mode = opts.mode or Util.get_mode()
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
-- make sure the trees exist for update
|
||||
Keys.get_tree(opts.mode)
|
||||
Keys.get_tree(opts.mode, buf)
|
||||
-- update only trees related to buf
|
||||
Keys.update(buf)
|
||||
-- trigger which key
|
||||
require("which-key.view").open(keys, opts)
|
||||
end
|
||||
|
||||
function M.show_command(keys, mode)
|
||||
keys = keys or ""
|
||||
keys = (keys == '""' or keys == "''") and "" or keys
|
||||
mode = (mode == '""' or mode == "''") and "" or mode
|
||||
mode = mode or "n"
|
||||
keys = Util.t(keys)
|
||||
if not Util.check_mode(mode) then
|
||||
Util.error(
|
||||
"Invalid mode passed to :WhichKey (Don't create any keymappings to trigger WhichKey. WhichKey does this automatically)"
|
||||
)
|
||||
else
|
||||
M.show(keys, { mode = mode })
|
||||
end
|
||||
end
|
||||
|
||||
local queue = {}
|
||||
|
||||
-- Defer registering keymaps until VimEnter
|
||||
function M.register(mappings, opts)
|
||||
schedule_load()
|
||||
if loaded then
|
||||
Keys.register(mappings, opts)
|
||||
Keys.update()
|
||||
else
|
||||
table.insert(queue, { mappings, opts })
|
||||
end
|
||||
end
|
||||
|
||||
-- Load mappings and update only once
|
||||
function M.load()
|
||||
if loaded then
|
||||
return
|
||||
end
|
||||
require("which-key.plugins").setup()
|
||||
require("which-key.colors").setup()
|
||||
Keys.register({}, { prefix = "<leader>", mode = "n" })
|
||||
Keys.register({}, { prefix = "<leader>", mode = "v" })
|
||||
Keys.setup()
|
||||
|
||||
for _, reg in pairs(queue) do
|
||||
local opts = reg[2] or {}
|
||||
opts.update = false
|
||||
Keys.register(reg[1], opts)
|
||||
end
|
||||
Keys.update()
|
||||
queue = {}
|
||||
loaded = true
|
||||
end
|
||||
|
||||
function M.reset()
|
||||
-- local mappings = Keys.mappings
|
||||
require("plenary.reload").reload_module("which-key")
|
||||
-- require("which-key.Keys").mappings = mappings
|
||||
require("which-key").setup()
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,438 @@
|
||||
local Tree = require("which-key.tree")
|
||||
local Util = require("which-key.util")
|
||||
local Config = require("which-key.config")
|
||||
|
||||
-- secret character that will be used to create <nop> mappings
|
||||
local secret = "Þ"
|
||||
|
||||
---@class Keys
|
||||
local M = {}
|
||||
|
||||
M.functions = {}
|
||||
M.operators = {}
|
||||
M.nowait = {}
|
||||
M.blacklist = {}
|
||||
|
||||
function M.setup()
|
||||
local builtin_ops = require("which-key.plugins.presets").operators
|
||||
for op, _ in pairs(builtin_ops) do
|
||||
M.operators[op] = true
|
||||
end
|
||||
local mappings = {}
|
||||
for op, label in pairs(Config.options.operators) do
|
||||
M.operators[op] = true
|
||||
if builtin_ops[op] then
|
||||
mappings[op] = { name = label, i = { name = "inside" }, a = { name = "around" } }
|
||||
end
|
||||
end
|
||||
for _, t in pairs(Config.options.triggers_nowait) do
|
||||
M.nowait[t] = true
|
||||
end
|
||||
M.register(mappings, { mode = "n", preset = true })
|
||||
M.register({ i = { name = "inside" }, a = { name = "around" } }, { mode = "v", preset = true })
|
||||
for mode, blacklist in pairs(Config.options.triggers_blacklist) do
|
||||
for _, prefix_n in ipairs(blacklist) do
|
||||
M.blacklist[mode] = M.blacklist[mode] or {}
|
||||
M.blacklist[mode][prefix_n] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.get_operator(prefix_i)
|
||||
for op_n, _ in pairs(Config.options.operators) do
|
||||
local op_i = Util.t(op_n)
|
||||
if prefix_i:sub(1, #op_i) == op_i then
|
||||
return op_i, op_n
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.process_motions(ret, mode, prefix_i, buf)
|
||||
local op_i, op_n = "", ""
|
||||
if mode ~= "v" then
|
||||
op_i, op_n = M.get_operator(prefix_i)
|
||||
end
|
||||
if (mode == "n" or mode == "v") and op_i then
|
||||
local op_prefix_i = prefix_i:sub(#op_i + 1)
|
||||
local op_count = op_prefix_i:match("^(%d+)")
|
||||
if op_count == "0" then
|
||||
op_count = nil
|
||||
end
|
||||
if Config.options.motions.count == false then
|
||||
op_count = nil
|
||||
end
|
||||
if op_count then
|
||||
op_prefix_i = op_prefix_i:sub(#op_count + 1)
|
||||
end
|
||||
local op_results = M.get_mappings("o", op_prefix_i, buf)
|
||||
|
||||
if not ret.mapping and op_results.mapping then
|
||||
ret.mapping = op_results.mapping
|
||||
ret.mapping.prefix = op_n .. (op_count or "") .. ret.mapping.prefix
|
||||
ret.mapping.keys = Util.parse_keys(ret.mapping.prefix)
|
||||
end
|
||||
|
||||
for _, mapping in pairs(op_results.mappings) do
|
||||
mapping.prefix = op_n .. (op_count or "") .. mapping.prefix
|
||||
mapping.keys = Util.parse_keys(mapping.prefix)
|
||||
table.insert(ret.mappings, mapping)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@return MappingGroup
|
||||
function M.get_mappings(mode, prefix_i, buf)
|
||||
---@class MappingGroup
|
||||
---@field mode string
|
||||
---@field prefix_i string
|
||||
---@field buf number
|
||||
---@field mapping? Mapping
|
||||
---@field mappings VisualMapping[]
|
||||
local ret
|
||||
ret = { mapping = nil, mappings = {}, mode = mode, buf = buf, prefix_i = prefix_i }
|
||||
|
||||
local prefix_len = #Util.parse_internal(prefix_i)
|
||||
|
||||
---@param node? Node
|
||||
local function add(node)
|
||||
if node then
|
||||
if node.mapping then
|
||||
ret.mapping = vim.tbl_deep_extend("force", {}, ret.mapping or {}, node.mapping)
|
||||
end
|
||||
for k, child in pairs(node.children) do
|
||||
if
|
||||
child.mapping
|
||||
and child.mapping.label ~= "which_key_ignore"
|
||||
and child.mapping.desc ~= "which_key_ignore"
|
||||
and not (child.mapping.group and vim.tbl_isempty(child.children))
|
||||
then
|
||||
ret.mappings[k] = vim.tbl_deep_extend("force", {}, ret.mappings[k] or {}, child.mapping)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local plugin_context = { buf = buf, mode = mode }
|
||||
add(M.get_tree(mode).tree:get(prefix_i, nil, plugin_context))
|
||||
add(M.get_tree(mode, buf).tree:get(prefix_i, nil, plugin_context))
|
||||
|
||||
-- Handle motions
|
||||
M.process_motions(ret, mode, prefix_i, buf)
|
||||
|
||||
-- Fix labels
|
||||
local tmp = {}
|
||||
for _, value in pairs(ret.mappings) do
|
||||
value.key = value.keys.notation[prefix_len + 1]
|
||||
if Config.options.key_labels[value.key] then
|
||||
value.key = Config.options.key_labels[value.key]
|
||||
end
|
||||
local skip = not value.label and Config.options.ignore_missing == true
|
||||
if Util.t(value.key) == Util.t("<esc>") then
|
||||
skip = true
|
||||
end
|
||||
if not skip then
|
||||
if value.group then
|
||||
value.label = value.label or "+prefix"
|
||||
value.label = value.label:gsub("^%+", "")
|
||||
value.label = Config.options.icons.group .. value.label
|
||||
elseif not value.label then
|
||||
value.label = value.desc or value.cmd or ""
|
||||
for _, v in ipairs(Config.options.hidden) do
|
||||
value.label = value.label:gsub(v, "")
|
||||
end
|
||||
end
|
||||
if value.value then
|
||||
value.value = vim.fn.strtrans(value.value)
|
||||
end
|
||||
-- remove duplicated keymap
|
||||
local exists = false
|
||||
for k, v in pairs(tmp) do
|
||||
if type(v) == "table" and v.key == value.key then
|
||||
tmp[k] = value
|
||||
exists = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not exists then
|
||||
table.insert(tmp, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Sort items, but not for plugins
|
||||
table.sort(tmp, function(a, b)
|
||||
if a.order and b.order then
|
||||
return a.order < b.order
|
||||
end
|
||||
if a.group == b.group then
|
||||
local ak = (a.key or ""):lower()
|
||||
local bk = (b.key or ""):lower()
|
||||
local aw = ak:match("[a-z]") and 1 or 0
|
||||
local bw = bk:match("[a-z]") and 1 or 0
|
||||
if aw == bw then
|
||||
return ak < bk
|
||||
end
|
||||
return aw < bw
|
||||
else
|
||||
return (a.group and 1 or 0) < (b.group and 1 or 0)
|
||||
end
|
||||
end)
|
||||
ret.mappings = tmp
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
---@type table<string, MappingTree>
|
||||
M.mappings = {}
|
||||
M.duplicates = {}
|
||||
|
||||
function M.map(mode, prefix_n, cmd, buf, opts)
|
||||
local other = vim.api.nvim_buf_call(buf or 0, function()
|
||||
local ret = vim.fn.maparg(prefix_n, mode, false, true)
|
||||
---@diagnostic disable-next-line: undefined-field
|
||||
return (ret and ret.lhs and ret.rhs and ret.rhs ~= cmd) and ret or nil
|
||||
end)
|
||||
if other and other.buffer == buf then
|
||||
table.insert(M.duplicates, { mode = mode, prefix = prefix_n, cmd = cmd, buf = buf, other = other })
|
||||
end
|
||||
if buf ~= nil then
|
||||
pcall(vim.api.nvim_buf_set_keymap, buf, mode, prefix_n, cmd, opts)
|
||||
else
|
||||
pcall(vim.api.nvim_set_keymap, mode, prefix_n, cmd, opts)
|
||||
end
|
||||
end
|
||||
|
||||
function M.register(mappings, opts)
|
||||
opts = opts or {}
|
||||
|
||||
mappings = require("which-key.mappings").parse(mappings, opts)
|
||||
|
||||
-- always create the root node for the mode, even if there's no mappings,
|
||||
-- to ensure we have at least a trigger hooked for non documented keymaps
|
||||
local modes = {}
|
||||
|
||||
for _, mapping in pairs(mappings) do
|
||||
if not modes[mapping.mode] then
|
||||
modes[mapping.mode] = true
|
||||
M.get_tree(mapping.mode)
|
||||
end
|
||||
if mapping.cmd ~= nil then
|
||||
M.map(mapping.mode, mapping.prefix, mapping.cmd, mapping.buf, mapping.opts)
|
||||
end
|
||||
M.get_tree(mapping.mode, mapping.buf).tree:add(mapping)
|
||||
end
|
||||
end
|
||||
|
||||
M.hooked = {}
|
||||
|
||||
function M.hook_id(prefix_n, mode, buf)
|
||||
return mode .. (buf or "") .. Util.t(prefix_n)
|
||||
end
|
||||
|
||||
function M.is_hooked(prefix_n, mode, buf)
|
||||
return M.hooked[M.hook_id(prefix_n, mode, buf)]
|
||||
end
|
||||
|
||||
function M.hook_del(prefix_n, mode, buf)
|
||||
local id = M.hook_id(prefix_n, mode, buf)
|
||||
M.hooked[id] = nil
|
||||
if buf then
|
||||
pcall(vim.api.nvim_buf_del_keymap, buf, mode, prefix_n)
|
||||
pcall(vim.api.nvim_buf_del_keymap, buf, mode, prefix_n .. secret)
|
||||
else
|
||||
pcall(vim.api.nvim_del_keymap, mode, prefix_n)
|
||||
pcall(vim.api.nvim_del_keymap, mode, prefix_n .. secret)
|
||||
end
|
||||
end
|
||||
|
||||
function M.hook_add(prefix_n, mode, buf, secret_only)
|
||||
-- check if this trigger is blacklisted
|
||||
if M.blacklist[mode] and M.blacklist[mode][prefix_n] then
|
||||
return
|
||||
end
|
||||
-- don't hook numbers. See #118
|
||||
if tonumber(prefix_n) then
|
||||
return
|
||||
end
|
||||
-- don't hook to j or k in INSERT mode
|
||||
if mode == "i" and (prefix_n == "j" or prefix_n == "k") then
|
||||
return
|
||||
end
|
||||
-- never hook q
|
||||
if mode == "n" and prefix_n == "q" then
|
||||
return
|
||||
end
|
||||
-- never hook into select mode
|
||||
if mode == "s" then
|
||||
return
|
||||
end
|
||||
-- never hook into operator pending mode
|
||||
-- this is handled differently
|
||||
if mode == "o" then
|
||||
return
|
||||
end
|
||||
if Util.t(prefix_n) == Util.t("<esc>") then
|
||||
return
|
||||
end
|
||||
-- never hook into operators in visual mode
|
||||
if (mode == "v" or mode == "x") and (prefix_n == "a" or prefix_n == "i" or M.operators[prefix_n]) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if we need to create the hook
|
||||
if type(Config.options.triggers) == "string" and Config.options.triggers ~= "auto" then
|
||||
if Util.t(prefix_n) ~= Util.t(Config.options.triggers) then
|
||||
return
|
||||
end
|
||||
end
|
||||
if type(Config.options.triggers) == "table" then
|
||||
local ok = false
|
||||
for _, trigger in pairs(Config.options.triggers) do
|
||||
if Util.t(trigger) == Util.t(prefix_n) then
|
||||
ok = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not ok then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local opts = { noremap = true, silent = true }
|
||||
local id = M.hook_id(prefix_n, mode, buf)
|
||||
local id_global = M.hook_id(prefix_n, mode)
|
||||
-- hook up if needed
|
||||
if not M.hooked[id] and not M.hooked[id_global] then
|
||||
local cmd = [[<cmd>lua require("which-key").show(%q, {mode = %q, auto = true})<cr>]]
|
||||
cmd = string.format(cmd, Util.t(prefix_n), mode)
|
||||
-- map group triggers and nops
|
||||
-- nops are needed, so that WhichKey always respects timeoutlen
|
||||
|
||||
local mapmode = mode == "v" and "x" or mode
|
||||
if secret_only ~= true then
|
||||
M.map(mapmode, prefix_n, cmd, buf, opts)
|
||||
end
|
||||
if not M.nowait[prefix_n] then
|
||||
M.map(mapmode, prefix_n .. secret, "<nop>", buf, opts)
|
||||
end
|
||||
|
||||
M.hooked[id] = true
|
||||
end
|
||||
end
|
||||
|
||||
function M.update(buf)
|
||||
for k, tree in pairs(M.mappings) do
|
||||
if tree.buf and not vim.api.nvim_buf_is_valid(tree.buf) then
|
||||
-- remove group for invalid buffers
|
||||
M.mappings[k] = nil
|
||||
elseif not buf or not tree.buf or buf == tree.buf then
|
||||
-- only update buffer maps, if:
|
||||
-- 1. we dont pass a buffer
|
||||
-- 2. this is a global node
|
||||
-- 3. this is a local buffer node for the passed buffer
|
||||
M.update_keymaps(tree.mode, tree.buf)
|
||||
M.add_hooks(tree.mode, tree.buf, tree.tree.root)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param node Node
|
||||
function M.add_hooks(mode, buf, node, secret_only)
|
||||
if not node.mapping then
|
||||
node.mapping = { prefix = node.prefix_n, group = true, keys = Util.parse_keys(node.prefix_n) }
|
||||
end
|
||||
if node.prefix_n ~= "" and node.mapping.group == true and not (node.mapping.cmd or node.mapping.callback) then
|
||||
-- first non-cmd level, so create hook and make all decendents secret only
|
||||
M.hook_add(node.prefix_n, mode, buf, secret_only)
|
||||
secret_only = true
|
||||
end
|
||||
for _, child in pairs(node.children) do
|
||||
M.add_hooks(mode, buf, child, secret_only)
|
||||
end
|
||||
end
|
||||
|
||||
function M.dump()
|
||||
local ok = {}
|
||||
local todo = {}
|
||||
for _, tree in pairs(M.mappings) do
|
||||
M.update_keymaps(tree.mode, tree.buf)
|
||||
tree.tree:walk(
|
||||
---@param node Node
|
||||
function(node)
|
||||
if node.mapping then
|
||||
if node.mapping.label then
|
||||
ok[node.mapping.prefix] = true
|
||||
todo[node.mapping.prefix] = nil
|
||||
elseif not ok[node.mapping.prefix] then
|
||||
todo[node.mapping.prefix] = { node.mapping.cmd or "" }
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
return todo
|
||||
end
|
||||
|
||||
---@param mode string
|
||||
---@param buf? buffer
|
||||
function M.get_tree(mode, buf)
|
||||
if mode == "s" or mode == "x" then
|
||||
mode = "v"
|
||||
end
|
||||
Util.check_mode(mode, buf)
|
||||
local idx = mode .. (buf or "")
|
||||
if not M.mappings[idx] then
|
||||
M.mappings[idx] = { mode = mode, buf = buf, tree = Tree:new() }
|
||||
end
|
||||
return M.mappings[idx]
|
||||
end
|
||||
|
||||
---@param prefix string
|
||||
---@param cmd string?
|
||||
function M.is_hook(prefix, cmd)
|
||||
-- skip mappings with our secret nop command
|
||||
if prefix:find(secret, 1, true) then
|
||||
return true
|
||||
end
|
||||
-- skip auto which-key mappings
|
||||
return cmd and cmd:find("which-key", 1, true) and cmd:find("auto", 1, true)
|
||||
end
|
||||
|
||||
---@param mode string
|
||||
---@param buf? number
|
||||
function M.update_keymaps(mode, buf)
|
||||
---@type Keymap[]
|
||||
local keymaps = buf and vim.api.nvim_buf_get_keymap(buf, mode) or vim.api.nvim_get_keymap(mode)
|
||||
local tree = M.get_tree(mode, buf).tree
|
||||
|
||||
local function is_nop(keymap)
|
||||
return not keymap.callback and (keymap.rhs == "" or keymap.rhs:lower() == "<nop>")
|
||||
end
|
||||
|
||||
for _, keymap in pairs(keymaps) do
|
||||
local skip = M.is_hook(keymap.lhs, keymap.rhs)
|
||||
|
||||
if is_nop(keymap) then
|
||||
skip = true
|
||||
end
|
||||
|
||||
if not skip then
|
||||
local mapping = {
|
||||
prefix = keymap.lhs,
|
||||
cmd = keymap.rhs,
|
||||
desc = keymap.desc,
|
||||
callback = keymap.callback,
|
||||
keys = Util.parse_keys(keymap.lhs),
|
||||
}
|
||||
-- don't include Plug keymaps
|
||||
if mapping.keys.notation[1]:lower() ~= "<plug>" then
|
||||
local node = tree:add(mapping)
|
||||
if node.mapping and node.mapping.preset and mapping.desc then
|
||||
node.mapping.label = mapping.desc
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,216 @@
|
||||
local Config = require("which-key.config")
|
||||
local Text = require("which-key.text")
|
||||
local Keys = require("which-key.keys")
|
||||
local Util = require("which-key.util")
|
||||
|
||||
---@class Layout
|
||||
---@field mapping Mapping
|
||||
---@field items VisualMapping[]
|
||||
---@field options Options
|
||||
---@field text Text
|
||||
---@field results MappingGroup
|
||||
local Layout = {}
|
||||
Layout.__index = Layout
|
||||
|
||||
---@param mappings MappingGroup
|
||||
---@param options? Options
|
||||
function Layout:new(mappings, options)
|
||||
options = options or Config.options
|
||||
local this = {
|
||||
results = mappings,
|
||||
mapping = mappings.mapping,
|
||||
items = mappings.mappings,
|
||||
options = options,
|
||||
text = Text:new(),
|
||||
}
|
||||
setmetatable(this, self)
|
||||
return this
|
||||
end
|
||||
|
||||
function Layout:max_width(key)
|
||||
local max = 0
|
||||
for _, item in pairs(self.items) do
|
||||
if item[key] and Text.len(item[key]) > max then
|
||||
max = Text.len(item[key])
|
||||
end
|
||||
end
|
||||
return max
|
||||
end
|
||||
|
||||
function Layout:trail()
|
||||
local prefix_i = self.results.prefix_i
|
||||
local buf_path = Keys.get_tree(self.results.mode, self.results.buf).tree:path(prefix_i)
|
||||
local path = Keys.get_tree(self.results.mode).tree:path(prefix_i)
|
||||
local len = #self.results.mapping.keys.notation
|
||||
local cmd_line = { { " " } }
|
||||
for i = 1, len, 1 do
|
||||
local node = buf_path[i]
|
||||
if not (node and node.mapping and node.mapping.label) then
|
||||
node = path[i]
|
||||
end
|
||||
local step = self.mapping.keys.notation[i]
|
||||
if node and node.mapping and node.mapping.label then
|
||||
step = self.options.icons.group .. node.mapping.label
|
||||
end
|
||||
if Config.options.key_labels[step] then
|
||||
step = Config.options.key_labels[step]
|
||||
end
|
||||
if Config.options.show_keys then
|
||||
table.insert(cmd_line, { step, "WhichKeyGroup" })
|
||||
if i ~= #self.mapping.keys.notation then
|
||||
table.insert(cmd_line, { " " .. self.options.icons.breadcrumb .. " ", "WhichKeySeparator" })
|
||||
end
|
||||
end
|
||||
end
|
||||
local width = 0
|
||||
if Config.options.show_keys then
|
||||
for _, line in pairs(cmd_line) do
|
||||
width = width + Text.len(line[1])
|
||||
end
|
||||
end
|
||||
local help = { --
|
||||
["<bs>"] = "go up one level",
|
||||
["<esc>"] = "close",
|
||||
}
|
||||
if #self.text.lines > self.options.layout.height.max then
|
||||
help[Config.options.popup_mappings.scroll_down] = "scroll down"
|
||||
help[Config.options.popup_mappings.scroll_up] = "scroll up"
|
||||
end
|
||||
local help_line = {}
|
||||
local help_width = 0
|
||||
for key, label in pairs(help) do
|
||||
help_width = help_width + Text.len(key) + Text.len(label) + 2
|
||||
table.insert(help_line, { key .. " ", "WhichKey" })
|
||||
table.insert(help_line, { label .. " ", "WhichKeySeparator" })
|
||||
end
|
||||
if Config.options.show_keys then
|
||||
table.insert(cmd_line, { string.rep(" ", math.floor(vim.o.columns / 2 - help_width / 2) - width) })
|
||||
end
|
||||
|
||||
if self.options.show_help then
|
||||
for _, l in pairs(help_line) do
|
||||
table.insert(cmd_line, l)
|
||||
end
|
||||
end
|
||||
if vim.o.cmdheight > 0 then
|
||||
vim.api.nvim_echo(cmd_line, false, {})
|
||||
vim.cmd([[redraw]])
|
||||
else
|
||||
local col = 1
|
||||
self.text:nl()
|
||||
local row = #self.text.lines
|
||||
for _, text in ipairs(cmd_line) do
|
||||
self.text:set(row, col, text[1], text[2] and text[2]:gsub("WhichKey", "") or nil)
|
||||
col = col + vim.fn.strwidth(text[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Layout:layout(win)
|
||||
local pad_top, pad_right, pad_bot, pad_left = unpack(self.options.window.padding)
|
||||
local window_width = vim.api.nvim_win_get_width(win)
|
||||
local width = window_width
|
||||
width = width - pad_right - pad_left
|
||||
|
||||
local max_key_width = self:max_width("key")
|
||||
local max_label_width = self:max_width("label")
|
||||
local max_value_width = self:max_width("value")
|
||||
|
||||
local intro_width = max_key_width + 2 + Text.len(self.options.icons.separator) + self.options.layout.spacing
|
||||
local max_width = max_label_width + intro_width + max_value_width
|
||||
if max_width > width then
|
||||
max_width = width
|
||||
end
|
||||
|
||||
local column_width = max_width
|
||||
|
||||
if max_value_width == 0 then
|
||||
if column_width > self.options.layout.width.max then
|
||||
column_width = self.options.layout.width.max
|
||||
end
|
||||
if column_width < self.options.layout.width.min then
|
||||
column_width = self.options.layout.width.min
|
||||
end
|
||||
else
|
||||
max_value_width = math.min(max_value_width, math.floor((column_width - intro_width) / 2))
|
||||
end
|
||||
|
||||
max_label_width = column_width - (intro_width + max_value_width)
|
||||
|
||||
local columns = math.floor(width / column_width)
|
||||
|
||||
local height = math.ceil(#self.items / columns)
|
||||
if height < self.options.layout.height.min then
|
||||
height = self.options.layout.height.min
|
||||
end
|
||||
-- if height > self.options.layout.height.max then height = self.options.layout.height.max end
|
||||
|
||||
local col = 1
|
||||
local row = 1
|
||||
|
||||
local columns_used = math.min(columns, math.ceil(#self.items / height))
|
||||
local offset_x = 0
|
||||
if columns_used < columns then
|
||||
if self.options.layout.align == "right" then
|
||||
offset_x = (columns - columns_used) * column_width
|
||||
elseif self.options.layout.align == "center" then
|
||||
offset_x = math.floor((columns - columns_used) * column_width / 2)
|
||||
end
|
||||
end
|
||||
|
||||
for _, item in pairs(self.items) do
|
||||
local start = (col - 1) * column_width + self.options.layout.spacing + offset_x + pad_left
|
||||
local key = item.key or ""
|
||||
if key == "<lt>" then
|
||||
key = "<"
|
||||
end
|
||||
if key == Util.t("<esc>") then
|
||||
key = "<esc>"
|
||||
end
|
||||
if Text.len(key) < max_key_width then
|
||||
key = string.rep(" ", max_key_width - Text.len(key)) .. key
|
||||
end
|
||||
|
||||
self.text:set(row + pad_top, start, key, "")
|
||||
start = start + Text.len(key) + 1
|
||||
|
||||
self.text:set(row + pad_top, start, self.options.icons.separator, "Separator")
|
||||
start = start + Text.len(self.options.icons.separator) + 1
|
||||
|
||||
if item.value then
|
||||
local value = item.value
|
||||
start = start + 1
|
||||
if Text.len(value) > max_value_width then
|
||||
value = vim.fn.strcharpart(value, 0, max_value_width - 2) .. " …"
|
||||
end
|
||||
self.text:set(row + pad_top, start, value, "Value")
|
||||
if item.highlights then
|
||||
for _, hl in pairs(item.highlights) do
|
||||
self.text:highlight(row + pad_top, start + hl[1] - 1, start + hl[2] - 1, hl[3])
|
||||
end
|
||||
end
|
||||
start = start + max_value_width + 2
|
||||
end
|
||||
|
||||
local label = item.label
|
||||
if Text.len(label) > max_label_width then
|
||||
label = vim.fn.strcharpart(label, 0, max_label_width - 2) .. " …"
|
||||
end
|
||||
self.text:set(row + pad_top, start, label, item.group and "Group" or "Desc")
|
||||
|
||||
if row % height == 0 then
|
||||
col = col + 1
|
||||
row = 1
|
||||
else
|
||||
row = row + 1
|
||||
end
|
||||
end
|
||||
|
||||
for _ = 1, pad_bot, 1 do
|
||||
self.text:nl()
|
||||
end
|
||||
self:trail()
|
||||
return self.text
|
||||
end
|
||||
|
||||
return Layout
|
||||
@ -0,0 +1,231 @@
|
||||
local Util = require("which-key.util")
|
||||
|
||||
local M = {}
|
||||
|
||||
local function lookup(...)
|
||||
local ret = {}
|
||||
for _, t in ipairs({ ... }) do
|
||||
for _, v in ipairs(t) do
|
||||
ret[v] = v
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
local mapargs = {
|
||||
"noremap",
|
||||
"desc",
|
||||
"expr",
|
||||
"silent",
|
||||
"nowait",
|
||||
"script",
|
||||
"unique",
|
||||
"callback",
|
||||
"replace_keycodes", -- TODO: add config setting for default value
|
||||
}
|
||||
local wkargs = {
|
||||
"prefix",
|
||||
"mode",
|
||||
"plugin",
|
||||
"buffer",
|
||||
"remap",
|
||||
"cmd",
|
||||
"name",
|
||||
"group",
|
||||
"preset",
|
||||
"cond",
|
||||
}
|
||||
local transargs = lookup({
|
||||
"noremap",
|
||||
"expr",
|
||||
"silent",
|
||||
"nowait",
|
||||
"script",
|
||||
"unique",
|
||||
"prefix",
|
||||
"mode",
|
||||
"buffer",
|
||||
"preset",
|
||||
"replace_keycodes",
|
||||
})
|
||||
local args = lookup(mapargs, wkargs)
|
||||
|
||||
function M.child_opts(opts)
|
||||
local ret = {}
|
||||
for k, v in pairs(opts) do
|
||||
if transargs[k] then
|
||||
ret[k] = v
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
function M._process(value, opts)
|
||||
local list = {}
|
||||
local children = {}
|
||||
for k, v in pairs(value) do
|
||||
if type(k) == "number" then
|
||||
if type(v) == "table" then
|
||||
-- nested child, without key
|
||||
table.insert(children, v)
|
||||
else
|
||||
-- list value
|
||||
table.insert(list, v)
|
||||
end
|
||||
elseif args[k] then
|
||||
-- option
|
||||
opts[k] = v
|
||||
else
|
||||
-- nested child, with key
|
||||
children[k] = v
|
||||
end
|
||||
end
|
||||
return list, children
|
||||
end
|
||||
|
||||
function M._parse(value, mappings, opts)
|
||||
if type(value) ~= "table" then
|
||||
value = { value }
|
||||
end
|
||||
|
||||
local list, children = M._process(value, opts)
|
||||
|
||||
if opts.plugin then
|
||||
opts.group = true
|
||||
end
|
||||
if opts.name then
|
||||
-- remove + from group names
|
||||
opts.name = opts.name and opts.name:gsub("^%+", "")
|
||||
opts.group = true
|
||||
end
|
||||
|
||||
-- fix remap
|
||||
if opts.remap then
|
||||
opts.noremap = not opts.remap
|
||||
opts.remap = nil
|
||||
end
|
||||
|
||||
-- fix buffer
|
||||
if opts.buffer == 0 then
|
||||
opts.buffer = vim.api.nvim_get_current_buf()
|
||||
end
|
||||
|
||||
if opts.cond ~= nil then
|
||||
if type(opts.cond) == "function" then
|
||||
if not opts.cond() then
|
||||
return
|
||||
end
|
||||
elseif not opts.cond then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- process any array child mappings
|
||||
for k, v in pairs(children) do
|
||||
local o = M.child_opts(opts)
|
||||
if type(k) == "string" then
|
||||
o.prefix = (o.prefix or "") .. k
|
||||
end
|
||||
M._try_parse(v, mappings, o)
|
||||
end
|
||||
|
||||
-- { desc }
|
||||
if #list == 1 then
|
||||
if type(list[1]) ~= "string" then
|
||||
error("Invalid mapping for " .. vim.inspect({ value = value, opts = opts }))
|
||||
end
|
||||
opts.desc = list[1]
|
||||
-- { cmd, desc }
|
||||
elseif #list == 2 then
|
||||
-- desc
|
||||
assert(type(list[2]) == "string")
|
||||
opts.desc = list[2]
|
||||
|
||||
-- cmd
|
||||
if type(list[1]) == "string" then
|
||||
opts.cmd = list[1]
|
||||
elseif type(list[1]) == "function" then
|
||||
opts.cmd = ""
|
||||
opts.callback = list[1]
|
||||
else
|
||||
error("Incorrect mapping " .. vim.inspect(list))
|
||||
end
|
||||
elseif #list > 2 then
|
||||
error("Incorrect mapping " .. vim.inspect(list))
|
||||
end
|
||||
|
||||
if opts.desc or opts.group then
|
||||
if type(opts.mode) == "table" then
|
||||
for _, mode in pairs(opts.mode) do
|
||||
local mode_opts = vim.deepcopy(opts)
|
||||
mode_opts.mode = mode
|
||||
table.insert(mappings, mode_opts)
|
||||
end
|
||||
else
|
||||
table.insert(mappings, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@return Mapping
|
||||
function M.to_mapping(mapping)
|
||||
mapping.silent = mapping.silent ~= false
|
||||
mapping.noremap = mapping.noremap ~= false
|
||||
if mapping.cmd and mapping.cmd:lower():find("^<plug>") then
|
||||
mapping.noremap = false
|
||||
end
|
||||
|
||||
mapping.buf = mapping.buffer
|
||||
mapping.buffer = nil
|
||||
|
||||
mapping.mode = mapping.mode or "n"
|
||||
mapping.label = mapping.desc or mapping.name
|
||||
mapping.keys = Util.parse_keys(mapping.prefix or "")
|
||||
|
||||
local opts = {}
|
||||
for _, o in ipairs(mapargs) do
|
||||
opts[o] = mapping[o]
|
||||
mapping[o] = nil
|
||||
end
|
||||
|
||||
if vim.fn.has("nvim-0.7.0") == 0 then
|
||||
opts.replace_keycodes = nil
|
||||
|
||||
-- Neovim < 0.7.0 doesn't support descriptions
|
||||
opts.desc = nil
|
||||
|
||||
-- use lua functions proxy for Neovim < 0.7.0
|
||||
if opts.callback then
|
||||
local functions = require("which-key.keys").functions
|
||||
table.insert(functions, opts.callback)
|
||||
if opts.expr then
|
||||
opts.cmd = string.format([[luaeval('require("which-key").execute(%d)')]], #functions)
|
||||
else
|
||||
opts.cmd = string.format([[<cmd>lua require("which-key").execute(%d)<cr>]], #functions)
|
||||
end
|
||||
opts.callback = nil
|
||||
end
|
||||
end
|
||||
|
||||
mapping.opts = opts
|
||||
return mapping
|
||||
end
|
||||
|
||||
function M._try_parse(value, mappings, opts)
|
||||
local ok, err = pcall(M._parse, value, mappings, opts)
|
||||
if not ok then
|
||||
Util.error(err)
|
||||
end
|
||||
end
|
||||
|
||||
---@return Mapping[]
|
||||
function M.parse(mappings, opts)
|
||||
opts = opts or {}
|
||||
local ret = {}
|
||||
M._try_parse(mappings, ret, opts)
|
||||
return vim.tbl_map(function(m)
|
||||
return M.to_mapping(m)
|
||||
end, ret)
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,59 @@
|
||||
local Keys = require("which-key.keys")
|
||||
local Util = require("which-key.util")
|
||||
local Config = require("which-key.config")
|
||||
|
||||
local M = {}
|
||||
|
||||
M.plugins = {}
|
||||
|
||||
function M.setup()
|
||||
for name, opts in pairs(Config.options.plugins) do
|
||||
-- only setup plugin if we didnt load it before
|
||||
if not M.plugins[name] then
|
||||
if type(opts) == "boolean" then
|
||||
opts = { enabled = opts }
|
||||
end
|
||||
opts.enabled = opts.enabled ~= false
|
||||
if opts.enabled then
|
||||
M.plugins[name] = require("which-key.plugins." .. name)
|
||||
M._setup(M.plugins[name], opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param plugin Plugin
|
||||
function M._setup(plugin, opts)
|
||||
if plugin.actions then
|
||||
for _, trigger in pairs(plugin.actions) do
|
||||
local prefix = trigger.trigger
|
||||
local mode = trigger.mode or "n"
|
||||
local label = trigger.label or plugin.name
|
||||
Keys.register({ [prefix] = { label, plugin = plugin.name } }, { mode = mode })
|
||||
end
|
||||
end
|
||||
|
||||
if plugin.setup then
|
||||
plugin.setup(require("which-key"), opts, Config.options)
|
||||
end
|
||||
end
|
||||
|
||||
---@param mapping Mapping
|
||||
function M.invoke(mapping, context)
|
||||
local plugin = M.plugins[mapping.plugin]
|
||||
local prefix = mapping.prefix
|
||||
local items = plugin.run(prefix, context.mode, context.buf)
|
||||
|
||||
local ret = {}
|
||||
for i, item in
|
||||
ipairs(items --[[@as VisualMapping[] ]])
|
||||
do
|
||||
item.order = i
|
||||
item.keys = Util.parse_keys(prefix .. item.key)
|
||||
item.prefix = prefix .. item.key
|
||||
table.insert(ret, item)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,66 @@
|
||||
local M = {}
|
||||
|
||||
M.name = "marks"
|
||||
|
||||
M.actions = {
|
||||
{ trigger = "`", mode = "n" },
|
||||
{ trigger = "'", mode = "n" },
|
||||
{ trigger = "g`", mode = "n" },
|
||||
{ trigger = "g'", mode = "n" },
|
||||
}
|
||||
|
||||
function M.setup(_wk, _config, options) end
|
||||
|
||||
local labels = {
|
||||
["^"] = "Last position of cursor in insert mode",
|
||||
["."] = "Last change in current buffer",
|
||||
['"'] = "Last exited current buffer",
|
||||
["0"] = "In last file edited",
|
||||
["'"] = "Back to line in current buffer where jumped from",
|
||||
["`"] = "Back to position in current buffer where jumped from",
|
||||
["["] = "To beginning of previously changed or yanked text",
|
||||
["]"] = "To end of previously changed or yanked text",
|
||||
["<lt>"] = "To beginning of last visual selection",
|
||||
[">"] = "To end of last visual selection",
|
||||
}
|
||||
|
||||
---@type Plugin
|
||||
---@return PluginItem[]
|
||||
function M.run(_trigger, _mode, buf)
|
||||
local items = {}
|
||||
|
||||
local marks = {}
|
||||
vim.list_extend(marks, vim.fn.getmarklist(buf))
|
||||
vim.list_extend(marks, vim.fn.getmarklist())
|
||||
|
||||
for _, mark in pairs(marks) do
|
||||
local key = mark.mark:sub(2, 2)
|
||||
if key == "<" then
|
||||
key = "<lt>"
|
||||
end
|
||||
local lnum = mark.pos[2]
|
||||
|
||||
local line
|
||||
if mark.pos[1] and mark.pos[1] ~= 0 then
|
||||
local lines = vim.fn.getbufline(mark.pos[1], lnum)
|
||||
if lines and lines[1] then
|
||||
line = lines[1]
|
||||
end
|
||||
end
|
||||
|
||||
local file = mark.file and vim.fn.fnamemodify(mark.file, ":p:~:.")
|
||||
|
||||
local value = string.format("%4d ", lnum)
|
||||
value = value .. (line or file or "")
|
||||
|
||||
table.insert(items, {
|
||||
key = key,
|
||||
label = labels[key] or file and ("file: " .. file) or "",
|
||||
value = value,
|
||||
highlights = { { 1, 5, "Number" } },
|
||||
})
|
||||
end
|
||||
return items
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,107 @@
|
||||
local M = {}
|
||||
|
||||
M.name = "presets"
|
||||
|
||||
M.operators = {
|
||||
d = "Delete",
|
||||
c = "Change",
|
||||
y = "Yank (copy)",
|
||||
["g~"] = "Toggle case",
|
||||
["gu"] = "Lowercase",
|
||||
["gU"] = "Uppercase",
|
||||
[">"] = "Indent right",
|
||||
["<lt>"] = "Indent left",
|
||||
["zf"] = "Create fold",
|
||||
["!"] = "Filter through external program",
|
||||
["v"] = "Visual Character Mode",
|
||||
-- ["V"] = "Visual Line Mode",
|
||||
}
|
||||
|
||||
M.motions = {
|
||||
["h"] = "Left",
|
||||
["j"] = "Down",
|
||||
["k"] = "Up",
|
||||
["l"] = "Right",
|
||||
["w"] = "Next word",
|
||||
["%"] = "Matching character: '()', '{}', '[]'",
|
||||
["b"] = "Previous word",
|
||||
["e"] = "Next end of word",
|
||||
["ge"] = "Previous end of word",
|
||||
["0"] = "Start of line",
|
||||
["^"] = "Start of line (non-blank)",
|
||||
["$"] = "End of line",
|
||||
["f"] = "Move to next char",
|
||||
["F"] = "Move to previous char",
|
||||
["t"] = "Move before next char",
|
||||
["T"] = "Move before previous char",
|
||||
["gg"] = "First line",
|
||||
["G"] = "Last line",
|
||||
["{"] = "Previous empty line",
|
||||
["}"] = "Next empty line",
|
||||
}
|
||||
|
||||
M.objects = {
|
||||
a = { name = "around" },
|
||||
i = { name = "inside" },
|
||||
['a"'] = [[double quoted string]],
|
||||
["a'"] = [[single quoted string]],
|
||||
["a("] = [[same as ab]],
|
||||
["a)"] = [[same as ab]],
|
||||
["a<lt>"] = [[a <> from '<' to the matching '>']],
|
||||
["a>"] = [[same as a<]],
|
||||
["aB"] = [[a Block from [{ to ]} (with brackets)]],
|
||||
["aW"] = [[a WORD (with white space)]],
|
||||
["a["] = [[a [] from '[' to the matching ']']],
|
||||
["a]"] = [[same as a[]],
|
||||
["a`"] = [[string in backticks]],
|
||||
["ab"] = [[a block from [( to ]) (with braces)]],
|
||||
["ap"] = [[a paragraph (with white space)]],
|
||||
["as"] = [[a sentence (with white space)]],
|
||||
["at"] = [[a tag block (with white space)]],
|
||||
["aw"] = [[a word (with white space)]],
|
||||
["a{"] = [[same as aB]],
|
||||
["a}"] = [[same as aB]],
|
||||
['i"'] = [[double quoted string without the quotes]],
|
||||
["i'"] = [[single quoted string without the quotes]],
|
||||
["i("] = [[same as ib]],
|
||||
["i)"] = [[same as ib]],
|
||||
["i<lt>"] = [[inner <> from '<' to the matching '>']],
|
||||
["i>"] = [[same as i<]],
|
||||
["iB"] = [[inner Block from [{ and ]}]],
|
||||
["iW"] = [[inner WORD]],
|
||||
["i["] = [[inner [] from '[' to the matching ']']],
|
||||
["i]"] = [[same as i[]],
|
||||
["i`"] = [[string in backticks without the backticks]],
|
||||
["ib"] = [[inner block from [( to ])]],
|
||||
["ip"] = [[inner paragraph]],
|
||||
["is"] = [[inner sentence]],
|
||||
["it"] = [[inner tag block]],
|
||||
["iw"] = [[inner word]],
|
||||
["i{"] = [[same as iB]],
|
||||
["i}"] = [[same as iB]],
|
||||
}
|
||||
|
||||
---@param config Options
|
||||
function M.setup(wk, opts, config)
|
||||
require("which-key.plugins.presets.misc").setup(wk, opts)
|
||||
|
||||
-- Operators
|
||||
if opts.operators then
|
||||
for op, label in pairs(M.operators) do
|
||||
config.operators[op] = label
|
||||
end
|
||||
end
|
||||
|
||||
-- Motions
|
||||
if opts.motions then
|
||||
wk.register(M.motions, { mode = "n", prefix = "", preset = true })
|
||||
wk.register(M.motions, { mode = "o", prefix = "", preset = true })
|
||||
end
|
||||
|
||||
-- Text objects
|
||||
if opts.text_objects then
|
||||
wk.register(M.objects, { mode = "o", prefix = "", preset = true })
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,97 @@
|
||||
local M = {}
|
||||
|
||||
M.name = "misc"
|
||||
|
||||
local misc = {
|
||||
windows = {
|
||||
["<c-w>"] = {
|
||||
name = "window",
|
||||
s = "Split window",
|
||||
v = "Split window vertically",
|
||||
w = "Switch windows",
|
||||
q = "Quit a window",
|
||||
o = "Close all other windows",
|
||||
T = "Break out into a new tab",
|
||||
x = "Swap current with next",
|
||||
["-"] = "Decrease height",
|
||||
["+"] = "Increase height",
|
||||
["<lt>"] = "Decrease width",
|
||||
[">"] = "Increase width",
|
||||
["|"] = "Max out the width",
|
||||
["_"] = "Max out the height",
|
||||
["="] = "Equally high and wide",
|
||||
h = "Go to the left window",
|
||||
l = "Go to the right window",
|
||||
k = "Go to the up window",
|
||||
j = "Go to the down window",
|
||||
},
|
||||
},
|
||||
z = {
|
||||
["z"] = {
|
||||
o = "Open fold under cursor",
|
||||
O = "Open all folds under cursor",
|
||||
c = "Close fold under cursor",
|
||||
C = "Close all folds under cursor",
|
||||
a = "Toggle fold under cursor",
|
||||
A = "Toggle all folds under cursor",
|
||||
v = "Show cursor line",
|
||||
M = "Close all folds",
|
||||
R = "Open all folds",
|
||||
m = "Fold more",
|
||||
r = "Fold less",
|
||||
x = "Update folds",
|
||||
z = "Center this line",
|
||||
t = "Top this line",
|
||||
["<CR>"] = "Top this line, 1st non-blank col",
|
||||
b = "Bottom this line",
|
||||
g = "Add word to spell list",
|
||||
w = "Mark word as bad/misspelling",
|
||||
e = "Right this line",
|
||||
s = "Left this line",
|
||||
H = "Half screen to the left",
|
||||
L = "Half screen to the right",
|
||||
i = "Toggle folding",
|
||||
["="] = "Spelling suggestions",
|
||||
},
|
||||
},
|
||||
nav = {
|
||||
["[{"] = "Previous {",
|
||||
["[("] = "Previous (",
|
||||
["[<lt>"] = "Previous <",
|
||||
["[m"] = "Previous method start",
|
||||
["[M"] = "Previous method end",
|
||||
["[%"] = "Previous unmatched group",
|
||||
["[s"] = "Previous misspelled word",
|
||||
["]{"] = "Next {",
|
||||
["]("] = "Next (",
|
||||
["]<lt>"] = "Next <",
|
||||
["]m"] = "Next method start",
|
||||
["]M"] = "Next method end",
|
||||
["]%"] = "Next unmatched group",
|
||||
["]s"] = "Next misspelled word",
|
||||
["H"] = "Home line of window (top)",
|
||||
["M"] = "Middle line of window",
|
||||
["L"] = "Last line of window",
|
||||
},
|
||||
g = {
|
||||
["gf"] = "Go to file under cursor",
|
||||
["gx"] = "Open the file under cursor with system app",
|
||||
["gi"] = "Move to the last insertion and INSERT",
|
||||
["gv"] = "Switch to VISUAL using last selection",
|
||||
["gn"] = "Search forwards and select",
|
||||
["gN"] = "Search backwards and select",
|
||||
["g%"] = "Cycle backwards through results",
|
||||
["gt"] = "Go to next tab page",
|
||||
["gT"] = "Go to previous tab page",
|
||||
},
|
||||
}
|
||||
|
||||
function M.setup(wk, config)
|
||||
for key, mappings in pairs(misc) do
|
||||
if config[key] ~= false then
|
||||
wk.register(mappings, { mode = "n", prefix = "", preset = true })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,52 @@
|
||||
---@type Plugin
|
||||
local M = {}
|
||||
|
||||
M.name = "registers"
|
||||
|
||||
M.actions = {
|
||||
{ trigger = '"', mode = "n" },
|
||||
{ trigger = '"', mode = "v" },
|
||||
-- { trigger = "@", mode = "n" },
|
||||
{ trigger = "<c-r>", mode = "i" },
|
||||
{ trigger = "<c-r>", mode = "c" },
|
||||
}
|
||||
|
||||
function M.setup(_wk, _config, options) end
|
||||
|
||||
M.registers = '*+"-:.%/#=_abcdefghijklmnopqrstuvwxyz0123456789'
|
||||
|
||||
local labels = {
|
||||
['"'] = "last deleted, changed, or yanked content",
|
||||
["0"] = "last yank",
|
||||
["-"] = "deleted or changed content smaller than one line",
|
||||
["."] = "last inserted text",
|
||||
["%"] = "name of the current file",
|
||||
[":"] = "most recent executed command",
|
||||
["#"] = "alternate buffer",
|
||||
["="] = "result of an expression",
|
||||
["+"] = "synchronized with the system clipboard",
|
||||
["*"] = "synchronized with the selection clipboard",
|
||||
["_"] = "black hole",
|
||||
["/"] = "last search pattern",
|
||||
}
|
||||
|
||||
---@type Plugin
|
||||
---@return PluginItem[]
|
||||
function M.run(_trigger, _mode, _buf)
|
||||
local items = {}
|
||||
|
||||
for i = 1, #M.registers, 1 do
|
||||
local key = M.registers:sub(i, i)
|
||||
local ok, value = pcall(vim.fn.getreg, key, 1)
|
||||
if not ok then
|
||||
value = ""
|
||||
end
|
||||
|
||||
if value ~= "" then
|
||||
table.insert(items, { key = key, label = labels[key] or "", value = value })
|
||||
end
|
||||
end
|
||||
return items
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,51 @@
|
||||
local M = {}
|
||||
|
||||
M.name = "spelling"
|
||||
|
||||
M.actions = { { trigger = "z=", mode = "n" } }
|
||||
|
||||
M.opts = {}
|
||||
|
||||
function M.setup(_, config, options)
|
||||
M.opts = config
|
||||
end
|
||||
|
||||
---@type Plugin
|
||||
---@return PluginItem[]
|
||||
function M.run()
|
||||
-- if started with a count, let the default keybinding work
|
||||
local count = vim.api.nvim_get_vvar("count")
|
||||
if count and count > 0 then
|
||||
return {}
|
||||
end
|
||||
|
||||
---@diagnostic disable-next-line: missing-parameter
|
||||
local cursor_word = vim.fn.expand("<cword>")
|
||||
-- get a misspellled word from under the cursor, if not found, then use the cursor_word instead
|
||||
---@diagnostic disable-next-line: redundant-parameter
|
||||
local bad = vim.fn.spellbadword(cursor_word)
|
||||
local word = bad[1]
|
||||
if word == "" then
|
||||
word = cursor_word
|
||||
end
|
||||
|
||||
local suggestions = vim.fn.spellsuggest(word, M.opts.suggestions or 20, bad[2] == "caps" and 1 or 0)
|
||||
|
||||
local items = {}
|
||||
local keys = "1234567890abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
for i, label in ipairs(suggestions) do
|
||||
local key = keys:sub(i, i)
|
||||
|
||||
table.insert(items, {
|
||||
key = key,
|
||||
label = label,
|
||||
fn = function()
|
||||
vim.cmd("norm! ciw" .. label)
|
||||
end,
|
||||
})
|
||||
end
|
||||
return items
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,72 @@
|
||||
---@class Highlight
|
||||
---@field group string
|
||||
---@field line number
|
||||
---@field from number
|
||||
---@field to number
|
||||
|
||||
---@class Text
|
||||
---@field lines string[]
|
||||
---@field hl Highlight[]
|
||||
---@field lineNr number
|
||||
---@field current string
|
||||
local Text = {}
|
||||
Text.__index = Text
|
||||
|
||||
function Text.len(str)
|
||||
return vim.fn.strwidth(str)
|
||||
end
|
||||
|
||||
function Text:new()
|
||||
local this = { lines = {}, hl = {}, lineNr = 0, current = "" }
|
||||
setmetatable(this, self)
|
||||
return this
|
||||
end
|
||||
|
||||
function Text:fix_nl(line)
|
||||
return line:gsub("[\n]", "")
|
||||
end
|
||||
|
||||
function Text:nl()
|
||||
local line = self:fix_nl(self.current)
|
||||
table.insert(self.lines, line)
|
||||
self.current = ""
|
||||
self.lineNr = self.lineNr + 1
|
||||
end
|
||||
|
||||
function Text:set(row, col, str, group)
|
||||
str = self:fix_nl(str)
|
||||
|
||||
-- extend lines if needed
|
||||
for i = 1, row, 1 do
|
||||
if not self.lines[i] then
|
||||
self.lines[i] = ""
|
||||
end
|
||||
end
|
||||
|
||||
-- extend columns when needed
|
||||
local width = Text.len(self.lines[row])
|
||||
if width < col then
|
||||
self.lines[row] = self.lines[row] .. string.rep(" ", col - width)
|
||||
end
|
||||
|
||||
local before = vim.fn.strcharpart(self.lines[row], 0, col)
|
||||
local after = vim.fn.strcharpart(self.lines[row], col)
|
||||
self.lines[row] = before .. str .. after
|
||||
|
||||
if not group then
|
||||
return
|
||||
end
|
||||
-- set highlights
|
||||
self:highlight(row, col, col + Text.len(str), "WhichKey" .. group)
|
||||
end
|
||||
|
||||
function Text:highlight(row, from, to, group)
|
||||
local line = self.lines[row]
|
||||
local before = vim.fn.strcharpart(line, 0, from)
|
||||
local str = vim.fn.strcharpart(line, 0, to)
|
||||
from = vim.fn.strlen(before)
|
||||
to = vim.fn.strlen(str)
|
||||
table.insert(self.hl, { line = row - 1, from = from, to = to, group = group })
|
||||
end
|
||||
|
||||
return Text
|
||||
@ -0,0 +1,108 @@
|
||||
local Util = require("which-key.util")
|
||||
|
||||
---@class Tree
|
||||
---@field root Node
|
||||
---@field nodes table<string, Node>
|
||||
local Tree = {}
|
||||
Tree.__index = Tree
|
||||
|
||||
---@class Node
|
||||
---@field mapping Mapping
|
||||
---@field prefix_i string
|
||||
---@field prefix_n string
|
||||
---@field children table<string, Node>
|
||||
-- selene: allow(unused_variable)
|
||||
local Node
|
||||
|
||||
---@return Tree
|
||||
function Tree:new()
|
||||
local this = { root = { children = {}, prefix_i = "", prefix_n = "" }, nodes = {} }
|
||||
setmetatable(this, self)
|
||||
return this
|
||||
end
|
||||
|
||||
---@param prefix_i string
|
||||
---@param index? number defaults to last. If < 0, then offset from last
|
||||
---@param plugin_context? any
|
||||
---@return Node?
|
||||
function Tree:get(prefix_i, index, plugin_context)
|
||||
local prefix = Util.parse_internal(prefix_i)
|
||||
local node = self.root
|
||||
index = index or #prefix
|
||||
if index < 0 then
|
||||
index = #prefix + index
|
||||
end
|
||||
for i = 1, index, 1 do
|
||||
node = node.children[prefix[i]]
|
||||
if node and plugin_context and node.mapping and node.mapping.plugin then
|
||||
local children = require("which-key.plugins").invoke(node.mapping, plugin_context)
|
||||
node.children = {}
|
||||
for _, child in pairs(children) do
|
||||
self:add(child, { cache = false })
|
||||
end
|
||||
end
|
||||
if not node then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
return node
|
||||
end
|
||||
|
||||
-- Returns the path (possibly incomplete) for the prefix
|
||||
---@param prefix_i string
|
||||
---@return Node[]
|
||||
function Tree:path(prefix_i)
|
||||
local prefix = Util.parse_internal(prefix_i)
|
||||
local node = self.root
|
||||
local path = {}
|
||||
for i = 1, #prefix, 1 do
|
||||
node = node.children[prefix[i]]
|
||||
table.insert(path, node)
|
||||
if not node then
|
||||
break
|
||||
end
|
||||
end
|
||||
return path
|
||||
end
|
||||
|
||||
---@param mapping Mapping
|
||||
---@param opts? {cache?: boolean}
|
||||
---@return Node
|
||||
function Tree:add(mapping, opts)
|
||||
opts = opts or {}
|
||||
opts.cache = opts.cache ~= false
|
||||
local node_key = mapping.keys.keys
|
||||
local node = opts.cache and self.nodes[node_key]
|
||||
if not node then
|
||||
local prefix_i = mapping.keys.internal
|
||||
local prefix_n = mapping.keys.notation
|
||||
node = self.root
|
||||
local path_i = ""
|
||||
local path_n = ""
|
||||
for i = 1, #prefix_i, 1 do
|
||||
path_i = path_i .. prefix_i[i]
|
||||
path_n = path_n .. prefix_n[i]
|
||||
if not node.children[prefix_i[i]] then
|
||||
node.children[prefix_i[i]] = { children = {}, prefix_i = path_i, prefix_n = path_n }
|
||||
end
|
||||
node = node.children[prefix_i[i]]
|
||||
end
|
||||
if opts.cache then
|
||||
self.nodes[node_key] = node
|
||||
end
|
||||
end
|
||||
node.mapping = vim.tbl_deep_extend("force", node.mapping or {}, mapping)
|
||||
return node
|
||||
end
|
||||
|
||||
---@param cb fun(node:Node)
|
||||
---@param node? Node
|
||||
function Tree:walk(cb, node)
|
||||
node = node or self.root
|
||||
cb(node)
|
||||
for _, child in pairs(node.children) do
|
||||
self:walk(cb, child)
|
||||
end
|
||||
end
|
||||
|
||||
return Tree
|
||||
@ -0,0 +1,74 @@
|
||||
---@meta
|
||||
|
||||
--# selene: allow(unused_variable)
|
||||
|
||||
---@class Keymap
|
||||
---@field rhs string
|
||||
---@field lhs string
|
||||
---@field buffer number
|
||||
---@field expr number
|
||||
---@field lnum number
|
||||
---@field mode string
|
||||
---@field noremap number
|
||||
---@field nowait number
|
||||
---@field script number
|
||||
---@field sid number
|
||||
---@field silent number
|
||||
---@field callback fun()|nil
|
||||
---@field id string terminal keycodes for lhs
|
||||
---@field desc string
|
||||
|
||||
---@class KeyCodes
|
||||
---@field keys string
|
||||
---@field internal string[]
|
||||
---@field notation string[]
|
||||
|
||||
---@class MappingOptions
|
||||
---@field noremap boolean
|
||||
---@field silent boolean
|
||||
---@field nowait boolean
|
||||
---@field expr boolean
|
||||
|
||||
---@class Mapping
|
||||
---@field buf number
|
||||
---@field group boolean
|
||||
---@field label string
|
||||
---@field desc string
|
||||
---@field prefix string
|
||||
---@field cmd string
|
||||
---@field opts MappingOptions
|
||||
---@field keys KeyCodes
|
||||
---@field mode? string
|
||||
---@field callback fun()|nil
|
||||
---@field preset boolean
|
||||
---@field plugin string
|
||||
---@field fn fun()
|
||||
|
||||
---@class MappingTree
|
||||
---@field mode string
|
||||
---@field buf? number
|
||||
---@field tree Tree
|
||||
|
||||
---@class VisualMapping : Mapping
|
||||
---@field key string
|
||||
---@field highlights table
|
||||
---@field value string
|
||||
|
||||
---@class PluginItem
|
||||
---@field key string
|
||||
---@field label string
|
||||
---@field value string
|
||||
---@field cmd string
|
||||
---@field highlights table
|
||||
|
||||
---@class PluginAction
|
||||
---@field trigger string
|
||||
---@field mode string
|
||||
---@field label? string
|
||||
---@field delay? boolean
|
||||
|
||||
---@class Plugin
|
||||
---@field name string
|
||||
---@field actions PluginAction[]
|
||||
---@field run fun(trigger:string, mode:string, buf:number):PluginItem[]
|
||||
---@field setup fun(wk, opts, Options)
|
||||
@ -0,0 +1,196 @@
|
||||
---@class Util
|
||||
local M = {}
|
||||
local strbyte = string.byte
|
||||
local strsub = string.sub
|
||||
---@type table<string, KeyCodes>
|
||||
local cache = {}
|
||||
---@type table<string,string>
|
||||
local tcache = {}
|
||||
local cache_leaders = ""
|
||||
|
||||
function M.check_cache()
|
||||
---@type string
|
||||
local leaders = (vim.g.mapleader or "") .. ":" .. (vim.g.maplocalleader or "")
|
||||
if leaders ~= cache_leaders then
|
||||
cache = {}
|
||||
tcache = {}
|
||||
cache_leaders = leaders
|
||||
end
|
||||
end
|
||||
|
||||
function M.count(tab)
|
||||
local ret = 0
|
||||
for _, _ in pairs(tab) do
|
||||
ret = ret + 1
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
function M.get_mode()
|
||||
local mode = vim.api.nvim_get_mode().mode
|
||||
mode = mode:gsub(M.t("<C-V>"), "v")
|
||||
mode = mode:gsub(M.t("<C-S>"), "s")
|
||||
return mode:lower()
|
||||
end
|
||||
|
||||
function M.is_empty(tab)
|
||||
return M.count(tab) == 0
|
||||
end
|
||||
|
||||
function M.t(str)
|
||||
M.check_cache()
|
||||
if not tcache[str] then
|
||||
-- https://github.com/neovim/neovim/issues/17369
|
||||
tcache[str] = vim.api.nvim_replace_termcodes(str, false, true, true):gsub("\128\254X", "\128")
|
||||
end
|
||||
return tcache[str]
|
||||
end
|
||||
|
||||
-- stylua: ignore start
|
||||
local utf8len_tab = {
|
||||
-- ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 0?
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1?
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 2?
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 3?
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 4?
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 5?
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 6?
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 7?
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 8?
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 9?
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- A?
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- B?
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- C?
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- D?
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -- E?
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1, -- F?
|
||||
}
|
||||
-- stylua: ignore end
|
||||
|
||||
local Tokens = {
|
||||
["<"] = strbyte("<"),
|
||||
[">"] = strbyte(">"),
|
||||
["-"] = strbyte("-"),
|
||||
}
|
||||
---@return KeyCodes
|
||||
function M.parse_keys(keystr)
|
||||
M.check_cache()
|
||||
if cache[keystr] then
|
||||
return cache[keystr]
|
||||
end
|
||||
|
||||
local keys = M.t(keystr)
|
||||
local internal = M.parse_internal(keys)
|
||||
|
||||
if #internal == 0 then
|
||||
local ret = { keys = keys, internal = {}, notation = {} }
|
||||
cache[keystr] = ret
|
||||
return ret
|
||||
end
|
||||
|
||||
local keystr_orig = keystr
|
||||
keystr = keystr:gsub("<lt>", "<")
|
||||
local notation = {}
|
||||
---@alias ParseState
|
||||
--- | "Character"
|
||||
--- | "Special"
|
||||
--- | "SpecialNoClose"
|
||||
local start = 1
|
||||
local i = start
|
||||
---@type ParseState
|
||||
local state = "Character"
|
||||
while i <= #keystr do
|
||||
local c = strbyte(keystr, i, i)
|
||||
|
||||
if state == "Character" then
|
||||
start = i
|
||||
-- Only interpret special tokens if neovim also replaces it
|
||||
state = c == Tokens["<"] and internal[#notation + 1] ~= "<" and "Special" or state
|
||||
elseif state == "Special" then
|
||||
state = (c == Tokens["-"] and "SpecialNoClose") or (c == Tokens[">"] and "Character") or state
|
||||
else
|
||||
state = "Special"
|
||||
end
|
||||
|
||||
i = i + utf8len_tab[c + 1]
|
||||
if state == "Character" then
|
||||
local k = strsub(keystr, start, i - 1)
|
||||
notation[#notation + 1] = k == " " and "<space>" or k
|
||||
end
|
||||
end
|
||||
|
||||
local mapleader = vim.g.mapleader
|
||||
mapleader = mapleader and M.t(mapleader)
|
||||
notation[1] = internal[1] == mapleader and "<leader>" or notation[1]
|
||||
|
||||
if #notation ~= #internal then
|
||||
error(vim.inspect({ keystr = keystr, internal = internal, notation = notation }))
|
||||
end
|
||||
|
||||
local ret = {
|
||||
keys = keys,
|
||||
internal = internal,
|
||||
notation = notation,
|
||||
}
|
||||
|
||||
cache[keystr_orig] = ret
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
-- @return string[]
|
||||
function M.parse_internal(keystr)
|
||||
local keys = {}
|
||||
---@alias ParseInternalState
|
||||
--- | "Character"
|
||||
--- | "Special"
|
||||
---@type ParseInternalState
|
||||
local state = "Character"
|
||||
local start = 1
|
||||
local i = 1
|
||||
while i <= #keystr do
|
||||
local c = strbyte(keystr, i, i)
|
||||
|
||||
if state == "Character" then
|
||||
state = c == 128 and "Special" or state
|
||||
i = i + utf8len_tab[c + 1]
|
||||
|
||||
if state == "Character" then
|
||||
keys[#keys + 1] = strsub(keystr, start, i - 1)
|
||||
start = i
|
||||
end
|
||||
else
|
||||
-- This state is entered on the second byte of K_SPECIAL sequence.
|
||||
if c == 252 then
|
||||
-- K_SPECIAL KS_MODIFIER: skip this byte and the next
|
||||
i = i + 2
|
||||
else
|
||||
-- K_SPECIAL _: skip this byte
|
||||
i = i + 1
|
||||
end
|
||||
-- The last byte of this sequence should be between 0x02 and 0x7f,
|
||||
-- switch to Character state to collect.
|
||||
state = "Character"
|
||||
end
|
||||
end
|
||||
return keys
|
||||
end
|
||||
|
||||
function M.warn(msg)
|
||||
vim.notify(msg, vim.log.levels.WARN, { title = "WhichKey" })
|
||||
end
|
||||
|
||||
function M.error(msg)
|
||||
vim.notify(msg, vim.log.levels.ERROR, { title = "WhichKey" })
|
||||
end
|
||||
|
||||
function M.check_mode(mode, buf)
|
||||
if not ("nvsxoiRct"):find(mode) then
|
||||
M.error(string.format("Invalid mode %q for buf %d", mode, buf or 0))
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,350 @@
|
||||
local Keys = require("which-key.keys")
|
||||
local config = require("which-key.config")
|
||||
local Layout = require("which-key.layout")
|
||||
local Util = require("which-key.util")
|
||||
|
||||
local highlight = vim.api.nvim_buf_add_highlight
|
||||
|
||||
---@class View
|
||||
local M = {}
|
||||
|
||||
M.keys = ""
|
||||
M.mode = "n"
|
||||
M.reg = nil
|
||||
M.auto = false
|
||||
M.count = 0
|
||||
M.buf = nil
|
||||
M.win = nil
|
||||
|
||||
function M.is_valid()
|
||||
return M.buf
|
||||
and M.win
|
||||
and vim.api.nvim_buf_is_valid(M.buf)
|
||||
and vim.api.nvim_buf_is_loaded(M.buf)
|
||||
and vim.api.nvim_win_is_valid(M.win)
|
||||
end
|
||||
|
||||
function M.show()
|
||||
if vim.b.visual_multi then
|
||||
vim.b.VM_skip_reset_once_on_bufleave = true
|
||||
end
|
||||
if M.is_valid() then
|
||||
return
|
||||
end
|
||||
|
||||
-- non-floating windows
|
||||
local wins = vim.tbl_filter(function(w)
|
||||
return vim.api.nvim_win_is_valid(w) and vim.api.nvim_win_get_config(w).relative == ""
|
||||
end, vim.api.nvim_list_wins())
|
||||
|
||||
---@type number[]
|
||||
local margins = {}
|
||||
for i, m in ipairs(config.options.window.margin) do
|
||||
if m > 0 and m < 1 then
|
||||
if i % 2 == 0 then
|
||||
m = math.floor(vim.o.columns * m)
|
||||
else
|
||||
m = math.floor(vim.o.lines * m)
|
||||
end
|
||||
end
|
||||
margins[i] = m
|
||||
end
|
||||
|
||||
local opts = {
|
||||
relative = "editor",
|
||||
width = vim.o.columns
|
||||
- margins[2]
|
||||
- margins[4]
|
||||
- (vim.fn.has("nvim-0.6") == 0 and config.options.window.border ~= "none" and 2 or 0),
|
||||
height = config.options.layout.height.min,
|
||||
focusable = false,
|
||||
anchor = "SW",
|
||||
border = config.options.window.border,
|
||||
row = vim.o.lines
|
||||
- margins[3]
|
||||
- (vim.fn.has("nvim-0.6") == 0 and config.options.window.border ~= "none" and 2 or 0)
|
||||
+ ((vim.o.laststatus == 0 or vim.o.laststatus == 1 and #wins == 1) and 1 or 0)
|
||||
- vim.o.cmdheight,
|
||||
col = margins[4],
|
||||
style = "minimal",
|
||||
noautocmd = true,
|
||||
zindex = config.options.window.zindex,
|
||||
}
|
||||
if config.options.window.position == "top" then
|
||||
opts.anchor = "NW"
|
||||
opts.row = margins[1]
|
||||
end
|
||||
M.buf = vim.api.nvim_create_buf(false, true)
|
||||
M.win = vim.api.nvim_open_win(M.buf, false, opts)
|
||||
vim.api.nvim_buf_set_option(M.buf, "filetype", "WhichKey")
|
||||
vim.api.nvim_buf_set_option(M.buf, "buftype", "nofile")
|
||||
vim.api.nvim_buf_set_option(M.buf, "bufhidden", "wipe")
|
||||
vim.api.nvim_buf_set_option(M.buf, "modifiable", true)
|
||||
|
||||
local winhl = "NormalFloat:WhichKeyFloat"
|
||||
if vim.fn.hlexists("FloatBorder") == 1 then
|
||||
winhl = winhl .. ",FloatBorder:WhichKeyBorder"
|
||||
end
|
||||
vim.api.nvim_win_set_option(M.win, "winhighlight", winhl)
|
||||
vim.api.nvim_win_set_option(M.win, "foldmethod", "manual")
|
||||
vim.api.nvim_win_set_option(M.win, "winblend", config.options.window.winblend)
|
||||
end
|
||||
|
||||
function M.read_pending()
|
||||
local esc = ""
|
||||
while true do
|
||||
local n = vim.fn.getchar(0)
|
||||
if n == 0 then
|
||||
break
|
||||
end
|
||||
local c = (type(n) == "number" and vim.fn.nr2char(n) or n)
|
||||
|
||||
-- HACK: for some reason, when executing a :norm command,
|
||||
-- vim keeps feeding <esc> at the end
|
||||
if c == Util.t("<esc>") then
|
||||
esc = esc .. c
|
||||
-- more than 10 <esc> in a row? most likely the norm bug
|
||||
if #esc > 10 then
|
||||
return
|
||||
end
|
||||
else
|
||||
-- we have <esc> characters, so add them to keys
|
||||
if esc ~= "" then
|
||||
M.keys = M.keys .. esc
|
||||
esc = ""
|
||||
end
|
||||
M.keys = M.keys .. c
|
||||
end
|
||||
end
|
||||
if esc ~= "" then
|
||||
M.keys = M.keys .. esc
|
||||
esc = ""
|
||||
end
|
||||
end
|
||||
|
||||
function M.getchar()
|
||||
local ok, n = pcall(vim.fn.getchar)
|
||||
|
||||
-- bail out on keyboard interrupt
|
||||
if not ok then
|
||||
return Util.t("<esc>")
|
||||
end
|
||||
|
||||
local c = (type(n) == "number" and vim.fn.nr2char(n) or n)
|
||||
return c
|
||||
end
|
||||
|
||||
function M.scroll(up)
|
||||
local height = vim.api.nvim_win_get_height(M.win)
|
||||
local cursor = vim.api.nvim_win_get_cursor(M.win)
|
||||
if up then
|
||||
cursor[1] = math.max(cursor[1] - height, 1)
|
||||
else
|
||||
cursor[1] = math.min(cursor[1] + height, vim.api.nvim_buf_line_count(M.buf))
|
||||
end
|
||||
vim.api.nvim_win_set_cursor(M.win, cursor)
|
||||
end
|
||||
|
||||
function M.on_close()
|
||||
M.hide()
|
||||
end
|
||||
|
||||
function M.hide()
|
||||
vim.api.nvim_echo({ { "" } }, false, {})
|
||||
M.hide_cursor()
|
||||
if M.buf and vim.api.nvim_buf_is_valid(M.buf) then
|
||||
vim.api.nvim_buf_delete(M.buf, { force = true })
|
||||
M.buf = nil
|
||||
end
|
||||
if M.win and vim.api.nvim_win_is_valid(M.win) then
|
||||
vim.api.nvim_win_close(M.win, true)
|
||||
M.win = nil
|
||||
end
|
||||
vim.cmd("redraw")
|
||||
end
|
||||
|
||||
function M.show_cursor()
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||
vim.api.nvim_buf_add_highlight(buf, config.namespace, "Cursor", cursor[1] - 1, cursor[2], cursor[2] + 1)
|
||||
end
|
||||
|
||||
function M.hide_cursor()
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
vim.api.nvim_buf_clear_namespace(buf, config.namespace, 0, -1)
|
||||
end
|
||||
|
||||
function M.back()
|
||||
local node = Keys.get_tree(M.mode, M.buf).tree:get(M.keys, -1) or Keys.get_tree(M.mode).tree:get(M.keys, -1)
|
||||
if node then
|
||||
M.keys = node.prefix_i
|
||||
end
|
||||
end
|
||||
|
||||
function M.execute(prefix_i, mode, buf)
|
||||
local global_node = Keys.get_tree(mode).tree:get(prefix_i)
|
||||
local buf_node = buf and Keys.get_tree(mode, buf).tree:get(prefix_i) or nil
|
||||
|
||||
if global_node and global_node.mapping and Keys.is_hook(prefix_i, global_node.mapping.cmd) then
|
||||
return
|
||||
end
|
||||
if buf_node and buf_node.mapping and Keys.is_hook(prefix_i, buf_node.mapping.cmd) then
|
||||
return
|
||||
end
|
||||
|
||||
local hooks = {}
|
||||
|
||||
local function unhook(nodes, nodes_buf)
|
||||
for _, node in pairs(nodes) do
|
||||
if Keys.is_hooked(node.mapping.prefix, mode, nodes_buf) then
|
||||
table.insert(hooks, { node.mapping.prefix, nodes_buf })
|
||||
Keys.hook_del(node.mapping.prefix, mode, nodes_buf)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- make sure we remove all WK hooks before executing the sequence
|
||||
-- this is to make existing keybindongs work and prevent recursion
|
||||
unhook(Keys.get_tree(mode).tree:path(prefix_i))
|
||||
if buf then
|
||||
unhook(Keys.get_tree(mode, buf).tree:path(prefix_i), buf)
|
||||
end
|
||||
|
||||
-- feed CTRL-O again if called from CTRL-O
|
||||
local full_mode = Util.get_mode()
|
||||
if full_mode == "nii" or full_mode == "nir" or full_mode == "niv" or full_mode == "vs" then
|
||||
vim.api.nvim_feedkeys(Util.t("<C-O>"), "n", false)
|
||||
end
|
||||
|
||||
-- handle registers that were passed when opening the popup
|
||||
if M.reg ~= '"' and M.mode ~= "i" and M.mode ~= "c" then
|
||||
vim.api.nvim_feedkeys('"' .. M.reg, "n", false)
|
||||
end
|
||||
|
||||
if M.count and M.count ~= 0 then
|
||||
prefix_i = M.count .. prefix_i
|
||||
end
|
||||
|
||||
-- feed the keys with remap
|
||||
vim.api.nvim_feedkeys(prefix_i, "m", true)
|
||||
|
||||
-- defer hooking WK until after the keys were executed
|
||||
vim.defer_fn(function()
|
||||
for _, hook in pairs(hooks) do
|
||||
Keys.hook_add(hook[1], mode, hook[2])
|
||||
end
|
||||
end, 0)
|
||||
end
|
||||
|
||||
function M.open(keys, opts)
|
||||
opts = opts or {}
|
||||
M.keys = keys or ""
|
||||
M.mode = opts.mode or Util.get_mode()
|
||||
M.count = vim.api.nvim_get_vvar("count")
|
||||
M.reg = vim.api.nvim_get_vvar("register")
|
||||
|
||||
if string.find(vim.o.clipboard, "unnamedplus") and M.reg == "+" then
|
||||
M.reg = '"'
|
||||
end
|
||||
|
||||
if string.find(vim.o.clipboard, "unnamed") and M.reg == "*" then
|
||||
M.reg = '"'
|
||||
end
|
||||
|
||||
M.show_cursor()
|
||||
M.on_keys(opts)
|
||||
end
|
||||
|
||||
function M.is_enabled(buf)
|
||||
local buftype = vim.api.nvim_buf_get_option(buf, "buftype")
|
||||
for _, bt in ipairs(config.options.disable.buftypes) do
|
||||
if bt == buftype then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local filetype = vim.api.nvim_buf_get_option(buf, "filetype")
|
||||
for _, bt in ipairs(config.options.disable.filetypes) do
|
||||
if bt == filetype then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function M.on_keys(opts)
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
|
||||
while true do
|
||||
-- loop
|
||||
M.read_pending()
|
||||
|
||||
local results = Keys.get_mappings(M.mode, M.keys, buf)
|
||||
|
||||
--- Check for an exact match. Feedkeys with remap
|
||||
if results.mapping and not results.mapping.group and #results.mappings == 0 then
|
||||
M.hide()
|
||||
if results.mapping.fn then
|
||||
results.mapping.fn()
|
||||
else
|
||||
M.execute(M.keys, M.mode, buf)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Check for no mappings found. Feedkeys without remap
|
||||
if #results.mappings == 0 then
|
||||
M.hide()
|
||||
-- only execute if an actual key was typed while WK was open
|
||||
if opts.auto then
|
||||
M.execute(M.keys, M.mode, buf)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local layout = Layout:new(results)
|
||||
|
||||
if M.is_enabled(buf) then
|
||||
if not M.is_valid() then
|
||||
M.show()
|
||||
end
|
||||
|
||||
M.render(layout:layout(M.win))
|
||||
end
|
||||
vim.cmd([[redraw]])
|
||||
|
||||
local c = M.getchar()
|
||||
|
||||
if c == Util.t("<esc>") then
|
||||
M.hide()
|
||||
break
|
||||
elseif c == Util.t(config.options.popup_mappings.scroll_down) then
|
||||
M.scroll(false)
|
||||
elseif c == Util.t(config.options.popup_mappings.scroll_up) then
|
||||
M.scroll(true)
|
||||
elseif c == Util.t("<bs>") then
|
||||
M.back()
|
||||
else
|
||||
M.keys = M.keys .. c
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param text Text
|
||||
function M.render(text)
|
||||
vim.api.nvim_buf_set_lines(M.buf, 0, -1, false, text.lines)
|
||||
local height = #text.lines
|
||||
if height > config.options.layout.height.max then
|
||||
height = config.options.layout.height.max
|
||||
end
|
||||
vim.api.nvim_win_set_height(M.win, height)
|
||||
if vim.api.nvim_buf_is_valid(M.buf) then
|
||||
vim.api.nvim_buf_clear_namespace(M.buf, config.namespace, 0, -1)
|
||||
end
|
||||
for _, data in ipairs(text.hl) do
|
||||
highlight(M.buf, config.namespace, data.group, data.line, data.from, data.to)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1 @@
|
||||
command! -nargs=* WhichKey lua require('which-key').show_command(<f-args>)
|
||||
@ -0,0 +1 @@
|
||||
std="lua51+vim"
|
||||
@ -0,0 +1,3 @@
|
||||
indent_type = "Spaces"
|
||||
indent_width = 2
|
||||
column_width = 120
|
||||
2
config/neovim/store/lazy-plugins/which-key.nvim/vim.toml
Normal file
2
config/neovim/store/lazy-plugins/which-key.nvim/vim.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[vim]
|
||||
any = true
|
||||
Reference in New Issue
Block a user