mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-28 20:34:07 +08:00
Also refresh TTY timestamps after external commands from bindings
Commitba67d20b7
(Refresh TTY timestamps after nextd/prevd, 2024-10-13) wasn't quite right because it also needs to fix it for arbitrary commands. While at it, do this only when needed: 1. It seems to be only relevant for multiline prompts. Note that we can wait until after evaluation to check if the prompt is multiline, because repaint events go through the queue, see5ba21cd29
(Send repaint requests through the input queue again, 2024-04-19). 2. When the binding doesn't execute any external command, we probably don't need to fix up whatever the user printed. If they actually wanted to show output and print another prompt, they should currently use "__fish_echo", to properly support multiline prompts. Bindings should produce no other output. What distinguishes external programs is that they can trigger this issue even if they don't produce any output that remains visible in fish, namely by using the terminal's alternate screen. Would be nice if we could get rid of __fish_echo; I'm not yet sure how. Fixes #10800
This commit is contained in:
parent
30cba03bf9
commit
2dbaf10c36
|
@ -1320,6 +1320,7 @@ fn exec_process_in_job(
|
||||||
piped_output_needs_buffering,
|
piped_output_needs_buffering,
|
||||||
),
|
),
|
||||||
ProcessType::external => {
|
ProcessType::external => {
|
||||||
|
parser.libdata_mut().exec_external_count += 1;
|
||||||
exec_external_command(parser, j, p, &process_net_io_chain)?;
|
exec_external_command(parser, j, p, &process_net_io_chain)?;
|
||||||
// It's possible (though unlikely) that this is a background process which recycled a
|
// It's possible (though unlikely) that this is a background process which recycled a
|
||||||
// pid from another, previous background process. Forget any such old process.
|
// pid from another, previous background process. Forget any such old process.
|
||||||
|
|
|
@ -236,6 +236,9 @@ pub struct LibraryData {
|
||||||
/// A counter incremented every time a command executes.
|
/// A counter incremented every time a command executes.
|
||||||
pub exec_count: u64,
|
pub exec_count: u64,
|
||||||
|
|
||||||
|
/// A counter incremented every time an external command executes.
|
||||||
|
pub exec_external_count: u64,
|
||||||
|
|
||||||
/// A counter incremented every time a command produces a $status.
|
/// A counter incremented every time a command produces a $status.
|
||||||
pub status_count: u64,
|
pub status_count: u64,
|
||||||
|
|
||||||
|
|
|
@ -1996,8 +1996,14 @@ impl<'a> Reader<'a> {
|
||||||
|
|
||||||
fn eval_bind_cmd(&mut self, cmd: &wstr) {
|
fn eval_bind_cmd(&mut self, cmd: &wstr) {
|
||||||
let last_statuses = self.parser.vars().get_last_statuses();
|
let last_statuses = self.parser.vars().get_last_statuses();
|
||||||
|
let prev_exec_external_count = self.parser.libdata().exec_external_count;
|
||||||
self.parser.eval(cmd, &IoChain::new());
|
self.parser.eval(cmd, &IoChain::new());
|
||||||
self.parser.set_last_statuses(last_statuses);
|
self.parser.set_last_statuses(last_statuses);
|
||||||
|
if self.parser.libdata().exec_external_count != prev_exec_external_count
|
||||||
|
&& self.data.left_prompt_buff.contains('\n')
|
||||||
|
{
|
||||||
|
self.save_screen_state();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a sequence of commands from an input binding.
|
/// Run a sequence of commands from an input binding.
|
||||||
|
@ -2862,7 +2868,6 @@ impl<'a> Reader<'a> {
|
||||||
self.force_exec_prompt_and_repaint = true;
|
self.force_exec_prompt_and_repaint = true;
|
||||||
self.input_data
|
self.input_data
|
||||||
.queue_char(CharEvent::from_readline(ReadlineCmd::Repaint));
|
.queue_char(CharEvent::from_readline(ReadlineCmd::Repaint));
|
||||||
self.save_screen_state();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2885,7 +2890,6 @@ impl<'a> Reader<'a> {
|
||||||
self.force_exec_prompt_and_repaint = true;
|
self.force_exec_prompt_and_repaint = true;
|
||||||
self.input_data
|
self.input_data
|
||||||
.queue_char(CharEvent::from_readline(ReadlineCmd::Repaint));
|
.queue_char(CharEvent::from_readline(ReadlineCmd::Repaint));
|
||||||
self.save_screen_state();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#RUN: %fish %s
|
#RUN: %fish %s
|
||||||
#REQUIRES: command -v tmux && ! tmux -V | grep -qE '^tmux (next-3.4|3\.[0123][a-z]*($|[.-]))'
|
#REQUIRES: command -v tmux && ! tmux -V | grep -qE '^tmux (next-3.4|3\.[0123][a-z]*($|[.-]))'
|
||||||
|
#REQUIRES: command -v less
|
||||||
|
|
||||||
isolated-tmux-start
|
isolated-tmux-start
|
||||||
|
|
||||||
|
@ -45,3 +46,16 @@ isolated-tmux capture-pane -p | tail -n 5
|
||||||
# CHECK: prompt-line-2>
|
# CHECK: prompt-line-2>
|
||||||
# CHECK:
|
# CHECK:
|
||||||
# CHECK:
|
# CHECK:
|
||||||
|
|
||||||
|
# Test repainint after running an external program that uses the alternate screen.
|
||||||
|
isolated-tmux send-keys 'bind ctrl-r "echo | less +q; commandline \'echo Hello World\'"' Enter C-l \
|
||||||
|
isolated-tmux send-keys C-r
|
||||||
|
tmux-sleep
|
||||||
|
isolated-tmux send-keys Enter
|
||||||
|
tmux-sleep
|
||||||
|
isolated-tmux capture-pane -p
|
||||||
|
# CHECK: prompt-line-1
|
||||||
|
# CHECK: prompt-line-2> echo Hello World
|
||||||
|
# CHECK: Hello World
|
||||||
|
# CHECK: prompt-line-1
|
||||||
|
# CHECK: prompt-line-2>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user