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

Keymap refactor #1179

Closed
NNBnh opened this issue Nov 26, 2021 · 4 comments
Closed

Keymap refactor #1179

NNBnh opened this issue Nov 26, 2021 · 4 comments
Labels
A-keymap Area: Keymap and keybindings C-enhancement Category: Improvements

Comments

@NNBnh
Copy link
Contributor

NNBnh commented Nov 26, 2021

This is a follow up update to this comment.

I have always looking for a modal terminal editor that use caret style cursors,
Helix currently has implement Gap indexing #376 which mean the caret cursor dream is not far from becoming the reality.

So as Cessen said:

I'll switch Helix to gap indexing, but keep all current behavior the same and enforce a minimum-1-width range.

Behavioral changes can be a separate discussion...

Let's discuss about refactor the keymap to take advantages of it (and more). Here is my attempt:

Note

Because of a defined Helix's goal from vision.md:

  • We aren't playing code golf: It's more important for the keymap to be consistent and easy to memorize than it is to save a key stroke or two when editing.

I feel more confident making some brave decision that focus way more on consistency.

Also i found a lot of my idea have been implemented on Pepper editor
so some keys are take inspiration from it's key bindings:

Pepper is heavily inspired by Kakoune's selection based workflow and multiple cursors.
However its cursors behave like caret ranges instead of block selections.
That is, the cursor is not a one-char selection but only a visual cue to indicate the caret location.

The final results will look like this:

Preview

Keyboard layout editor link.

Current keymap

I thinks the movement will stay pretty much the same except for moving to the end of an object:

Because the implement Gap indexing, moving to the end of an object (e.g: a word) will place the cursor to the right of the last character of the object.

Text inserts

For consistency, any actions that insert text to the cursor will have the following behaviors:

  1. In normal mode, insert text will be place to the left of the cursor (not the selection).
  2. In select mode, insert text will replace the selections and not copy/yank it.
  3. If a <n> number is assigned, the text will be insert <n> times.
  4. Inserted text will be selected (work with number assign).

Because insert text will replace the selection:

  • Remove change_selection from c
  • Remove change_selection_noyank from a-c
  • Remove replace_with_yanked from R.
    • Move copy_selection_on_next_line, copy_selection_on_prev_line from C, a-c to c, C.

Because of the same reason, users don't need to different "insert" and "append" anymore:

  • Remove append_mode from a.
    • Unmap prepend_to_line from I.
    • Move append_to_line from A to I.
  • Remove paste_before from P.
    • Rename paste_after to paste.
  • Remove shell_append_output from a-!.

And therefore we should make flipping selections as easy to press as possible:

  • Move flip_selections from a-; to a.
TODO Improve append_to_line and prepend_to_line.

Movement key

Word movement

I found that move_next_word_start is just a legacy key that people get used to from Vi.
Where move_next_word_end is much more superior in this navigation system,
not to mention it's behavior is consistent with move_prev_word_start.
I know this is a controversial decision but Pepper and literally all non Vim-like editors agree with me on this one:

  • Unmap move_next_word_start, move_next_long_word_start from w, W.
  • Move move_next_word_end, move_next_long_word_end from e, E to w, W.

Find and till

As discussed in #274 #510, we will have a much more fast and convenient way to navigate the code.
In contrast find and till keys will just be a slow clumsy unpredict legacy ways to navigate that took space on keyboard.
The only advantage of the find and till keys is they can be use when there is multiple cursor,
but then user can just use the search key which way more powerful and consistent:

  • Unmap find_next_char, find_prev_char from f, F.
  • Unmap find_till_char, till_prev_char from t, T.

But after some consideration from my own experience and listen to @raphCode suggestion:

Please consider keeping f, F since I use these often to jump into the middle of a word with a typo (especially german words can be pretty long). Alternatively, the jump mode could incorporate this workflow by offering multiple jump targets in longer words.

I decided to keep the find keys, but the till keys still need to go in order to make room for the "No Alt-based keys" section.

Movement behavior

As pointed out in keymap brainstorm wiki and #863, Helix currently need a bit more keypress to do some basic action than it's should.
To improve this, i suggest:

