diff options
Diffstat (limited to 'src/terminal.rs')
| -rw-r--r-- | src/terminal.rs | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/src/terminal.rs b/src/terminal.rs index 1ba2b01..c46a4a2 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -74,10 +74,16 @@ impl Terminal { } pub async fn init_full_screen(&mut self) -> Result<()> { - self.do_start_alternate_screen().await?; - self.do_cursor_position(0, 0).await?; - - let (width, height) = self.do_report_size().await?; + /* Theoretically, xterm clears the alternate screen buffer when switching + * into it. Konsole does not necessarily do so, so we add an explicit + * clear. This is only noticeable when we fail to exit cleanly and return + * to the shell while still in the alternate screen buffer. + */ + self.start_alternate_screen().await?; + self.clear().await?; + self.set_cursor_position(0, 0).await?; + + let (width, height) = self.report_size().await?; *self.width.write().await = width.try_into().unwrap(); *self.height.write().await = height.try_into().unwrap(); @@ -87,20 +93,22 @@ impl Terminal { } pub async fn zap_full_screen(&mut self) -> Result<()> { - let (width, height) = self.do_report_size().await?; + let (width, height) = self.report_size().await?; *self.width.write().await = width.try_into().unwrap(); *self.height.write().await = height.try_into().unwrap(); self.set_scroll_region(0, height).await?; - self.do_end_alternate_screen().await?; + self.end_alternate_screen().await?; self.stdout.flush().await?; Ok(()) } pub async fn read_char(&mut self) -> Result<char> { - encoding::read_utf8_char(&mut self.stdin).await + let decode = encoding::read_utf8_char(&mut self.stdin).await?; + + Ok(decode.c) } pub async fn do_escape(&mut self, escape_type: EscapeType, code: &str, @@ -188,24 +196,24 @@ impl Terminal { } // xterm - pub async fn do_start_alternate_screen(&mut self) -> Result<()> { + pub async fn start_alternate_screen(&mut self) -> Result<()> { self.do_escape(EscapeType::CSIPrivate, "h", &[1049]).await } // xterm - pub async fn do_end_alternate_screen(&mut self) -> Result<()> { + pub async fn end_alternate_screen(&mut self) -> Result<()> { self.do_escape(EscapeType::CSIPrivate, "l", &[1049]).await } // vt220? vt100? - pub async fn do_cursor_position(&mut self, x: usize, y: usize) + pub async fn set_cursor_position(&mut self, x: usize, y: usize) -> Result<()> { self.do_escape(EscapeType::CSI, "H", &[y + 1, x + 1]).await } // dtterm? xterm - pub async fn do_report_size(&mut self) -> Result<(usize, usize)> { + pub async fn report_size(&mut self) -> Result<(usize, usize)> { self.do_escape(EscapeType::CSI, "t", &[18]).await?; self.stdout.flush().await?; let (code, values) = self.read_report(EscapeType::CSI).await?; |