Skip to content

Cassin01/wf.nvim

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Contributors Forks Stargazers Issues MIT License Build Status


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

theme.mp4

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

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

  • 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

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

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

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

Picker

Which-key

Theme

buffer-switcher

(back to top)