In normal mode, all movement keys (w, W, b, B, f, F) and goto mode key should do the following actions in order:

  1. Collapse all selections.
  2. Enter select mode.
  3. Call <n> the assigned number, <n> == 1 if there is no number being assigned, repeat the movement key <n> times (as discussed in Using a count for a motion should select all text traversed #536).
  4. Go back to normal mode.

This will make most basic action in Helix have the keypress count as low as in Kakoune.

E.g

Deletes till the end of the line:

Editor Example Keypress
Vim D 2
Kakoune g l d 3
Helix current v g l d 4
Helix refactor g l d 3

Changes behavior

In normal mode, if a <n> number is assigned, it will have an effect to <n> lines or the next <n> charaters base on each oporation type:

  • Charater type oporations:
    • replace
    • switch_case
    • switch_to_lowercase
    • switch_to_uppercase
  • Whole line type oporations:
    • yank
    • delete_selection
    • delete_selection_noyank
    • format_selections
    • toggle_comments

No Alt-based keys

I have remap nearly every keys on Vim, Kakoune, Emacs
and i alway include a feature: a "normal" mod key in insert mode (which i explain in more detail at #1064).

To achieve this, we mustn't have any Alt-based keys by defaults.

Plus as mentioned in keymap brainstorm wiki:

we prefer not to hold keys (shift, ctrl, alt)

  • Move delete_selection_noyank from a-d to D.

  • Move shell_pipe_to from a-| to \.

  • Move split_selection_on_newline from a-s to c-l.

  • Move switch_to_uppercase from a-` to ^.

  • Move earlier, later from a-u, a-U to t, T.

  • Move rotate_selections_forward, rotate_selections_backward from ), ( to L, H.

    • Move rotate_selection_contents_forward, rotate_selection_contents_backward from a-), a-( to ), (.
  • Move keep_primary_selection from , to e.

  • Move remove_primary_selection from a-, to E.

  • Move repeat_last_motion from a-. to ,.

  • Move remove_selections from a-K to R.

Future keymap

The following keymaps are in TODO.md keys.md:

  • Normal:
    • Add ensure_selections (ensure selections are in forward direction) to A.
    • Add join_selections_linebreak (join selected lines and select spaces inserted in place of line breaks) to c-j.
    • Add merge_selections (merge contiguous selections together) to M.
    • Add duplicate_selections (duplicate each selection / generating overlapping selections) to +.
    • Add merge_overlap_selections (merge overlapping selections) to -.
    • Add paste_all (paste every yanked text) to P.
  • Marks:

    This is currently being discussed in Marks #703 and Support toggling editing of all selections versus only primary selection #943.

  • Macros:
    • Add play_macro to q.
    • Add record_macro to Q.
    • Add stop_record to esc.
  • Jumps:
    • Add jump_save (save selection on jumplist) to c-s.

Because as we stased: "we mustn't have any Alt-based keys by defaults", the following key need some more thought out placement.

TODO Description
a-& Copy indent, copy the indentation of the main selection (or the count one if a count is given) to all other ones.
@ Convert tabs to spaces in each selection, uses the buffer tabstop option or the count parameter for tabstop.
a-@ Convert spaces to tabs in each selection, uses the buffer tabstop option or the count parameter for tabstop.

Paragraph

As explained in #753:

  • Add paragraph_next to }.
  • Add paragraph_prev to {.

Jump mode

As discussed in #274 #510 (#1162):

  • Add jump_mode to '.
@NNBnh NNBnh added the C-enhancement Category: Improvements label Nov 26, 2021
@kirawi kirawi added the A-keymap Area: Keymap and keybindings label Nov 26, 2021
@glyh
Copy link

glyh commented Nov 29, 2021

I think we should keep on mind to put the most frequency keymaps with the easiest to reach key.
For example, I always think the command mode "Shift+;" deserves to be a single keystroke, because it's so frequently used.

@raphCode
Copy link

raphCode commented Nov 30, 2021

I think with the planned plugin system and remapping support we gain with it it should be fairly easy to implement whatever layout. For example, you can make a custom "NNBnh keymap" that is independent of the default helix mapping. See also: #165 (comment) and following comments.

I believe that the default mapping of helix probably will not change by your proposal. On the flip side this means you can use more "agressive" remappings which deviate from the mainstream because you don't have to find a compromise with the existing mapping.

@pickfire
Copy link
Contributor

pickfire commented Dec 8, 2021

I do agree on most of the stuff @NNBnh mentioned (I didn't look closely at every key). To make this contributor friendly it would be better to split this into multiple smaller issues and then use milestones to group them. So even if people disagree, other parts can still continue.

Example scope for an issue, change goto mode to select text for those that make sense (E.g. gh).

@NNBnh
Copy link
Contributor Author

NNBnh commented Dec 9, 2021

To make this contributor friendly it would be better to split this into multiple smaller issues and then use milestones to group them. So even if people disagree, other parts can still continue.

You can make a custom "NNBnh keymap" that is independent of the default helix mapping.

I believe that the default mapping of helix probably will not change by your proposal. On the flip side this means you can use more "agressive" remappings which deviate from the mainstream because you don't have to find a compromise with the existing mapping.

I have this two on my todo list for a while, but currently doesn't have much time to sort it out. I think it's time to take this into action:

NOTE All strikethrough sections are things that can be achievable by remapping if #1245 and #1200 are implemented

You can make a custom "NNBnh keymap" that is independent of the default helix mapping.

I will definitely focus on this next year on this repo. Here are some old/outdate idea and implement of this saga:

Thank you guy for the support and feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-keymap Area: Keymap and keybindings C-enhancement Category: Improvements
Projects
None yet
Development

No branches or pull requests

5 participants