Cassin01 / wf.nvim

A modern which-key for neovim
MIT License
208 stars 3 forks source link
neovim neovim-lua neovim-plugin nvim nvim-plugin

Contributors Forks Stargazers Issues MIT License Build Status


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

The difference with which-key.nvim

The display of wf.nvim is displayed in a row at the bottom right like helix. Instead of displaying multiple columns at the bottom like spacemacs style. This has improved the display speed of multibyte characters in particular.

Pros

Cons

(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
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",
  "<Space>wr",
  -- register(opts?: table) -> function
  -- opts?: option
  register(),
  { noremap = true, silent = true, desc = "[wf.nvim] register" }
)

-- Bookmark
vim.keymap.set(
  "n",
  "<Space>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",
  "<Space>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",
  "<Leader>",
   -- mark(opts?: table) -> function
   -- opts?: option
  which_key({ text_insert_in_advance = "<Leader>" }),
  { 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.

-- 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",
    "<Leader>",
    which_key({ text_insert_in_advance = "<Leader>" }),
    { 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",
        "<Leader>",
        which_key({ text_insert_in_advance = "<Leader>" }),
        { noremap = true, silent = true, desc = "[wf.nvim] which-key /", buffer = true })
    end)
  end
})

(back to top)

Configuration

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 <c-t> Toggle the which-key with the fuzzy-find
Normal <esc> Close wf.nvim
Normal <c-c> 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:

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.

(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.

-- 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("<space>n", "fern",
{{"p", "<cmd>Fern . -drawer -toggle<cr>", "open fern on a current working directory"},
 {"d", "<cmd>Fern %:h -drawer -toggle<cr>", "open fern on a parent directory of a current buffer"}})

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

-- set keymap for calling which-key
---------------------------------------
vim.set.keymap("n", "<Space>",
which_key({text_insert_in_advance="<space>", 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.

  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

buffer-switcher

(back to top)