mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 07:04:29 +00:00
Prevent out-of-order execution following repaint
Commita583fe723
("commandline -f foo" to skip queue and execute immediately, 2024-04-08) fixed the execution order of some bindings but was partially backed out in5ba21cd29
(Send repaint requests through the input queue again, 2024-04-19) because repainting outside toplevel yields surprising results (wrong $status etc). Transient prompts wants to first repaint and then execute some more readline commands, all within a single binding. This was broken by the second commit because that one defers the repaint until after the binding has finished. Work around this problem by deferring input events again while a readline event was queued. This is closest to the historical behavior. The implementation feels hacky; we might find odd situations. For example, commandline -f repaint end-of-line set token (commandline -t) sets the wrong token. Probably not a very important case. We could throw an error or make it work by letting "commandline -t" drain the input queue. That seems too complicated, better change repaints to not use the input queue (and fake $status etc). Let's try to do that in future. Closes #10492
This commit is contained in:
parent
d6e231af0d
commit
a19ff4989a
2 changed files with 29 additions and 0 deletions
|
@ -500,6 +500,7 @@ pub struct ReaderData {
|
|||
|
||||
/// The source of input events.
|
||||
inputter: Inputter,
|
||||
queued_repaint: bool,
|
||||
/// The history.
|
||||
history: Arc<History>,
|
||||
/// The history search.
|
||||
|
@ -914,6 +915,9 @@ pub fn reader_execute_readline_cmd(ch: CharEvent) {
|
|||
| ReadlineCmd::Repaint
|
||||
| ReadlineCmd::ForceRepaint
|
||||
) {
|
||||
data.queued_repaint = true;
|
||||
}
|
||||
if data.queued_repaint {
|
||||
data.inputter.queue_char(ch);
|
||||
return;
|
||||
}
|
||||
|
@ -1091,6 +1095,7 @@ impl ReaderData {
|
|||
last_flash: Default::default(),
|
||||
screen: Screen::new(),
|
||||
inputter,
|
||||
queued_repaint: false,
|
||||
history,
|
||||
history_search: Default::default(),
|
||||
history_pager_active: Default::default(),
|
||||
|
@ -2220,6 +2225,7 @@ impl ReaderData {
|
|||
}
|
||||
}
|
||||
rl::RepaintMode | rl::ForceRepaint | rl::Repaint => {
|
||||
self.queued_repaint = false;
|
||||
self.parser().libdata_mut().pods.is_repaint = true;
|
||||
if c == rl::RepaintMode {
|
||||
// Repaint the mode-prompt only if possible.
|
||||
|
|
23
tests/checks/tmux-transient.fish
Normal file
23
tests/checks/tmux-transient.fish
Normal file
|
@ -0,0 +1,23 @@
|
|||
#RUN: %fish %s
|
||||
#REQUIRES: command -v tmux
|
||||
|
||||
set -g isolated_tmux_fish_extra_args -C '
|
||||
function fish_prompt
|
||||
if set -q transient
|
||||
printf "> "
|
||||
set --erase transient
|
||||
else
|
||||
printf "> full prompt > "
|
||||
end
|
||||
end
|
||||
bind enter "set transient true; commandline -f repaint execute"
|
||||
'
|
||||
|
||||
isolated-tmux-start
|
||||
|
||||
isolated-tmux send-keys 'echo foo' Enter
|
||||
tmux-sleep
|
||||
isolated-tmux capture-pane -p
|
||||
# CHECK: > echo foo
|
||||
# CHECK: foo
|
||||
# CHECK: > full prompt >
|
Loading…
Reference in a new issue