Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added bindings from vim index #120

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

mly32
Copy link
Contributor

@mly32 mly32 commented Jul 5, 2021

Summary

The built-in bindings described in which-key aren't exhaustive, and I would like them to be. This PR changes the preset keybindings. Namely, it adds the extra (default is off) and mouse options to the preset configuration.

The extra option changes other plugin descriptions (including presets, marks, and registers).
The mouse option only works with extra turned on.

Different from the current preset, entering visual mode does not count as an operator.

Some Greek characters are used to indicate some information about the commands, just like how + is used to indicate a prefix by default:

suffixes
.{char}				.δ
.{register}({regname})		.λ
.{number}			.σ
.{motion}			.ξ
.{filter}			.ζ
.{pattern}			.π
.{0-9a-zA-Z"}			.φ
.{a-z}				.α
.{A-Za-z}			.β
.{mark}({a-zA-Z0-9})		.μ
.{expr}				.ε

shorthands
cursor			Δ
motion command		Ξ
highlighted area	Θ
["x]A command		Λ
undo/redoable		Ψ


... under the cursor		Δ...
... in front of the cursor 	...Δ


not added
{char}.{char}			.
{count}.			.
.{mode}				.
.{range}			.

The suffix symbols are added at the beginning of descriptions to indicate what the current command expects next. The shorthands follow these symbols with a , to indicate what type of command the current keybinding is. The shorthands (especially Δ) are used to decrease the length of descriptions.

For example,

  • ["c"] = "ξ,ΛΨ_(change) delete text, start insert" means c expects a motion afterward and is a command that has the optional register prefix and can be undone;
  • ["0"] = "Ξ_Δ to the first char of the line", means 0 is a motion and the description translates to "cursor to the first character of the line;
  • ["<C-a>"] = "Ψ_add N to number at/after Δ", means <C-a> is a normal keybind that can be undone, it translates to "add N to number at or after the cursor".

For each mode, there are the following tables:

  • mapping: keybindings that are shown if extra is true;
  • same_as: keybindings that are the "same as" a keybinding already in mapping, these keybindings are not shown;
  • mode: keybindings with the <C-\> prefix for switching modes, these keybindings are not shown;
  • mouse: keybindings involving the mouse, these are shown if mouse is true;
  • not_included: keybindings are not shown either because their descriptions are too long, or there are issues properly displaying them;
  • when: shows what keybindings' descriptions change should a setting change (e.g., if wrap is on or off);
  • not_used: keybindings that are described with "not used" in vim documentation, yet are still included.

The following settings are relevant to when:

  • wrap
  • mem_profile
  • allowrevins (this setting is added to mappings anyway)
  • digraph
  • tildeop
  • cedit
  • wildchar

The following keybindings are "not included":

  • in insert and command-line mode
    • <C-v>{char} (note that <C-v>{number} is included
  • in normal mode
    • {count}%
    • {count}<Del>
    • z{height}<CR>
    • gV
    • numbers (1-9)
    • {count}:

There are commands that share a prefix with triggers for the marks, registers, and spelling plugins. In the relevant plugin files are the commands that are missing. They are not shown anywhere, but I would like them to be shown.

Since entering visual mode is no longer considered an operator, typing v will not show the operator-pending keybindings. This was done because the keybindings between operator-pending and visual-mode are not exactly the same.

However, a deep mapping was added to the operator pending keybindings v, V, and <C-v> where they are prefixes to the visual keybindings. In this way cvj (change visual down) shows all keybindings each step, but v switches to visual mode without showing keybindings.

Notes

There can be the following additional configuration options (not implemented):

  • a plugin for digraphs
  • an option for deep mappings (like how the visual modes are shown in the presets)
  • choose a naming style (e.g., <c-s-o> vs. <C-S-o> vs. <C-S-O>).
  • have a field during setup to add a list of renames for the descriptions for the preset built-in keybindings.
  • have options to replace the Greek symbols used as icons.
  • like how there is the operators option in the setup, there could also be a motions option.
  • have a toggle for showing or hiding:
    • "same as" keybindings (e.g., h = <Left> = <C-h> = <BS>),
  • check the state of certain settings to display different commands (e.g., wrap).

This a snippet of my nvim config:

local util = require('util')
local wk = require('which-key')
wk.setup({
  plugins = {presets = {extra = true, mouse = true}},
  key_labels = {
    ["<LT>"] = "<",
    ["<ScrollWheelDown>"] = '<ScrollDown>',
    ["<S-ScrollWheelDown>"] = '<S-ScrollDown>',
    ["<ScrollWheelUp>"] = '<ScrollUp>',
    ["<S-ScrollWheelUp>"] = '<S-ScrollUp>',
    ["<ScrollWheelLeft>"] = '<ScrollLeft>',
    ["<S-ScrollWheelLeft>"] = '<S-ScrollLeft>',
    ["<ScrollWheelRight>"] = '<ScrollRight>',
    ["<S-ScrollWheelRight>"] = '<S-ScrollRight>'
  },
  icons = {group = ""},
  layout = {height = {min = 4, max = 32}, width = {min = 20, max = 80}},
  triggers_blacklist = {}
})

wk.register({['<Leader>h'] = {name = 'WhichKey'}})

local modes = {'n', 'i', 'v', 'c', 'o'}
for _, m in ipairs(modes) do
  local cmd = ('<Cmd>WhichKey \'\' %s<CR>'):format(m)
  util.map('', ('<Leader>h%s'):format(m), cmd)
  util.map(m, '<C-S-h>', cmd)
end

The <C-S-h> and <Leader>h keybindings were used to test the descriptions. I was hoping that there is a way to show WhichKey automatically when no key is pressed, but I could not find a way.

Updates

I switched to stylua, and in doing so, it seems I was still using this branch, so I removed the other PR.

There are no longer keymap conflict warnings.

Issues

  • Because g? is an operator, when typing g?, all motions are shown next. This also includes the ? motion. However, g?? is a keybinding that encodes the whole line. In the current configuration, there is a g?? prefix and g?? command. This causes ? to be shown 2 times when pressing g?, but check health does not show any issues.
  • Similar to the above issues, there were duplicate prefixes shown in the visual mode when entering visual mode was set as an operator. This was due to operator-pending keybindings having conflicting keybindings (such as %, a, i, g). To resolve this, I added a check inside keys.lua to not add the operator-pending keybindings to visual mode if extra is true.

@folke
Copy link
Owner

folke commented Jul 5, 2021

Hi! Thank you for doing this. Some remarks:

  • the lists would be probably too long for most users. Right now, the preset is based off a couple of quickcheat lists for vim to get the most used keybindings.
  • would be best if all the extra bindings would be under an options opts.extra and keep the misc bindings as is
  • the default value for opts.extra for the preset plugin should be false
  • I also did some work on manually cleaning the descriptions that came from the help (like removing ", etc.) and making them shorter
  • the way which-key works right now, is a bit hacky to be honest. It works as is for most of the use cases and there is currently no better way to implement this, but it's definitely fragile in some ways. Adding a lot of new operators could possibly break keybindings in unexpected places :). But again, if it's under opts.extra I'm fine with that.
  • I'll fix the scrolling. I know what's happening there and recently implemented a better solution for compe that I still need to port to which-key

Thanks again for the effort. I'll keep this open for now, but won't merge it as is. I also don't have the time to work on this, and it's also not something I would use myself, but I can imagine new users might be interested in more presets.

@mly32
Copy link
Contributor Author

mly32 commented Jul 5, 2021

Thanks for the fast reply. I think I'll move the changes to opts.extra like you said, clean up the descriptions and the keymap conflicts, and try to get a more comprehensive list of keybindings that were not included in extra. I'll get more time later this week and hopefully complete it then.

@mly32 mly32 closed this Jul 7, 2021
@mly32
Copy link
Contributor Author

mly32 commented Jul 7, 2021

I had an issue merging and somehow ended up creating a new PR for this. Apologies.

@folke
Copy link
Owner

folke commented Jul 7, 2021

no problem :)

I did notice you've been reformatting most source files. This repo uses stylua and has a proper configuration for this. Please don't use anything else, since in its current state, this PR is impossible for me to review.

@mly32 mly32 reopened this Jul 7, 2021
@mly32
Copy link
Contributor Author

mly32 commented Jul 7, 2021

Thanks for the update. I've switched to `style, which drastically reduced the number of changed lines. I also updated the summary with more information about what I did. It seems like I was able to get this PR working again, so I ended up deleting the other PR.

😐 sorry for the confusion.

@mly32
Copy link
Contributor Author

mly32 commented Aug 7, 2021

@folke I haven't made any updates since you were away. Would you look over what I have so I can make any required changes? Thanks.

@tmillr
Copy link
Contributor

tmillr commented Oct 5, 2022

Nice this looks awesome! As a new which-key user, I was wondering myself why the builtin "keymap" listings weren't complete/exhaustive and I'd really love to see this implemented. I also don't like how v stalls and opens up the popup because it just gets in the way (especially if you're on a laptop with a smaller screen) and feels unintuitive. Plus, v isn't an operator (or is it?), and without which-key v doesn't wait for a motion.

@textzenith
Copy link

textzenith commented Apr 26, 2023

Thanks,

I couldn't figure out why the keymap listings are so incomplete, either.

For someone using Vim for the very first time, the limited number of suggestions is welcome. For longtime users, this is a frustration.

Rather than enabing "extra" mode, this should be about disabling "noob" mode!

As for the Greek characters, this is a surefire way to make Neovim completely, bewilideringly confusing to first-time users. However, there's the grain of a very good idea here in educating users which commands are motions, register- or mark- based, etc. etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants