Repository: kkawakam/rustyline
Pull request #458 (2020-10-20 19:04:46)

Ignore EINTR while polling


Patch:
diff --git a/src/config.rs b/src/config.rs
index 5db7a8a..39802a3 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 18fe287..cf3ef21 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 a020b4d..f2c22f5 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/tty/unix.rs b/src/tty/unix.rs
index bce53dc..8e8ce64 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<i32> {
         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::Relaxed) {
+                    r
+                } else {
+                    Ok(0) // Ignore EINTR while polling
+                }
+            }
+            Err(_) => r,
+        }
     }
 }
 


Test patch:
diff --git a/src/test/vi_cmd.rs b/src/test/vi_cmd.rs
index eac3221..be8437d 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"),
     );