mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-12 04:58:57 +00:00
Move some fake readline commands to a separate type
This commit is contained in:
parent
48ae19b4b1
commit
ca9c5f4cec
3 changed files with 59 additions and 70 deletions
26
src/input.rs
26
src/input.rs
|
@ -4,7 +4,8 @@ use crate::env::{Environment, CURSES_INITIALIZED};
|
|||
use crate::event;
|
||||
use crate::flog::FLOG;
|
||||
use crate::input_common::{
|
||||
CharEvent, CharInputStyle, InputData, InputEventQueuer, ReadlineCmd, R_END_INPUT_FUNCTIONS,
|
||||
CharEvent, CharInputStyle, ImplicitEvent, InputData, InputEventQueuer, ReadlineCmd,
|
||||
R_END_INPUT_FUNCTIONS,
|
||||
};
|
||||
use crate::key::{self, canonicalize_raw_escapes, ctrl, Key, Modifiers};
|
||||
use crate::proc::job_reap;
|
||||
|
@ -120,10 +121,6 @@ const fn make_md(name: &'static wstr, code: ReadlineCmd) -> InputFunctionMetadat
|
|||
/// Keep this list sorted alphabetically!
|
||||
#[rustfmt::skip]
|
||||
const INPUT_FUNCTION_METADATA: &[InputFunctionMetadata] = &[
|
||||
// NULL makes it unusable - this is specially inserted when we detect mouse input
|
||||
make_md(L!(""), ReadlineCmd::DisableMouseTracking),
|
||||
make_md(L!(""), ReadlineCmd::FocusIn),
|
||||
make_md(L!(""), ReadlineCmd::FocusOut),
|
||||
make_md(L!("accept-autosuggestion"), ReadlineCmd::AcceptAutosuggestion),
|
||||
make_md(L!("and"), ReadlineCmd::FuncAnd),
|
||||
make_md(L!("backward-bigword"), ReadlineCmd::BackwardBigword),
|
||||
|
@ -621,9 +618,10 @@ impl<'q, Queuer: InputEventQueuer + ?Sized> EventQueuePeeker<'q, Queuer> {
|
|||
|
||||
/// Test if any of our peeked events are readline or check_exit.
|
||||
fn char_sequence_interrupted(&self) -> bool {
|
||||
self.peeked
|
||||
.iter()
|
||||
.any(|evt| evt.is_readline_or_command() || evt.is_check_exit())
|
||||
self.peeked.iter().any(|evt| {
|
||||
evt.is_readline_or_command()
|
||||
|| matches!(evt, CharEvent::Implicit(ImplicitEvent::CheckExit))
|
||||
})
|
||||
}
|
||||
|
||||
/// Reset our index back to 0.
|
||||
|
@ -774,15 +772,6 @@ impl<'a> Reader<'a> {
|
|||
CharEvent::Command(_) => {
|
||||
return evt;
|
||||
}
|
||||
CharEvent::Eof => {
|
||||
// If we have EOF, we need to immediately quit.
|
||||
// There's no need to go through the input functions.
|
||||
return evt;
|
||||
}
|
||||
CharEvent::CheckExit => {
|
||||
// Allow the reader to check for exit conditions.
|
||||
return evt;
|
||||
}
|
||||
CharEvent::Key(ref kevt) => {
|
||||
FLOG!(
|
||||
reader,
|
||||
|
@ -797,6 +786,9 @@ impl<'a> Reader<'a> {
|
|||
self.push_front(evt);
|
||||
self.mapping_execute_matching_or_generic();
|
||||
}
|
||||
CharEvent::Implicit(_) => {
|
||||
return evt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,10 +130,6 @@ pub enum ReadlineCmd {
|
|||
BeginUndoGroup,
|
||||
EndUndoGroup,
|
||||
RepeatJump,
|
||||
DisableMouseTracking,
|
||||
FocusIn,
|
||||
FocusOut,
|
||||
// ncurses uses the obvious name
|
||||
ClearScreenAndRepaint,
|
||||
// NOTE: This one has to be last.
|
||||
ReverseRepeatJump,
|
||||
|
@ -180,6 +176,21 @@ pub struct KeyEvent {
|
|||
pub seq: WString,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ImplicitEvent {
|
||||
/// end-of-file was reached.
|
||||
Eof,
|
||||
/// An event was handled internally, or an interrupt was received. Check to see if the reader
|
||||
/// loop should exit.
|
||||
CheckExit,
|
||||
/// Our terminal window gained focus.
|
||||
FocusIn,
|
||||
/// Our terminal window lost focus.
|
||||
FocusOut,
|
||||
/// Request to disable mouse tracking.
|
||||
DisableMouseTracking,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CharEvent {
|
||||
/// A character was entered.
|
||||
|
@ -191,12 +202,8 @@ pub enum CharEvent {
|
|||
/// A shell command.
|
||||
Command(WString),
|
||||
|
||||
/// end-of-file was reached.
|
||||
Eof,
|
||||
|
||||
/// An event was handled internally, or an interrupt was received. Check to see if the reader
|
||||
/// loop should exit.
|
||||
CheckExit,
|
||||
/// Any event that has no user-visible representation.
|
||||
Implicit(ImplicitEvent),
|
||||
}
|
||||
|
||||
impl CharEvent {
|
||||
|
@ -204,14 +211,6 @@ impl CharEvent {
|
|||
matches!(self, CharEvent::Key(_))
|
||||
}
|
||||
|
||||
pub fn is_eof(&self) -> bool {
|
||||
matches!(self, CharEvent::Eof)
|
||||
}
|
||||
|
||||
pub fn is_check_exit(&self) -> bool {
|
||||
matches!(self, CharEvent::CheckExit)
|
||||
}
|
||||
|
||||
pub fn is_readline(&self) -> bool {
|
||||
matches!(self, CharEvent::Readline(_))
|
||||
}
|
||||
|
@ -273,7 +272,7 @@ impl CharEvent {
|
|||
}
|
||||
|
||||
pub fn from_check_exit() -> CharEvent {
|
||||
CharEvent::CheckExit
|
||||
CharEvent::Implicit(ImplicitEvent::CheckExit)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -631,7 +630,7 @@ pub trait InputEventQueuer {
|
|||
let rr = readb(self.get_in_fd(), blocking);
|
||||
match rr {
|
||||
ReadbResult::Eof => {
|
||||
return Some(CharEvent::Eof);
|
||||
return Some(CharEvent::Implicit(ImplicitEvent::Eof));
|
||||
}
|
||||
|
||||
ReadbResult::Interrupted => {
|
||||
|
@ -1028,11 +1027,11 @@ pub trait InputEventQueuer {
|
|||
}
|
||||
b'Z' => shift(key::Tab),
|
||||
b'I' => {
|
||||
self.push_front(CharEvent::from_readline(ReadlineCmd::FocusIn));
|
||||
self.push_front(CharEvent::Implicit(ImplicitEvent::FocusIn));
|
||||
return Some(Key::from_raw(key::Invalid));
|
||||
}
|
||||
b'O' => {
|
||||
self.push_front(CharEvent::from_readline(ReadlineCmd::FocusOut));
|
||||
self.push_front(CharEvent::Implicit(ImplicitEvent::FocusOut));
|
||||
return Some(Key::from_raw(key::Invalid));
|
||||
}
|
||||
_ => return None,
|
||||
|
@ -1051,7 +1050,7 @@ pub trait InputEventQueuer {
|
|||
|
||||
// We shouldn't directly manipulate stdout from here, so we ask the reader to do it.
|
||||
// writembs(outputter_t::stdoutput(), "\x1B[?1000l");
|
||||
self.push_front(CharEvent::from_readline(ReadlineCmd::DisableMouseTracking));
|
||||
self.push_front(CharEvent::Implicit(ImplicitEvent::DisableMouseTracking));
|
||||
}
|
||||
|
||||
fn parse_ss3(&mut self, buffer: &mut Vec<u8>) -> Option<Key> {
|
||||
|
@ -1227,7 +1226,9 @@ pub trait InputEventQueuer {
|
|||
// Find the first sequence of non-char events.
|
||||
// EOF is considered a char: we don't want to pull EOF in front of real chars.
|
||||
let queue = &mut self.get_input_data_mut().queue;
|
||||
let is_char = |evt: &CharEvent| evt.is_char() || evt.is_eof();
|
||||
let is_char = |evt: &CharEvent| {
|
||||
evt.is_char() || matches!(evt, CharEvent::Implicit(ImplicitEvent::Eof))
|
||||
};
|
||||
// Find the index of the first non-char event.
|
||||
// If there's none, we're done.
|
||||
let Some(first): Option<usize> = queue.iter().position(|e| !is_char(e)) else {
|
||||
|
|
|
@ -77,6 +77,7 @@ use crate::history::{
|
|||
};
|
||||
use crate::input::init_input;
|
||||
use crate::input_common::terminal_protocols_disable_ifn;
|
||||
use crate::input_common::ImplicitEvent;
|
||||
use crate::input_common::IN_MIDNIGHT_COMMANDER_PRE_CSI_U;
|
||||
use crate::input_common::{
|
||||
terminal_protocol_hacks, terminal_protocols_enable_ifn, CharEvent, CharInputStyle, InputData,
|
||||
|
@ -2161,22 +2162,16 @@ impl<'a> Reader<'a> {
|
|||
let Some(event_needing_handling) = event_needing_handling else {
|
||||
return ControlFlow::Continue(());
|
||||
};
|
||||
if event_needing_handling.is_check_exit() {
|
||||
return ControlFlow::Continue(());
|
||||
} else if event_needing_handling.is_eof() {
|
||||
reader_sighup();
|
||||
return ControlFlow::Continue(());
|
||||
}
|
||||
|
||||
if !matches!(
|
||||
self.rls().last_cmd,
|
||||
Some(ReadlineCmd::Yank | ReadlineCmd::YankPop)
|
||||
) {
|
||||
self.rls_mut().yank_len = 0;
|
||||
}
|
||||
|
||||
match event_needing_handling {
|
||||
CharEvent::Readline(readline_cmd_evt) => {
|
||||
if !matches!(
|
||||
self.rls().last_cmd,
|
||||
Some(ReadlineCmd::Yank | ReadlineCmd::YankPop)
|
||||
) {
|
||||
self.rls_mut().yank_len = 0;
|
||||
}
|
||||
|
||||
let readline_cmd = readline_cmd_evt.cmd;
|
||||
if readline_cmd == ReadlineCmd::Cancel && self.is_navigating_pager_contents() {
|
||||
self.clear_transient_edit();
|
||||
|
@ -2230,9 +2225,23 @@ impl<'a> Reader<'a> {
|
|||
}
|
||||
self.rls_mut().last_cmd = None;
|
||||
}
|
||||
CharEvent::Eof | CharEvent::CheckExit => {
|
||||
panic!("Should have a char, readline or command")
|
||||
}
|
||||
CharEvent::Implicit(implicit_event) => match implicit_event {
|
||||
ImplicitEvent::Eof => {
|
||||
reader_sighup();
|
||||
}
|
||||
ImplicitEvent::CheckExit => (),
|
||||
ImplicitEvent::FocusIn => {
|
||||
event::fire_generic(self.parser, L!("fish_focus_in").to_owned(), vec![]);
|
||||
}
|
||||
ImplicitEvent::FocusOut => {
|
||||
event::fire_generic(self.parser, L!("fish_focus_out").to_owned(), vec![]);
|
||||
}
|
||||
ImplicitEvent::DisableMouseTracking => {
|
||||
Outputter::stdoutput()
|
||||
.borrow_mut()
|
||||
.write_wstr(L!("\x1B[?1000l"));
|
||||
}
|
||||
},
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
@ -3437,17 +3446,6 @@ impl<'a> Reader<'a> {
|
|||
let (_elt, el) = self.active_edit_line_mut();
|
||||
el.end_edit_group();
|
||||
}
|
||||
rl::DisableMouseTracking => {
|
||||
Outputter::stdoutput()
|
||||
.borrow_mut()
|
||||
.write_wstr(L!("\x1B[?1000l"));
|
||||
}
|
||||
rl::FocusIn => {
|
||||
event::fire_generic(self.parser, L!("fish_focus_in").to_owned(), vec![]);
|
||||
}
|
||||
rl::FocusOut => {
|
||||
event::fire_generic(self.parser, L!("fish_focus_out").to_owned(), vec![]);
|
||||
}
|
||||
rl::ClearScreenAndRepaint => {
|
||||
self.parser.libdata_mut().is_repaint = true;
|
||||
let clear = screen_clear();
|
||||
|
@ -5129,8 +5127,6 @@ fn command_ends_history_search(c: ReadlineCmd) -> bool {
|
|||
| rl::EndOfHistory
|
||||
| rl::Repaint
|
||||
| rl::ForceRepaint
|
||||
| rl::FocusIn
|
||||
| rl::FocusOut
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue