Ecosyste.ms: Awesome

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

Awesome Lists | Featured Topics | Projects

https://github.com/Cassin01/wf.nvim

A modern which-key for neovim
https://github.com/Cassin01/wf.nvim

neovim neovim-lua neovim-plugin nvim nvim-plugin

Last synced: 11 days ago
JSON representation

A modern which-key for neovim

Awesome Lists containing this project

README

        

[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
[![MIT License][license-shield]][license-url]
[![Build Status][ci-shield]][ci-url]






Logo





Explore the docs ยป




View Demo
ยท
Report Bug
ยท
Request Feature


Table of Contents



  1. About The Project

  2. Installation

  3. Getting started

  4. Configuration

  5. Default Shortcut / Key
    Bindings Assignments

  6. Documentation

  7. How to use as a picker

  8. Contributing

  9. License

  10. Credits

## About The Project


https://user-images.githubusercontent.com/42632201/219690019-a5615bac-6747-41d8-a10e-ddae151af5c2.mp4

[The video link for mobile users](https://youtu.be/S3aKshSPyiQ)

`wf.nvim` is a new which-key like plugin for Neovim.

### โœจ Features
- Built-in fuzzy-finder
- Does not provide a default global keymap
- Using `nvim_set_keymap`'s "desc" feature (see `:help nvim_set_keymap`)
- for Neovim 0.7 and higher, it uses the desc as key description
- Skip duplicate characters (`skip_front_duplication`, `skip_back_duplication`)
- Builtin pickers:
* `which-key`: displays key mappings to invoke
* `mark`: displays marks to move
* `bookmark`: displays file paths to open
* `buffer`: displays buffers to focus
* `register`: displays the contents of registers

### The difference with [which-key.nvim](https://github.com/folke/which-key.nvim)

The display of `wf.nvim` is displayed in a row at the bottom right like [helix](https://helix-editor.com/). Instead of displaying multiple columns at the bottom like [spacemacs](https://www.spacemacs.org/) style. This has improved the display speed of multibyte characters in particular.

#### Pros
- The layout does not collapse even if multibyte characters are included.
- You can use the builtin fuzzy finder to find forgotten shortcuts.
- Three themes(default, space, chad) are offered.
- Fits any color scheme.
- The colors change to match the color scheme.
- Stress-free selection even when long letters are available as options.
- See `skip_front_duplication` and `skip_back_duplication` at the document.
- Modal selection is made possible by adopting an event-driven architecture instead of waiting for a key with a while loop.

#### Cons
- Slower processing speed for larger number of runtime process

(back to top)

## Installation

Package manager
Snippet

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

```lua
-- stable version
use {"Cassin01/wf.nvim", tag = "*", config = function() require("wf").setup() end}
-- dev version
use {"Cassin01/wf.nvim", config = function() require("wf").setup() end}
```

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

```vim
call plug#begin()
-- stable version
Plug "Cassin01/wf.nvim", { "tag": "*" }
-- dev version
Plug "Cassin01/wf.nvim"
call plug#end()

lua << EOF
require("wf").setup()
EOF
```

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

```lua
-- stable version
require("lazy").setup({{"Cassin01/wf.nvim", version = "*", config = function() require("wf").setup() end}})
-- dev version
require("lazy").setup({{"Cassin01/wf.nvim", config = function() require("wf").setup() end}})
```

(back to top)

## Getting started


Neovim >= 0.9.0 and
[nvim-web-devicons](https://github.com/nvim-tree/nvim-web-devicons) is recommended
for enjoying all the features of `wf.nvim`.

Minimal Setup

```lua
local which_key = require("wf.builtin.which_key")
local register = require("wf.builtin.register")
local bookmark = require("wf.builtin.bookmark")
local buffer = require("wf.builtin.buffer")
local mark = require("wf.builtin.mark")

-- Register
vim.keymap.set(
"n",
"wr",
-- register(opts?: table) -> function
-- opts?: option
register(),
{ noremap = true, silent = true, desc = "[wf.nvim] register" }
)

-- Bookmark
vim.keymap.set(
"n",
"wbo",
-- bookmark(bookmark_dirs: table, opts?: table) -> function
-- bookmark_dirs: directory or file paths
-- opts?: option
bookmark({
nvim = "~/.config/nvim",
zsh = "~/.zshrc",
}),
{ noremap = true, silent = true, desc = "[wf.nvim] bookmark" }
)

-- Buffer
vim.keymap.set(
"n",
"wbu",
-- buffer(opts?: table) -> function
-- opts?: option
buffer(),
{noremap = true, silent = true, desc = "[wf.nvim] buffer"}
)

-- Mark
vim.keymap.set(
"n",
"'",
-- mark(opts?: table) -> function
-- opts?: option
mark(),
{ nowait = true, noremap = true, silent = true, desc = "[wf.nvim] mark"}
)

-- Which Key
vim.keymap.set(
"n",
"",
-- mark(opts?: table) -> function
-- opts?: option
which_key({ text_insert_in_advance = "" }),
{ noremap = true, silent = true, desc = "[wf.nvim] which-key /", }
)
```

If you are concerned about the lag between pressing the shortcut that activates `which-key` and the actual activation of `which-key`, you can put the `nowait` option in the keymap. (Not recommended.)

However, in order for the key to be invoked nowait, the shortcut to invoke `which-key` must be at the end of the `init.lua` file.
Below is an example of using `timeout` to delay the registration of the shortcut that activates `which-key`.

```lua
-- set keymaps with `nowait`
-- see `:h :map-nowait`

-- a timer to call a callback after a specified number of milliseconds.
local function timeout(ms, callback)
local uv = vim.loop
local timer = uv.new_timer()
local _callback = vim.schedule_wrap(function()
uv.timer_stop(timer)
uv.close(timer)
callback()
end)
uv.timer_start(timer, ms, 0, _callback)
end
timeout(100, function()
vim.keymap.set(
"n",
"",
which_key({ text_insert_in_advance = "" }),
{ noremap = true, silent = true, desc = "[wf.nvim] which-key /", }
)
end)
vim.api.nvim_create_autocmd({"BufEnter", "BufAdd"}, {
group = vim.api.nvim_create_augroup("my_wf", { clear = true }),
callback = function()
timeout(100, function()
vim.keymap.set(
"n",
"",
which_key({ text_insert_in_advance = "" }),
{ noremap = true, silent = true, desc = "[wf.nvim] which-key /", buffer = true })
end)
end
})
```

(back to top)

## Configuration

```lua
require("wf").setup({
theme = "default",
-- you can copy the full list from lua/wf/setup/init.lua
})
```

(back to top)

## Key Bindings Assignments

The default key assignments are shown in the table below.

| Mode | Key | Action |
| - | - | - |
| Normal, Insert | `` | Toggle the which-key with the fuzzy-find |
| Normal | `` | Close wf.nvim |
| Normal | `` | Close wf.nvim |

(back to top)

## How to use as a picker

The core concept of `wf.nvim` is to extend the functionality of which-key so that it can be used as a picker rather than just a shortcut completion.

To realize this concept, `wf.nvim` can be used as a picker to select an item from arbitrary items like `vim.ui.select({items}, {opts}, {on_choice})`, i.e. `wf.select({items}, {opts}, {on_choice})`.

Example:
```lua
require("wf").select({happy = "๐Ÿ˜Š", sad = "๐Ÿ˜ฅ"}, {
title = "Select your feelings:", behavior = {
skip_front_duplication = true,
skip_back_duplication = true,
},
}, function(text, key)
-- You feel happy๐Ÿ˜Š.
vim.notify("You feel " .. key .. text .. ".")
end)
end
```

(back to top)

## Documentation

You can find guides for the plugin on [the document](https://github.com/Cassin01/wf.nvim/blob/main/doc/wf.txt).

(back to top)

## Tips

### Holding specific key pattern on which_key

Below is an example of using `keys_group_dict`. `keys_group_dict` is a list of prefix patterns.
Keys with that pattern can be grouped together when displayed.

```lua
-- setup table for prefixes
---------------------------------------
if _G.__key_prefixes == nil then
_G.__key_prefixes = {
n = {},
i = {},
}
end

-- utility function for setting keymaps
---------------------------------------
local function nmaps(prefix, group, tbl)
local sign = "[" .. group .. "] "
table.insert(_G.__key_prefixes["n"], prefix, sign)
local set = function(key, cmd, desc, opt)
local _opt = opt or {}
_opt["desc"] = sign .. desc
_opt["noremap"] = true
vim.keymap.set("n", prefix .. key, cmd, _opt)
end
for _, v in ipairs(tbl) do
set(unpack(v))
end
end

-- set keymap for each plugins
---------------------------------------
-- lambdalisue/fern.vim
nmaps("n", "fern",
{{"p", "Fern . -drawer -toggle", "open fern on a current working directory"},
{"d", "Fern %:h -drawer -toggle", "open fern on a parent directory of a current buffer"}})

-- nvim-telescope/telescope.nvim
nmaps("t", "telescope"
{{"f", "Telescope find_files", "find files"},
{"g", "Telescope live_grep", "live grep"},
{"b", "Telescope buffers", "buffers"},
{"h", "Telescope help_tags", "help tags"},
{"t", "Telescope", "telescope"},
{"o", "Telescope oldfiles", "old files"},
{"r", "Telescope file_browser", "file_browser"}})

-- set keymap for calling which-key
---------------------------------------
vim.set.keymap("n", "",
which_key({text_insert_in_advance="", key_group_dict=_G.__key_prefixes["n"]}),
{noremap = true, silent = tre, desc = "which-key space", nowait = true})
```

(back to top)

## Contributing

Any contributions you make are **greatly appreciated**.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".
Don't forget to give the project a star! Thanks again!

Development flow basically follows [git-flow](https://nvie.com/posts/a-successful-git-branching-model/).

1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Generate document, format codes and test codes (`make push`)
4. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
5. Push to the Branch (`git push origin feature/AmazingFeature`)
6. Open a Pull Request

(back to top)

## License

Distributed under the MIT License. See `LICENSE.txt` for more information.

(back to top)

## Credits

### CI, README
- [shortcuts/neovim-plugin-boilerplate](https://github.com/shortcuts/neovim-plugin-boilerplate)
- [echasnovski/mini.nvim](https://github.com/echasnovski/mini.nvim)
- [othneildrew/Best-README-Template](https://github.com/othneildrew/Best-README-Template)
### Picker
- [nvim-telescope/telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
- [folke/which-key.nvim](https://github.com/folke/which-key.nvim)
- [liuchengxu/vim-which-key](https://github.com/liuchengxu/vim-which-key)
### Which-key
- [justbuf/emacs-which-key](https://github.com/justbur/emacs-which-key)
- [helix-editor/helix](https://github.com/helix-editor/helix)
- [syl20bnr/spacemacs](https://github.com/syl20bnr/spacemacs)
### Theme
- [NvChad/NvChad](https://github.com/NvChad/NvChad)

### buffer-switcher

- [matbme/JABS.nvim](https://github.com/matbme/JABS.nvim)

(back to top)

[contributors-shield]: https://img.shields.io/github/contributors/Cassin01/wf.nvim.svg?style=for-the-badge
[contributors-url]: https://github.com/Cassin01/wf.nvim/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/Cassin01/wf.nvim.svg?style=for-the-badge
[forks-url]: https://github.com/Cassin01/wf.nvim/network/members
[stars-shield]: https://img.shields.io/github/stars/Cassin01/wf.nvim.svg?style=for-the-badge
[stars-url]: https://github.com/Cassin01/wf.nvim/stargazers
[issues-shield]: https://img.shields.io/github/issues/Cassin01/wf.nvim.svg?style=for-the-badge
[issues-url]: https://github.com/Cassin01/wf.nvim/issues
[license-shield]: https://img.shields.io/github/license/Cassin01/wf.nvim.svg?style=for-the-badge
[license-url]: https://github.com/Cassin01/wf.nvim/blob/main/LICENSE.txt
[ci-shield]: https://img.shields.io/github/actions/workflow/status/Cassin01/wf.nvim/main.yml?style=for-the-badge
[ci-url]: https://github.com/Cassin01/wf.nvim/actions/workflows/main.yml
[document-shield]: https://img.shields.io/github/actions/workflow/status/Cassin01/wf.nvim/main.yml?style=for-the-badge
[document-url]: https://github.com/Cassin01/wf.nvim/actions/workflows/main.yml
[product-screenshot]: https://user-images.githubusercontent.com/42632201/213849418-3cddb8bb-7323-4af7-b201-1ce2de07d3b9.png
[product-video]: .github/images/theme.mp4