diff --git a/src/config.rs b/src/config.rs index 746145166..5a531d3f3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -35,6 +35,8 @@ pub struct Config { check_cursor_position: bool, /// Bracketed paste on unix platform enable_bracketed_paste: bool, + /// Whether to disable or not the signals in termios + enable_signals: bool, } impl Config { @@ -193,6 +195,18 @@ impl Config { pub fn enable_bracketed_paste(&self) -> bool { self.enable_bracketed_paste } + + /// Enable or disable signals in termios + /// + /// By default, it's disabled. + #[must_use] + pub fn enable_signals(&self) -> bool { + self.enable_signals + } + + pub(crate) fn set_enable_signals(&mut self, enable_signals: bool) { + self.enable_signals = enable_signals; + } } impl Default for Config { @@ -213,6 +227,7 @@ impl Default for Config { indent_size: 2, check_cursor_position: false, enable_bracketed_paste: true, + enable_signals: false, } } } @@ -450,6 +465,15 @@ impl Builder { self } + /// Enable or disable signals in termios + /// + /// By default, it's disabled. + #[must_use] + pub fn enable_signals(mut self, enable_signals: bool) -> Self { + self.p.set_enable_signals(enable_signals); + self + } + /// Builds a `Config` with the settings specified so far. #[must_use] pub fn build(self) -> Config { @@ -567,4 +591,11 @@ pub trait Configurer { fn enable_bracketed_paste(&mut self, enabled: bool) { self.config_mut().enable_bracketed_paste = enabled; } + + /// Enable or disable signals in termios + /// + /// By default, it's disabled. + fn set_enable_signals(&mut self, enable_signals: bool) { + self.config_mut().set_enable_signals(enable_signals); + } } diff --git a/src/lib.rs b/src/lib.rs index 972af0f44..02d42b90d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -618,6 +618,7 @@ impl Editor { config.tab_stop(), config.bell_style(), config.enable_bracketed_paste(), + config.enable_signals(), )?; Ok(Self { term, diff --git a/src/tty/mod.rs b/src/tty/mod.rs index e79d2a96b..2cee68768 100644 --- a/src/tty/mod.rs +++ b/src/tty/mod.rs @@ -228,6 +228,7 @@ pub trait Term { tab_stop: usize, bell_style: BellStyle, enable_bracketed_paste: bool, + enable_signals: bool, ) -> Result where Self: Sized; diff --git a/src/tty/test.rs b/src/tty/test.rs index d26af5e0a..55d830e57 100644 --- a/src/tty/test.rs +++ b/src/tty/test.rs @@ -173,6 +173,7 @@ impl Term for DummyTerminal { _tab_stop: usize, bell_style: BellStyle, _enable_bracketed_paste: bool, + _enable_signals: bool, ) -> Result { Ok(DummyTerminal { keys: Vec::new(), diff --git a/src/tty/unix.rs b/src/tty/unix.rs index 75dace14a..afd0b1cec 100644 --- a/src/tty/unix.rs +++ b/src/tty/unix.rs @@ -1240,6 +1240,7 @@ pub struct PosixTerminal { // external print writer pipe_writer: Option, sigwinch: Option, + enable_signals: bool, } impl PosixTerminal { @@ -1266,6 +1267,7 @@ impl Term for PosixTerminal { tab_stop: usize, bell_style: BellStyle, enable_bracketed_paste: bool, + enable_signals: bool, ) -> Result { let (tty_in, is_in_a_tty, tty_out, is_out_a_tty, close_on_drop) = if behavior == Behavior::PreferTerm { @@ -1314,6 +1316,7 @@ impl Term for PosixTerminal { pipe_reader: None, pipe_writer: None, sigwinch, + enable_signals, }) } @@ -1340,7 +1343,7 @@ impl Term for PosixTerminal { if !self.is_in_a_tty { return Err(ENOTTY.into()); } - let (original_mode, key_map) = termios_::enable_raw_mode(self.tty_in)?; + let (original_mode, key_map) = termios_::enable_raw_mode(self.tty_in, self.enable_signals)?; self.raw_mode.store(true, Ordering::SeqCst); // enable bracketed paste @@ -1493,7 +1496,7 @@ mod termios_ { let fd = unsafe { BorrowedFd::borrow_raw(tty_in) }; Ok(termios::tcsetattr(fd, SetArg::TCSADRAIN, termios)?) } - pub fn enable_raw_mode(tty_in: RawFd) -> Result<(Termios, PosixKeyMap)> { + pub fn enable_raw_mode(tty_in: RawFd, enable_signals: bool) -> Result<(Termios, PosixKeyMap)> { use nix::sys::termios::{ControlFlags, InputFlags, LocalFlags}; let fd = unsafe { BorrowedFd::borrow_raw(tty_in) }; @@ -1515,6 +1518,11 @@ mod termios_ { // disable echoing, canonical mode, extended input processing and signals raw.local_flags &= !(LocalFlags::ECHO | LocalFlags::ICANON | LocalFlags::IEXTEN | LocalFlags::ISIG); + + if enable_signals { + raw.local_flags |= LocalFlags::ISIG; + } + raw.control_chars[SCI::VMIN as usize] = 1; // One character-at-a-time input raw.control_chars[SCI::VTIME as usize] = 0; // with blocking read @@ -1551,7 +1559,7 @@ mod termios_ { pub fn disable_raw_mode(tty_in: RawFd, termios: &Termios) -> Result<()> { Ok(termios::tcsetattr(tty_in, termios::TCSADRAIN, termios)?) } - pub fn enable_raw_mode(tty_in: RawFd) -> Result<(Termios, PosixKeyMap)> { + pub fn enable_raw_mode(tty_in: RawFd, enable_signals: bool) -> Result<(Termios, PosixKeyMap)> { let original_mode = Termios::from_fd(tty_in)?; let mut raw = original_mode; // disable BREAK interrupt, CR to NL conversion on input, @@ -1566,6 +1574,11 @@ mod termios_ { raw.c_cflag |= termios::CS8; // disable echoing, canonical mode, extended input processing and signals raw.c_lflag &= !(termios::ECHO | termios::ICANON | termios::IEXTEN | termios::ISIG); + + if enable_signals { + raw.c_lflag |= termios::ISIG; + } + raw.c_cc[termios::VMIN] = 1; // One character-at-a-time input raw.c_cc[termios::VTIME] = 0; // with blocking read diff --git a/src/tty/windows.rs b/src/tty/windows.rs index f1598cbc3..7ac6ff574 100644 --- a/src/tty/windows.rs +++ b/src/tty/windows.rs @@ -653,6 +653,7 @@ impl Term for Console { _tab_stop: usize, bell_style: BellStyle, _enable_bracketed_paste: bool, + _enable_signals: bool, ) -> Result { let (conin, conout, close_on_drop) = if behavior == Behavior::PreferTerm { if let (Ok(conin), Ok(conout)) = (