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

Select text in the command line with shift-modified movement #8677

Open
andmis opened this issue Jan 30, 2022 · 12 comments
Open

Select text in the command line with shift-modified movement #8677

andmis opened this issue Jan 30, 2022 · 12 comments

Comments

@andmis
Copy link
Contributor

andmis commented Jan 30, 2022

In most text-editing contexts (in most browsers, in most text editors, etc.), if you hold down shift and move the cursor, the text you move over gets selected. If there is a selection and you issue a command that inserts text (typing a normal character or pasting from the system clipboard, for example), the selected text gets replaced. If you issue a delete or backspace, the selected text gets deleted. If you issue a movement command, then the selection is shrunk/expanded if shift is being held down, and the selection is cleared if shift is not held down.

It would be cool if fish supported this. It would make it easier to copy/paste in part of the command line, for example.

@floam floam added this to the fish-future milestone Jan 30, 2022
@mqudsi
Copy link
Contributor

mqudsi commented Jan 31, 2022

It's important to understand the distinction between the shell and the terminal/tty it is executing in. I'm not aware of any standardized escape codes that allow the executed program to actually (at the terminal level) change the text selection. I don't think even the mouse support APIs can be used in the reverse direction (i.e. faking a mouse drag-and-select) as I'm pretty sure they only notify the running program of input events and are not handled as output characters by the terminal (and if they are, that would be highly terminal-dependent). We also don't even support mouse input yet, so there's that.

@MForster
Copy link
Contributor

MForster commented Jun 4, 2022

I don't think that this feature would need to change the terminal's notion of selection. It would be good enough to update fish's concept of selection and show it with a highlighted background. Fish can already do that using begin-selection (bind \ce begin-selection, press Ctrl-E, move cursor). Interaction with the the X selection could happen per xsel, etc.

What's really missing here may be less intrusive than it first seems. It could be down to mostly providing the correct mapping from keys to begin-selection and end-selection. Without native support in the shell this is quite awkward, because a lot of key bindings have to be changed, including the behavior of all simple characters.

@daleeidd has tried to implement this here: https://github.com/daleeidd/natural-selection and achieves quite a bit of the intended behavior, although I didn't quite get this to work to my liking. There is also a subtle issue about what the fish selection commands should do exactly. They currently seem to only work well in vi-mode with a block cursor: daleeidd/natural-selection#1

@andmis
Copy link
Contributor Author

andmis commented Jun 6, 2022

The problem with only updating fish's selection (and not the terminal emulator's) is getting shortcuts like ⌘C (copy, on macOS) to work -- the way most emulators support ⌘C right now is that (often/usually) mouse-drag selection controls the emulator's selected text, and ⌘C is handled by the emulator.

@MForster
Copy link
Contributor

MForster commented Jun 6, 2022

Getting it fully right is certainly a challenge. And different users will have different ideas on how it should work exactly. But note that fish does already support copy/paste by binding the fish_clipboard_copy and fish_clipboard_paste functions.

I think a bigger issue is actually that Ctrl-C for copying collides with SIGINT. (Not sure if that translates to Mac).

@andmis
Copy link
Contributor Author

andmis commented Jun 6, 2022

Fish can support creating a binding for fish_clipboard_copy, but ⌘C still won't work out-of-the-box for users of most macOS terminal emulators unless the shell–emulator integration is set up right. I guess this should be doable, though.

@MForster
Copy link
Contributor

MForster commented Jun 6, 2022

Ah, yes, I understand now, what you mean. Sorry, I have now idea about Mac. But I've certainly also had to reconfigure terminals to not intercept certain keys.

@robenkleene
Copy link

Why not just do what Emacs already does and use their bindings M-w, C-w, etc... leveraging Fish shell's existing kill ring.

E.g., this is implementing shift-select-mode in Fish, which seems like an obvious addition to add?

(I.e., bypassing the terminal emulators separate selection mechanism entirely. This is how Vim, Emacs, and tmux implement selection. Usually you can then pipe that to the system clipboard, e.g., via `pbpaste‘ on macOS. I think the fish functions mentioned previously in the thread are like that.)

@MForster
Copy link
Contributor

@robenkleene, I think you're saying exactly what I said?

@faho
Copy link
Member

faho commented Oct 27, 2022

This issue seems to be a bit confused about what is actually needed here, so let me try to explain:

We already have a selection. This isn't the selection that the terminal does, but it's our internal selection, same as other programs.

We already have a way of copying the selection to the clipboard - fish_clipboard_copy will take it if it exists (via commandline --current-selection). This is bound to \cx, not \cc, because ctrl/command-c is cancel in a terminal. Honestly I don't think that's a big problem, and it has nothing to do with extending the selection in any case.


So, here is what is needed:

We need some way to bind shift-arrow to extend the selection (starting it if necessary), and some way to end the selection if you press anything but shift-arrow.

The current way to start the selection is "begin-selection", and then any cursor movement you do will alter it, and "end-selection" to stop selecting. Unfortunately "begin-selection" will restart the selection if it already is active and "end-selection" will clear the selection immediately. Both of those would need to be solved, which probably requires new bind functions. [0]

Other than that, the mode system seems to almost be what you want - you could make a bind mode that knows shift-arrow selects and switches back to the previous mode if anything else is pressed.

Except: It will just dump you in the previous mode and swallow the key otherwise. I would assume if you shift-arrow select something and press e.g. backspace you would want that backspace to delete. So we would need a way to switch mode without consuming the key (so it gets run again in the new mode). [1]


[0]: I can see two ways: Either you change "begin" and "end"-selection to not do those things and introduce a separate "clear-selection" function (this is a compatibility break), or you add two new functions "begin-or-keep-selection" and "end-and-keep-selection", which wouldn't be a compatibility break. I don't know if a break here is justified.

[1]: Currently you would bind this like bind --mode shift-selection --new-mode default '' end-selection - this would switch for any otherwise unbound key ('' is the catch-all binding). This should be something like bind --mode shift-selection --new-mode-but-also-reuse-the-key default '' end-selection. This might be fairly tricky with fish's input queue.

@MForster
Copy link
Contributor

@Varriount

This comment was marked as duplicate.

@faho

This comment was marked as duplicate.

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

No branches or pull requests

7 participants