Enable putting cursor by mouse clicking#12026
Enable putting cursor by mouse clicking#12026SuperKenVery wants to merge 9 commits intofish-shell:masterfrom
Conversation
|
It's now possible to put the cursor by clicking the desired position with your mouse.
FWIW terminals that support OSC 133 click_events feature
(https://fishshell.com/docs/4.1/terminal-compatibility#term-compat-osc-133)
such as kitty already offered that. Thanks. Will queue.
|
Commit eecc223 (Recognize and disable mouse-tracking CSI events, 2021-02-06) made fish disable mouse reporting whenever we receive a mouse event. This was because at the time we didn't have a parser for mouse inputs. We do now, so let's allow users to toggle mouse support with printf '\e[?1000h' printf '\e[?1000l' Currently the only mouse even we support is left click (to move cursor in commandline, select pager items). Part of #4918 See #12026 [ja: tweak patch and commit message]
…uperkenvery/click-put-cursor
|
Great. Nice cleanup on get_protocols().
Out of curiosity, do you really want to have mouse tracking turned on all the time?
It of breaks things like
- click+drag to make a selection in the terminal (can be worked around with shift-click+drag)
- double click to select a word
- triple-click to select a line
and the advantage is mainly that it allows moving the cursor with the mouse.
You might prefer using the alt-e binding to spawn a full-screen editor
|
|
Well, the main reason is I didn't know about My use case is that, I'm doing some deep learning work and I have very long and multi-line commands, like this: CUDA_VISIBLE_DEVICES=0,1 \
accelerate launch --main_process_port 0 1_train_model.py \
--model SPF_LUT_net \
--scale 4 \
--modes s \
--expDir ../models/take-residual-out \
--trainDir ../data/DIV2K \
--valDir ../data/SRBenchmark \
--sample-size 3 \
--workerNum 8 \
--batchSize 16And changing a number in the middle can often be a pain in the ass. As for the word selecting, I can just hold |
|
Well, the main reason is I didn't know about `alt-e`...
My use case is that, I'm doing some deep learning work and I have very long and multi-line commands, like this:
Interesting.
I wonder if we can detect this case and
1. either suggest to use alt-e
2. or enable mouse automatically if the command line is too large
I guess 2 is less likely to work out.
And changing a number in the middle can often be a pain in the ass.
As for the word selecting, I can just hold `shift` and everything would go back (and mouse events won't be reported to program in terminal), at least in wezterm.
Right, I think that works on a lot of terminals (and in all ncurses apps).
Sounds like you're good with having it turned on always. LMK if that changes (or if you won't use it at all now that you know about alt-e), it'd be a valuable data point.
(Maybe we should toggle mouse capture based on capslock. Bad idea probably.)
Most users probably don't know about the trick with holding shift,
and teaching it to everyone is probably not easy. Also, we probably can't break habits.
|
I would probably still use this. I often just need to change some digits, and opening helix for that, then click (on the top part of the screen rather than in place), then go to insert mode, change, and escape and save, is a little bit long.
Well if people uses vim or helix, or anything that captures mouse, and they want to copy text to clipboard, they probably need to know this.
Yeah, and when |
| reader_set_autosuggestion_enabled(vars); | ||
| } | ||
|
|
||
| fn handle_fish_mouse_change(vars: &EnvStack) { |
There was a problem hiding this comment.
the "fish_" seems reundant,
though we could call this function handle_mouse_enabled_change or similar, not sure.
Maybe we should also rename the user-visible variable,
but tmux also calls it just "mouse" so maybe this seems fine.
| } | ||
|
|
||
| fn handle_fish_mouse_change(vars: &EnvStack) { | ||
| let Some(data) = current_data() else { |
There was a problem hiding this comment.
I'd do something like this for docs and completions:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 76d1bc52fa..649fb82e26 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -22,8 +22,7 @@
- Fish now hides the portion of a multiline prompt that is scrolled out of view due to a huge command line. This prevents duplicate lines after repainting with partially visible prompt (:issue:`11911`).
- On macOS, fish sets :envvar:`MANPATH` correctly also when that variable was already present in the environment (:issue:`10684`).
- Added a workaround for MSYS2 to prevent Konsole and WezTerm from opening new tabs in the wrong working directory (:issue:`11981`).
-- fish no longer disables mouse tracking sequences (DECSET/DECRST 1000),
- so you can use those to toggle mouse reporting,
+- It is now possible to enable mouse capture by setting :envvar:`fish_mouse`,
which allows to move the cursor or select completions items with the mouse (:issue:`4918`).
Scripting improvements
diff --git a/doc_src/language.rst b/doc_src/language.rst
index 37c3888894..6f42f29f89 100644
--- a/doc_src/language.rst
+++ b/doc_src/language.rst
@@ -1628,6 +1628,11 @@
empty string, history is not saved to disk (but is still available within the interactive
session).
+.. envvar:: fish_mouse
+
+ Set it to 1 to capture mouse input, which allows move the cursor and select pager items using the mouse.
+ Note that this will prevent the terminal from handling mouse input.
+
.. envvar:: fish_trace
if set and not empty, will cause fish to print commands before they execute, similar to ``set -x``
diff --git a/share/completions/set.fish b/share/completions/set.fish
index f5396f6dfc..82d294c295 100644
--- a/share/completions/set.fish
+++ b/share/completions/set.fish
@@ -56,6 +56,7 @@
umask "current file creation mask" \
fish_ambiguous_width "affects computed width of east asian chars" \
fish_autosuggestion_enabled "set to 0 to turn autosuggestions off" \
+ fish_mouse "set to 1 to capture mouse input" \
fish_cursor_end_mode "set to 'inclusive' to disallow moving the cursor beyond the command line end" \
fish_cursor_selection_mode "set to 'inclusive' if selections should include the cursor" \
fish_emoji_width "cols wide fish assumes emoji render as" \| DecsetMouseTracking | ||
| } else { | ||
| DecrstMouseTracking | ||
| }); |
There was a problem hiding this comment.
it's not as simple as that
because the TtyProtocolsSet is immutable.
So the variable change would be lost after the next command.
To make this work reliably, I think we should
- disable all protocols
- toggle our flag
- re-enable protocols, including our flag
Something like
SetMouseTracking(enabled) => {
FLOG!(reader, "Set mouse tracking enabled:", enabled);
let mut tty = TtyHandoff::new(reader_save_screen_state);
tty.disable_tty_protocols();
// TODO now set a global atomic bool in tty_handoff.rs
// Now let the Drop implementation of TtyHandoff re-enable
// TTY protocols, including mouse capture if applicable.
}Since this involves atomics and async-signal-safe code,
it may get tricky (though it also might not),
if you prefer I can finish this when I get around to
There was a problem hiding this comment.
Oh. I previously tried to disable protocols, re-initialize tty protocols, then re-enable them, after fish_mouse is changed. However it didn't work as expected and I couldn't figure it out, what's more, that introduced a race condition that sometimes triggered an assertion that protocols should be off when running commands. Probably my implementation was problematic, though.
because the
TtyProtocolsSetis immutable
This should explain why it didn't work...
I certainly need to dig deeper to solve this.
Also, out of curiosity, why did you handle the atomics yourself? I believe there are wrappers like OnceLock or LazyLock, which should make life easier.
There was a problem hiding this comment.
Also, out of curiosity, why did you handle the atomics yourself? I believe there are wrappers like OnceLock or LazyLock, which should make life easier.
When you do kill -TERM $fish_pid, fish wants to disable TTY protocols.
This is currently done in a signal handler (on an arbitrary thread).
We can not use things like Mutex in signal handlers. See man signal-safety for which functions are allowed in signal handlers. For Rust APIs, we'd ideally also want a promise that the implementation won't violate signal safety in future.
Hence the mouse disposition should be accessible in a global variable by only calling async-signal-safe functions.
We try to prefix the name of every function that is used in a signal handler with safe_.
| fn get_protocols(self) -> TtyProtocolsSet { | ||
| fn get_protocols(self, vars: &dyn Environment) -> TtyProtocolsSet { | ||
| let mut on_chain = vec![DecsetBracketedPaste]; | ||
| let mut off_chain = vec![DecrstBracketedPaste]; |
There was a problem hiding this comment.
with the other comment, changing the serialized commands should no longer be necessary,
but let's keep the cleanup for the tmux-specific code paths,
ideally in a separate commit
There was a problem hiding this comment.
If you get the chance to work on this, can you clean up the commit history, i.e. squash most commits -- the final result should probably have two commits, one for the tmux-hack cleanup, and another one to add fish_mouse.
There was a problem hiding this comment.
Okay, I will do that when I get time...
Description
The mouse handling code was already there. What I did:
Fixes issue #4918
TODOs: