wezterm icon indicating copy to clipboard operation
wezterm copied to clipboard

Alternative copy-mode selection model

Open Lenbok opened this issue 3 years ago • 3 comments

Is your feature request related to a problem? Please describe.

When in copy-mode, the wezterm selection model that the start and end position are inclusive of the cursor, which has some (subjectively) undesirable consequences:

  1. Activate copy mode
  2. Jump to the start of a line
  3. Enable selection
  4. Move down a few lines
  5. Copy the selection

Now note that the paste buffer does not contain whole lines, there's one extra character corresponding to the cursor end position.

This is apparently how vi does it, but many editors use a selection model that is start-inclusive and end-exclusive. Tmux defaults to emacs-style end-exclusive but has the ability to use end-inclusive selection via setw -g mode-keys vi

Describe the solution you'd like

  1. Wezterm should allow end-exclusive selection so that users can ensure consistency with their other typical editing applications.
  2. End-exclusive selection should be the default ;-)

Describe alternatives you've considered I'm currently using tmux inside wezterm, but wanting to switch fully to wezterm with it's built-in muxing.

Lenbok avatar May 05 '22 19:05 Lenbok

I think the path forwards here is something like:

  • Rename the current set of movement actions to be something like ViMoveForwardWord to indicate when they behave like vi
  • Introduce emacs style movement actions with names like EmacsMoveForwardWord where that makes sense
  • Add those emacs actions to the default copy_mode table if possible to do so without conflict, otherwise define copy_mode_vi and copy_mode_emacs key tables and then introduce another config option to specify which should be activated for copy mode.

wez avatar May 05 '22 19:05 wez

It might need some deeper changes, e.g. when you move the cursor ("end") position from somewhere after the start position to somewhere before the start position, the cell at the start position should swap from being part of the selection to not (like it currently does if you do that type of action with the mouse).

Lenbok avatar May 05 '22 20:05 Lenbok

https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#Movement is the sort of thing I'm thinking about here

wez avatar May 06 '22 01:05 wez

Came here to see if there was any issue open for supporting WORD in vim (all characters except whitespace) since my muscle memory from tmux vi mode always uses capital B to select things. I see that zsh line editor movement includes the WORD movements. Would this issue be tracking that too?

jamesnicolas avatar May 25 '23 16:05 jamesnicolas

@jamesnicolas see https://wezfurlong.org/wezterm/config/lua/keyassignment/CopyMode/MoveForwardWord.html

wez avatar May 26 '23 20:05 wez

@jamesnicolas see https://wezfurlong.org/wezterm/config/lua/keyassignment/CopyMode/MoveForwardWord.html

@wez Thank you for reading my comment and finding the config docs to link. I just want to clarify I was talking about the capital W and capital B functionality (vi-forward-blank-word and vi-backward-blank-word in the zsh movement docs). In the vim docs, these are WORD movements (caps is not just for emphasis). WORDs are separated by whitespace, and not symbols like / - + * etc.

Currently, we only have support for word movements (lowercase). So for example, if I had a path /path/to/file, and ^ marks the cursor position, repeated presses of w would look like:

/path/to/file.txt and some other text in my terminal
^
/path/to/file.txt and some other text in my terminal
 ^
/path/to/file.txt and some other text in my terminal
      ^
/path/to/file.txt and some other text in my terminal
        ^
/path/to/file.txt and some other text in my terminal
         ^
/path/to/file.txt and some other text in my terminal
             ^
/path/to/file.txt and some other text in my terminal
              ^
/path/to/file.txt and some other text in my terminal
                  ^

But if we had WORD movements, one press of W would look like

/path/to/file.txt and some other text in my terminal
^
/path/to/file.txt and some other text in my terminal
                  ^

I would love to see support for these extra movements, as WORD movements are a big part of my workflow.

jamesnicolas avatar May 30 '23 13:05 jamesnicolas

@jamesnicolas ah, I see. Sure we can track that here. If you wanted to try your hand at a PR, I'd welcome it!

https://github.com/wez/wezterm/blob/95e44f2199d9779e353bccf387a1eb2dbaf41f44/wezterm-gui/src/overlay/copy.rs#L858 is where the current word movement is handled.

You could add variants to: https://github.com/wez/wezterm/blob/95e44f2199d9779e353bccf387a1eb2dbaf41f44/config/src/keyassignment.rs#L633 for the new movement(s), and then connect them together around: https://github.com/wez/wezterm/blob/95e44f2199d9779e353bccf387a1eb2dbaf41f44/wezterm-gui/src/overlay/copy.rs#L1182

wez avatar May 30 '23 13:05 wez

But if we had WORD movements, one press of W would look like

this is partially supported with the Move forward one word end command (e by default https://wezfurlong.org/wezterm/copymode.html), it skips non-whitespace. Although the command in the opposite direction is missing

eugenesvk avatar May 30 '23 14:05 eugenesvk

But if we had WORD movements, one press of W would look like

this is partially supported with the Move forward one word end command (e by default https://wezfurlong.org/wezterm/copymode.html), it skips non-whitespace. Although the command in the opposite direction is missing

AFAIK all word movements use https://unicode.org/reports/tr29/ to determine what a "word" is. So e would not have the same behaviour as the desired W. Actually I would've wanted to use E in the example but W was more illustrative.

jamesnicolas avatar May 30 '23 14:05 jamesnicolas

Oh, and yeah I can try my hand at a PR. Will try later today!

jamesnicolas avatar May 30 '23 15:05 jamesnicolas

AFAIK

did you test it? it doesn't behave the same as the other word movement keys w and b

eugenesvk avatar May 30 '23 15:05 eugenesvk

@eugenesvk Oh you're right 😅 . I just read the code and saw "let mut words = s.split_word_bounds();" which uses the unicode text segmentation standard. But I didn't see later it loops through the next words until it hits whitespace. So I think e right now behaves as how E is supposed to behave, at least for vim bindings.

jamesnicolas avatar May 30 '23 17:05 jamesnicolas