From 2101528a4d98a83f9e353d355abf0b4400d86151 Mon Sep 17 00:00:00 2001 From: gwenn Date: Tue, 20 Oct 2020 20:56:19 +0200 Subject: [PATCH 1/3] Ignore EINTR while polling In a attempt to fix #454 --- src/tty/unix.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/tty/unix.rs b/src/tty/unix.rs index bce53dce4e..333d628740 100644 --- a/src/tty/unix.rs +++ b/src/tty/unix.rs @@ -608,7 +608,18 @@ impl PosixRawReader { fn poll(&mut self, timeout_ms: i32) -> ::nix::Result { let mut fds = [poll::PollFd::new(STDIN_FILENO, PollFlags::POLLIN)]; - poll::poll(&mut fds, timeout_ms) + let r = poll::poll(&mut fds, timeout_ms); + match r { + Ok(_) => r, + Err(nix::Error::Sys(nix::errno::Errno::EINTR)) => { + if SIGWINCH.load(atomic::Ordering::SeqCst) { + r + } else { + Ok(0) // Ignore EINTR while polling + } + } + Err(_) => r, + } } } From 49b83fdffef147dea3cddb4c373025c10c1a2199 Mon Sep 17 00:00:00 2001 From: gwenn Date: Tue, 20 Oct 2020 20:59:56 +0200 Subject: [PATCH 2/3] Rustfmt --- src/config.rs | 1 + src/edit.rs | 5 +---- src/line_buffer.rs | 54 +++++++++++++++++++--------------------------- src/test/vi_cmd.rs | 20 ++++++++--------- 4 files changed, 34 insertions(+), 46 deletions(-) diff --git a/src/config.rs b/src/config.rs index 5db7a8a523..39802a3172 100644 --- a/src/config.rs +++ b/src/config.rs @@ -156,6 +156,7 @@ impl Config { pub fn check_cursor_position(&self) -> bool { self.check_cursor_position } + /// Indentation size used by indentation commands /// /// By default, 2. diff --git a/src/edit.rs b/src/edit.rs index 18fe28775f..cf3ef21049 100644 --- a/src/edit.rs +++ b/src/edit.rs @@ -655,10 +655,7 @@ impl<'out, 'prompt, H: Helper> State<'out, 'prompt, H> { } /// Change the indentation of the lines covered by movement - pub fn edit_indent(&mut self, mvt: &Movement, - amount: usize, dedent: bool) - -> Result<()> - { + pub fn edit_indent(&mut self, mvt: &Movement, amount: usize, dedent: bool) -> Result<()> { if self.line.indent(mvt, amount, dedent) { self.refresh_line() } else { diff --git a/src/line_buffer.rs b/src/line_buffer.rs index a020b4dd6e..f2c22f5842 100644 --- a/src/line_buffer.rs +++ b/src/line_buffer.rs @@ -1101,52 +1101,43 @@ impl LineBuffer { } /// Indent range specified by `mvt`. - pub fn indent(&mut self, mvt: &Movement, amount: usize, dedent: bool) - -> bool - { + pub fn indent(&mut self, mvt: &Movement, amount: usize, dedent: bool) -> bool { let pair = match *mvt { // All inline operators are the same: indent current line - | Movement::WholeLine + Movement::WholeLine | Movement::BeginningOfLine | Movement::ViFirstPrint | Movement::EndOfLine | Movement::BackwardChar(..) | Movement::ForwardChar(..) - | Movement::ViCharSearch(..) - => { - Some((self.pos, self.pos)) - } - Movement::EndOfBuffer => { - Some((self.pos, self.buf.len())) - } - Movement::WholeBuffer => { - Some((0, self.buf.len())) - } - Movement::BeginningOfBuffer => { - Some((0, self.pos)) - } - Movement::BackwardWord(n, word_def) => { - self.prev_word_pos(self.pos, word_def, n) - .map(|pos| (pos, self.pos)) - } - Movement::ForwardWord(n, at, word_def) => { - self.next_word_pos(self.pos, at, word_def, n) - .map(|pos| (self.pos, pos)) - } + | Movement::ViCharSearch(..) => Some((self.pos, self.pos)), + Movement::EndOfBuffer => Some((self.pos, self.buf.len())), + Movement::WholeBuffer => Some((0, self.buf.len())), + Movement::BeginningOfBuffer => Some((0, self.pos)), + Movement::BackwardWord(n, word_def) => self + .prev_word_pos(self.pos, word_def, n) + .map(|pos| (pos, self.pos)), + Movement::ForwardWord(n, at, word_def) => self + .next_word_pos(self.pos, at, word_def, n) + .map(|pos| (self.pos, pos)), Movement::LineUp(n) => self.n_lines_up(n), Movement::LineDown(n) => self.n_lines_down(n), }; let (start, end) = pair.unwrap_or((self.pos, self.pos)); - let start = self.buf[..start].rfind('\n') - .map(|pos| pos + 1).unwrap_or(0); - let end = self.buf[end..].rfind('\n') - .map(|pos| end + pos).unwrap_or(self.buf.len()); + let start = self.buf[..start] + .rfind('\n') + .map(|pos| pos + 1) + .unwrap_or(0); + let end = self.buf[end..] + .rfind('\n') + .map(|pos| end + pos) + .unwrap_or(self.buf.len()); let mut index = start; if dedent { for line in self.buf[start..end].to_string().split('\n') { let max = line.len() - line.trim_start().len(); let deleting = min(max, amount); - self.drain(index..index+deleting, Default::default()); + self.drain(index..index + deleting, Default::default()); if self.pos >= index { if self.pos.saturating_sub(index) < deleting { // don't wrap into the previous line @@ -1160,8 +1151,7 @@ impl LineBuffer { } else { for line in self.buf[start..end].to_string().split('\n') { for off in (0..amount).step_by(INDENT.len()) { - self.insert_str(index, - &INDENT[..min(amount - off, INDENT.len())]); + self.insert_str(index, &INDENT[..min(amount - off, INDENT.len())]); } if self.pos >= index { self.pos += amount; diff --git a/src/test/vi_cmd.rs b/src/test/vi_cmd.rs index eac3221794..be8437d2dc 100644 --- a/src/test/vi_cmd.rs +++ b/src/test/vi_cmd.rs @@ -511,37 +511,37 @@ fn indent() { EditMode::Vi, ("Hello, world!", ""), &[E::ESC, E::from('>'), E::from('>'), E::ENTER], - (" Hello, world", "!"), // Esc moves to the left + (" Hello, world", "!"), // Esc moves to the left ); assert_cursor( EditMode::Vi, ("line1\nline2", ""), &[E::ESC, E::from('>'), E::from('>'), E::ENTER], - ("line1\n line", "2"), // Esc moves to the left + ("line1\n line", "2"), // Esc moves to the left ); assert_cursor( EditMode::Vi, ("line1\nline2", ""), &[E::ESC, E::from('>'), E::from('k'), E::ENTER], - (" line1\n line", "2"), // Esc moves to the left + (" line1\n line", "2"), // Esc moves to the left ); assert_cursor( EditMode::Vi, - (" li", "ne1\n line2",), + (" li", "ne1\n line2"), &[E::ESC, E::from('>'), E::from('j'), E::ENTER], - (" l", "ine1\n line2"), // Esc moves to the left + (" l", "ine1\n line2"), // Esc moves to the left ); assert_cursor( EditMode::Vi, - (" ", "line1\n line2",), + (" ", "line1\n line2"), &[E::ESC, E::from('>'), E::from('j'), E::ENTER], - (" ", " line1\n line2"), // Esc moves to the left + (" ", " line1\n line2"), // Esc moves to the left ); assert_cursor( EditMode::Vi, - (" ", "line1\n line2",), + (" ", "line1\n line2"), &[E::ESC, E::from('>'), E::from('j'), E::ENTER], - (" ", " line1\n line2"), // Esc moves to the left + (" ", " line1\n line2"), // Esc moves to the left ); } @@ -563,7 +563,7 @@ fn dedent() { assert_cursor( EditMode::Vi, - (" li", "ne1\n line2", ), + (" li", "ne1\n line2"), &[E::ESC, E::from('<'), E::from('j'), E::ENTER], ("l", "ine1\nline2"), ); From ffd6db9e520260c9d2cce1e494d921b44ff1c283 Mon Sep 17 00:00:00 2001 From: gwenn Date: Tue, 20 Oct 2020 21:13:06 +0200 Subject: [PATCH 3/3] Use same ordering --- src/tty/unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tty/unix.rs b/src/tty/unix.rs index 333d628740..8e8ce64b32 100644 --- a/src/tty/unix.rs +++ b/src/tty/unix.rs @@ -612,7 +612,7 @@ impl PosixRawReader { match r { Ok(_) => r, Err(nix::Error::Sys(nix::errno::Errno::EINTR)) => { - if SIGWINCH.load(atomic::Ordering::SeqCst) { + if SIGWINCH.load(atomic::Ordering::Relaxed) { r } else { Ok(0) // Ignore EINTR while polling