From 5d360ae3657473ba45c84fec0fbcdce82a80eec8 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Fri, 8 Jan 2021 00:21:54 -0800 Subject: [PATCH] termwiz: Remove anyhow::Result from public API It's been replaced with an opaque termwiz error type instead. This is a bit of a more conservative approach than that in (refs: #407) and has less of an impact on the surrounding code, which appeals to me from a maintenance perspective. refs: #406 refs: #407 --- Cargo.lock | 1 + mux/src/termwiztermtab.rs | 33 ++-- termwiz/Cargo.toml | 1 + termwiz/examples/buffered_terminal.rs | 2 +- termwiz/examples/hello.rs | 2 +- termwiz/examples/key_tester.rs | 2 +- termwiz/examples/line_editor.rs | 2 +- termwiz/examples/terminal_direct.rs | 2 +- termwiz/examples/widgets_basic.rs | 2 +- termwiz/examples/widgets_nested.rs | 6 +- termwiz/src/caps/mod.rs | 7 +- termwiz/src/error.rs | 180 ++++++++++++++++++ termwiz/src/escape/osc.rs | 78 ++++---- termwiz/src/hyperlink.rs | 14 +- termwiz/src/lib.rs | 3 + termwiz/src/lineedit/mod.rs | 25 ++- termwiz/src/render/mod.rs | 2 +- termwiz/src/render/terminfo.rs | 67 +++---- termwiz/src/render/windows.rs | 20 +- termwiz/src/terminal/buffered.rs | 10 +- termwiz/src/terminal/mod.rs | 26 +-- termwiz/src/terminal/unix.rs | 74 +++---- termwiz/src/terminal/windows.rs | 20 +- termwiz/src/widgets/layout.rs | 18 +- termwiz/src/widgets/mod.rs | 12 +- .../src/gui/overlay/confirm_close_pane.rs | 2 +- wezterm-gui/src/gui/overlay/launcher.rs | 2 +- wezterm-gui/src/gui/overlay/tabnavigator.rs | 2 +- 28 files changed, 392 insertions(+), 223 deletions(-) create mode 100644 termwiz/src/error.rs diff --git a/Cargo.lock b/Cargo.lock index dbe109eab..cb4f8ad6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3683,6 +3683,7 @@ dependencies = [ "signal-hook", "terminfo", "termios 0.3.3", + "thiserror", "unicode-segmentation", "unicode-width", "varbincode", diff --git a/mux/src/termwiztermtab.rs b/mux/src/termwiztermtab.rs index c7cedad91..b61ceddee 100644 --- a/mux/src/termwiztermtab.rs +++ b/mux/src/termwiztermtab.rs @@ -29,6 +29,7 @@ use termwiz::render::terminfo::TerminfoRenderer; use termwiz::surface::Change; use termwiz::surface::Line; use termwiz::terminal::{ScreenSize, TerminalWaker}; +use termwiz::Context; use url::Url; use wezterm_term::color::ColorPalette; use wezterm_term::{KeyCode, KeyModifiers, MouseEvent, StableRowIndex}; @@ -269,13 +270,13 @@ impl std::io::Write for TermWizTerminalRenderTty { } impl termwiz::render::RenderTty for TermWizTerminalRenderTty { - fn get_size_in_cells(&mut self) -> anyhow::Result<(usize, usize)> { + fn get_size_in_cells(&mut self) -> termwiz::Result<(usize, usize)> { Ok((self.screen_size.cols, self.screen_size.rows)) } } impl TermWizTerminal { - fn do_input_poll(&mut self, wait: Option) -> anyhow::Result> { + fn do_input_poll(&mut self, wait: Option) -> termwiz::Result> { if let Some(timeout) = wait { match self.input_rx.recv_timeout(timeout) { Ok(input) => Ok(Some(input)), @@ -283,19 +284,19 @@ impl TermWizTerminal { if err.is_timeout() { Ok(None) } else { - Err(err.into()) + Err(err).context("receive from channel") } } } } else { - let input = self.input_rx.recv()?; + let input = self.input_rx.recv().context("receive from channel")?; Ok(Some(input)) } } } impl termwiz::terminal::Terminal for TermWizTerminal { - fn set_raw_mode(&mut self) -> anyhow::Result<()> { + fn set_raw_mode(&mut self) -> termwiz::Result<()> { use termwiz::escape::csi::{DecPrivateMode, DecPrivateModeCode, Mode, CSI}; macro_rules! decset { @@ -318,37 +319,37 @@ impl termwiz::terminal::Terminal for TermWizTerminal { Ok(()) } - fn set_cooked_mode(&mut self) -> anyhow::Result<()> { + fn set_cooked_mode(&mut self) -> termwiz::Result<()> { Ok(()) } - fn enter_alternate_screen(&mut self) -> anyhow::Result<()> { - bail!("TermWizTerminalPane has no alt screen"); + fn enter_alternate_screen(&mut self) -> termwiz::Result<()> { + termwiz::bail!("TermWizTerminalPane has no alt screen"); } - fn exit_alternate_screen(&mut self) -> anyhow::Result<()> { - bail!("TermWizTerminalPane has no alt screen"); + fn exit_alternate_screen(&mut self) -> termwiz::Result<()> { + termwiz::bail!("TermWizTerminalPane has no alt screen"); } - fn get_screen_size(&mut self) -> anyhow::Result { + fn get_screen_size(&mut self) -> termwiz::Result { Ok(self.render_tx.screen_size) } - fn set_screen_size(&mut self, _size: ScreenSize) -> anyhow::Result<()> { - bail!("TermWizTerminalPane cannot set screen size"); + fn set_screen_size(&mut self, _size: ScreenSize) -> termwiz::Result<()> { + termwiz::bail!("TermWizTerminalPane cannot set screen size"); } - fn render(&mut self, changes: &[Change]) -> anyhow::Result<()> { + fn render(&mut self, changes: &[Change]) -> termwiz::Result<()> { self.renderer.render_to(changes, &mut self.render_tx)?; Ok(()) } - fn flush(&mut self) -> anyhow::Result<()> { + fn flush(&mut self) -> termwiz::Result<()> { self.render_tx.render_tx.flush()?; Ok(()) } - fn poll_input(&mut self, wait: Option) -> anyhow::Result> { + fn poll_input(&mut self, wait: Option) -> termwiz::Result> { self.do_input_poll(wait).map(|i| { if let Some(InputEvent::Resized { cols, rows }) = i.as_ref() { self.render_tx.screen_size.cols = *cols; diff --git a/termwiz/Cargo.toml b/termwiz/Cargo.toml index 731ccf598..42079b92a 100644 --- a/termwiz/Cargo.toml +++ b/termwiz/Cargo.toml @@ -27,6 +27,7 @@ regex = "1" semver = "0.11" serde = {version="1.0", features = ["rc", "derive"], optional=true} terminfo = "0.7" +thiserror = "1.0" unicode-segmentation = "1.7" unicode-width = "0.1" xi-unicode = "0.3" diff --git a/termwiz/examples/buffered_terminal.rs b/termwiz/examples/buffered_terminal.rs index 15772114c..5557315c2 100644 --- a/termwiz/examples/buffered_terminal.rs +++ b/termwiz/examples/buffered_terminal.rs @@ -2,13 +2,13 @@ //! up changes and then flush them. `BufferedTerminal` enables //! optimizing the output sequence to update the screen, which is //! important on links with poor connectivity. -use anyhow::Error; use termwiz::caps::Capabilities; use termwiz::cell::AttributeChange; use termwiz::color::AnsiColor; use termwiz::surface::Change; use termwiz::terminal::buffered::BufferedTerminal; use termwiz::terminal::{new_terminal, Terminal}; +use termwiz::Error; fn main() -> Result<(), Error> { let caps = Capabilities::new_from_env()?; diff --git a/termwiz/examples/hello.rs b/termwiz/examples/hello.rs index fc92cfddd..1731eddee 100644 --- a/termwiz/examples/hello.rs +++ b/termwiz/examples/hello.rs @@ -1,4 +1,3 @@ -use anyhow::Error; use termwiz::caps::Capabilities; use termwiz::cell::AttributeChange; use termwiz::color::AnsiColor; @@ -6,6 +5,7 @@ use termwiz::input::{InputEvent, KeyCode, KeyEvent}; use termwiz::surface::{Change, Position, Surface}; use termwiz::terminal::buffered::BufferedTerminal; use termwiz::terminal::{new_terminal, Terminal}; +use termwiz::Error; fn main() -> Result<(), Error> { let caps = Capabilities::new_from_env()?; diff --git a/termwiz/examples/key_tester.rs b/termwiz/examples/key_tester.rs index 9a4ac68a9..861fad78e 100644 --- a/termwiz/examples/key_tester.rs +++ b/termwiz/examples/key_tester.rs @@ -1,7 +1,7 @@ -use anyhow::Error; use termwiz::caps::Capabilities; use termwiz::input::{InputEvent, KeyCode, KeyEvent, Modifiers}; use termwiz::terminal::{new_terminal, Terminal}; +use termwiz::Error; const CTRL_C: KeyEvent = KeyEvent { key: KeyCode::Char('C'), diff --git a/termwiz/examples/line_editor.rs b/termwiz/examples/line_editor.rs index 90fb5e6f7..045f13d8e 100644 --- a/termwiz/examples/line_editor.rs +++ b/termwiz/examples/line_editor.rs @@ -90,7 +90,7 @@ fn word_at_cursor(line: &str, cursor_position: usize) -> Option<(std::ops::Range } } -fn main() -> anyhow::Result<()> { +fn main() -> termwiz::Result<()> { println!("Type `exit` to quit this example, or start a word with `h` and press Tab."); let mut terminal = line_editor_terminal()?; let mut editor = LineEditor::new(&mut terminal); diff --git a/termwiz/examples/terminal_direct.rs b/termwiz/examples/terminal_direct.rs index 14b0dc41e..fac191ffb 100644 --- a/termwiz/examples/terminal_direct.rs +++ b/termwiz/examples/terminal_direct.rs @@ -5,12 +5,12 @@ //! the `buffered_terminal.rs` example demonstrates a simple //! way to enable optimizations. -use anyhow::Error; use termwiz::caps::Capabilities; use termwiz::cell::AttributeChange; use termwiz::color::AnsiColor; use termwiz::surface::Change; use termwiz::terminal::{new_terminal, Terminal}; +use termwiz::Error; fn main() -> Result<(), Error> { let caps = Capabilities::new_from_env()?; diff --git a/termwiz/examples/widgets_basic.rs b/termwiz/examples/widgets_basic.rs index 3e2c05d1c..1f45470a5 100644 --- a/termwiz/examples/widgets_basic.rs +++ b/termwiz/examples/widgets_basic.rs @@ -1,7 +1,6 @@ //! This example shows how to make a basic widget that accumulates //! text input and renders it to the screen #![allow(unused)] -use anyhow::Error; use termwiz::caps::Capabilities; use termwiz::cell::AttributeChange; use termwiz::color::{AnsiColor, ColorAttribute, RgbColor}; @@ -11,6 +10,7 @@ use termwiz::terminal::buffered::BufferedTerminal; use termwiz::terminal::{new_terminal, Terminal}; #[cfg(feature = "widgets")] use termwiz::widgets::*; +use termwiz::Error; /// This is a widget for our application struct MainScreen<'a> { diff --git a/termwiz/examples/widgets_nested.rs b/termwiz/examples/widgets_nested.rs index 4f9e61705..e1d85d06a 100644 --- a/termwiz/examples/widgets_nested.rs +++ b/termwiz/examples/widgets_nested.rs @@ -1,7 +1,6 @@ //! This example shows how to make an app that uses parent/child widgets #[cfg(feature = "widgets")] mod inner { - use anyhow::Error; use termwiz::caps::Capabilities; use termwiz::cell::AttributeChange; use termwiz::color::{AnsiColor, ColorAttribute, RgbColor}; @@ -11,6 +10,7 @@ mod inner { use termwiz::terminal::{new_terminal, Terminal}; use termwiz::widgets::layout::{ChildOrientation, VerticalAlignment}; use termwiz::widgets::*; + use termwiz::Error; /// This is the main container widget for the app struct MainScreen {} @@ -202,12 +202,12 @@ mod inner { #[cfg(not(feature = "widgets"))] mod inner { - pub fn run() -> anyhow::Result<()> { + pub fn run() -> termwiz::Result<()> { println!("recompile with --features widgets"); Ok(()) } } -fn main() -> anyhow::Result<()> { +fn main() -> termwiz::Result<()> { inner::run() } diff --git a/termwiz/src/caps/mod.rs b/termwiz/src/caps/mod.rs index 9eb6d4e0d..87c316c9c 100644 --- a/termwiz/src/caps/mod.rs +++ b/termwiz/src/caps/mod.rs @@ -54,8 +54,7 @@ //! implements some heuristics (a fancy word for guessing) to compute //! the terminal capabilities, but also offers a `ProbeHints` //! that can be used by the embedding application to override those choices. -use crate::builder; -use anyhow::Error; +use crate::{builder, Result}; use semver::Version; use std::env::var; use terminfo::{self, capability as cap}; @@ -163,7 +162,7 @@ impl Capabilities { /// Capability object holding the outcome. /// This function inspects the environment variables to build /// up configuration hints. - pub fn new_from_env() -> Result { + pub fn new_from_env() -> Result { Self::new_with_hints(ProbeHints::new_from_env()) } @@ -184,7 +183,7 @@ impl Capabilities { } /// Build a `Capabilities` object based on the provided `ProbeHints` object. - pub fn new_with_hints(hints: ProbeHints) -> Result { + pub fn new_with_hints(hints: ProbeHints) -> Result { let color_level = hints.color_level.unwrap_or_else(|| { // If set, COLORTERM overrides any other source of information match hints.colorterm.as_ref().map(String::as_ref) { diff --git a/termwiz/src/error.rs b/termwiz/src/error.rs new file mode 100644 index 000000000..685cffa32 --- /dev/null +++ b/termwiz/src/error.rs @@ -0,0 +1,180 @@ +use std::fmt::Display; +use thiserror::*; + +/// The termwiz Error type encapsulates a range of internal +/// errors in an opaque manner. You can use the `source` +/// method to reach the underlying errors if +/// necessary, but it is not expected that most code will +/// need to do so. Please file an issue if you've got a +/// usecase for this! +#[derive(Error, Debug)] +#[error(transparent)] +pub struct Error(pub(crate) InternalError); + +/// A Result whose error type is a termwiz Error +pub type Result = std::result::Result; + +impl From for Error +where + E: Into, +{ + fn from(err: E) -> Self { + Self(err.into()) + } +} + +/// This enum encapsulates the various errors that can be +/// mapped into the termwiz Error type. +/// The intent is that this is effectively private to termwiz +/// itself, but since Rust doesn't allow enums with private +/// variants, we're dancing around with a newtype of an enum +/// and hiding it from the docs. +#[derive(Error, Debug)] +#[non_exhaustive] +#[doc(hidden)] +pub enum InternalError { + #[error(transparent)] + Fmt(#[from] std::fmt::Error), + + #[error(transparent)] + Io(#[from] std::io::Error), + + #[error(transparent)] + Regex(#[from] regex::Error), + + #[error(transparent)] + FromUtf8(#[from] std::string::FromUtf8Error), + + #[error(transparent)] + Utf8(#[from] std::str::Utf8Error), + + #[error(transparent)] + Base64(#[from] base64::DecodeError), + + #[error(transparent)] + ParseFloat(#[from] std::num::ParseFloatError), + + #[error(transparent)] + ParseInt(#[from] std::num::ParseIntError), + + #[error(transparent)] + FloatIsNan(#[from] ordered_float::FloatIsNan), + + #[error("{0}")] + StringErr(#[from] StringWrap), + + #[error(transparent)] + Anyhow(#[from] anyhow::Error), + + #[error(transparent)] + Terminfo(#[from] terminfo::Error), + + #[error("{}", .context)] + Context { + context: String, + source: Box, + }, +} + +impl From for InternalError { + fn from(s: String) -> Self { + InternalError::StringErr(StringWrap(s)) + } +} + +#[derive(Error, Debug)] +#[doc(hidden)] +#[error("{0}")] +pub struct StringWrap(pub String); + +#[macro_export] +macro_rules! format_err { + ($msg:literal $(,)?) => { + return $crate::error::Error::from($crate::error::StringWrap($msg.to_string())) + }; + ($err:expr $(,)?) => { + return $crate::error::Error::from($crate::error::StringWrap(format!($err))) + }; + ($fmt:expr, $($arg:tt)*) => { + return $crate::error::Error::from($crate::error::StringWrap(format!($fmt, $($arg)*))) + }; +} + +#[macro_export] +macro_rules! bail { + ($msg:literal $(,)?) => { + return Err($crate::error::StringWrap($msg.to_string()).into()) + }; + ($err:expr $(,)?) => { + return Err($crate::error::StringWrap(format!($err)).into()) + }; + ($fmt:expr, $($arg:tt)*) => { + return Err($crate::error::StringWrap(format!($fmt, $($arg)*)).into()) + }; +} + +#[macro_export] +macro_rules! ensure { + ($cond:expr, $msg:literal $(,)?) => { + if !$cond { + return Err($crate::error::StringWrap(format!($msg)).into()); + } + }; + ($cond:expr, $err:expr $(,)?) => { + if !$cond { + return Err($crate::error::StringWrap(format!($err)).into()); + } + }; + ($cond:expr, $fmt:expr, $($arg:tt)*) => { + if !$cond { + return Err($crate::error::StringWrap(format!($fmt, $($arg)*)).into()); + } + }; +} + +/// This trait allows extending the Result type so that it can create a +/// `termwiz::Error` that wraps an underlying other error and provide +/// additional context on that error. +pub trait Context { + /// Wrap the error value with additional context. + fn context(self, context: C) -> Result + where + C: Display + Send + Sync + 'static; + + /// Wrap the error value with additional context that is evaluated lazily + /// only once an error does occur. + fn with_context(self, f: F) -> Result + where + C: Display + Send + Sync + 'static, + F: FnOnce() -> C; +} + +impl Context for std::result::Result +where + E: std::error::Error + Send + Sync + 'static, +{ + fn context(self, context: C) -> Result + where + C: Display + Send + Sync + 'static, + { + self.map_err(|error| { + Error(InternalError::Context { + context: context.to_string(), + source: Box::new(error), + }) + }) + } + + fn with_context(self, context: F) -> Result + where + C: Display + Send + Sync + 'static, + F: FnOnce() -> C, + { + self.map_err(|error| { + Error(InternalError::Context { + context: context().to_string(), + source: Box::new(error), + }) + }) + } +} diff --git a/termwiz/src/escape/osc.rs b/termwiz/src/escape/osc.rs index a0d42770d..19426ac29 100644 --- a/termwiz/src/escape/osc.rs +++ b/termwiz/src/escape/osc.rs @@ -1,13 +1,13 @@ use crate::color::RgbColor; pub use crate::hyperlink::Hyperlink; -use anyhow::{anyhow, bail, ensure}; +use crate::{bail, ensure, Result}; use base64; use bitflags::bitflags; use num_derive::*; use num_traits::FromPrimitive; use ordered_float::NotNan; use std::collections::HashMap; -use std::fmt::{Display, Error as FmtError, Formatter}; +use std::fmt::{Display, Error as FmtError, Formatter, Result as FmtResult}; use std::str; #[derive(Debug, Clone, PartialEq, Eq)] @@ -17,7 +17,7 @@ pub enum ColorOrQuery { } impl Display for ColorOrQuery { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, f: &mut Formatter) -> FmtResult { match self { ColorOrQuery::Query => write!(f, "?"), ColorOrQuery::Color(c) => write!(f, "{}", c.to_x11_16bit_rgb_string()), @@ -89,7 +89,7 @@ pub struct Selection :u16{ } impl Selection { - fn try_parse(buf: &[u8]) -> anyhow::Result { + fn try_parse(buf: &[u8]) -> Result { if buf == b"" { Ok(Selection::SELECT | Selection::CUT0) } else { @@ -118,7 +118,7 @@ impl Selection { } impl Display for Selection { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, f: &mut Formatter) -> FmtResult { macro_rules! item { ($variant:ident, $s:expr) => { if (*self & Selection::$variant) != Selection::NONE { @@ -160,7 +160,7 @@ impl OperatingSystemCommand { }) } - fn parse_selection(osc: &[&[u8]]) -> anyhow::Result { + fn parse_selection(osc: &[&[u8]]) -> Result { if osc.len() == 2 { Selection::try_parse(osc[1]).map(OperatingSystemCommand::ClearSelection) } else if osc.len() == 3 && osc[2] == b"?" { @@ -175,7 +175,7 @@ impl OperatingSystemCommand { } } - fn parse_reset_colors(osc: &[&[u8]]) -> anyhow::Result { + fn parse_reset_colors(osc: &[&[u8]]) -> Result { let mut colors = vec![]; let mut iter = osc.iter(); iter.next(); // skip the command word that we already know is present @@ -191,7 +191,7 @@ impl OperatingSystemCommand { Ok(OperatingSystemCommand::ResetColors(colors)) } - fn parse_change_color_number(osc: &[&[u8]]) -> anyhow::Result { + fn parse_change_color_number(osc: &[&[u8]]) -> Result { let mut pairs = vec![]; let mut iter = osc.iter(); iter.next(); // skip the command word that we already know is present @@ -204,7 +204,7 @@ impl OperatingSystemCommand { } else { ColorOrQuery::Color( RgbColor::from_named_or_rgb_string(spec) - .ok_or_else(|| anyhow!("invalid color spec {:?}", spec))?, + .ok_or_else(|| format!("invalid color spec {:?}", spec))?, ) }; @@ -217,16 +217,16 @@ impl OperatingSystemCommand { Ok(OperatingSystemCommand::ChangeColorNumber(pairs)) } - fn parse_reset_dynamic_color_number(idx: u8) -> anyhow::Result { + fn parse_reset_dynamic_color_number(idx: u8) -> Result { let which_color: DynamicColorNumber = FromPrimitive::from_u8(idx) - .ok_or_else(|| anyhow!("osc code is not a valid DynamicColorNumber!?"))?; + .ok_or_else(|| format!("osc code is not a valid DynamicColorNumber!?"))?; Ok(OperatingSystemCommand::ResetDynamicColor(which_color)) } - fn parse_change_dynamic_color_number(idx: u8, osc: &[&[u8]]) -> anyhow::Result { + fn parse_change_dynamic_color_number(idx: u8, osc: &[&[u8]]) -> Result { let which_color: DynamicColorNumber = FromPrimitive::from_u8(idx) - .ok_or_else(|| anyhow!("osc code is not a valid DynamicColorNumber!?"))?; + .ok_or_else(|| format!("osc code is not a valid DynamicColorNumber!?"))?; let mut colors = vec![]; for spec in osc.iter().skip(1) { if spec == b"?" { @@ -235,7 +235,7 @@ impl OperatingSystemCommand { let spec = str::from_utf8(spec)?; colors.push(ColorOrQuery::Color( RgbColor::from_named_or_rgb_string(spec) - .ok_or_else(|| anyhow!("invalid color spec {:?}", spec))?, + .ok_or_else(|| format!("invalid color spec {:?}", spec))?, )); } } @@ -246,7 +246,7 @@ impl OperatingSystemCommand { )) } - fn internal_parse(osc: &[&[u8]]) -> anyhow::Result { + fn internal_parse(osc: &[&[u8]]) -> Result { ensure!(!osc.is_empty(), "no params"); let p1str = String::from_utf8_lossy(osc[0]); @@ -268,7 +268,7 @@ impl OperatingSystemCommand { } else { OperatingSystemCommandCode::from_code(&p1str) } - .ok_or_else(|| anyhow!("unknown code"))?; + .ok_or_else(|| format!("unknown code"))?; macro_rules! single_string { ($variant:ident) => {{ @@ -442,7 +442,7 @@ impl OperatingSystemCommandCode { } impl Display for OperatingSystemCommand { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, f: &mut Formatter) -> FmtResult { write!(f, "\x1b]")?; macro_rules! single_string { @@ -532,20 +532,20 @@ pub enum FinalTermClick { } impl std::convert::TryFrom<&str> for FinalTermClick { - type Error = anyhow::Error; - fn try_from(s: &str) -> anyhow::Result { + type Error = crate::Error; + fn try_from(s: &str) -> Result { match s { "line" => Ok(Self::Line), "m" => Ok(Self::MultipleLine), "v" => Ok(Self::ConservativeVertical), "w" => Ok(Self::SmartVertical), - _ => Err(anyhow!("invalid FinalTermClick {}", s)), + _ => bail!("invalid FinalTermClick {}", s), } } } impl Display for FinalTermClick { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, f: &mut Formatter) -> FmtResult { match self { Self::Line => write!(f, "line"), Self::MultipleLine => write!(f, "m"), @@ -575,20 +575,20 @@ impl Default for FinalTermPromptKind { } impl std::convert::TryFrom<&str> for FinalTermPromptKind { - type Error = anyhow::Error; - fn try_from(s: &str) -> anyhow::Result { + type Error = crate::Error; + fn try_from(s: &str) -> Result { match s { "i" => Ok(Self::Initial), "r" => Ok(Self::RightSide), "c" => Ok(Self::Continuation), "s" => Ok(Self::Secondary), - _ => Err(anyhow!("invalid FinalTermPromptKind {}", s)), + _ => bail!("invalid FinalTermPromptKind {}", s), } } } impl Display for FinalTermPromptKind { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, f: &mut Formatter) -> FmtResult { match self { Self::Initial => write!(f, "i"), Self::RightSide => write!(f, "r"), @@ -644,7 +644,7 @@ pub enum FinalTermSemanticPrompt { } impl FinalTermSemanticPrompt { - fn parse(osc: &[&[u8]]) -> anyhow::Result { + fn parse(osc: &[&[u8]]) -> Result { ensure!(osc.len() > 1, "not enough args"); let param = String::from_utf8_lossy(osc[1]); @@ -721,7 +721,7 @@ impl FinalTermSemanticPrompt { })); } - anyhow::bail!( + bail!( "invalid FinalTermSemanticPrompt p1:{:?}, params:{:?}", param, params @@ -730,7 +730,7 @@ impl FinalTermSemanticPrompt { } impl Display for FinalTermSemanticPrompt { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, f: &mut Formatter) -> FmtResult { write!(f, "133;")?; match self { Self::FreshLine => write!(f, "L")?, @@ -841,7 +841,7 @@ pub struct ITermFileData { } impl ITermFileData { - fn parse(osc: &[&[u8]]) -> anyhow::Result { + fn parse(osc: &[&[u8]]) -> Result { let mut params = HashMap::new(); // Unfortunately, the encoding for the file download data is @@ -904,7 +904,7 @@ impl ITermFileData { .map(|s| *s != "0") .unwrap_or(true); let inline = params.get("inline").map(|s| *s != "0").unwrap_or(false); - let data = data.ok_or_else(|| anyhow!("didn't set data"))?; + let data = data.ok_or_else(|| format!("didn't set data"))?; Ok(Self { name, size, @@ -918,10 +918,10 @@ impl ITermFileData { } impl Display for ITermFileData { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, f: &mut Formatter) -> FmtResult { write!(f, "File")?; let mut sep = "="; - let emit_sep = |sep, f: &mut Formatter| -> Result<&str, FmtError> { + let emit_sep = |sep, f: &mut Formatter| -> std::result::Result<&str, FmtError> { write!(f, "{}", sep)?; Ok(";") }; @@ -974,7 +974,7 @@ impl Default for ITermDimension { } impl Display for ITermDimension { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, f: &mut Formatter) -> FmtResult { use self::ITermDimension::*; match self { Automatic => write!(f, "auto"), @@ -986,14 +986,14 @@ impl Display for ITermDimension { } impl std::str::FromStr for ITermDimension { - type Err = anyhow::Error; - fn from_str(s: &str) -> anyhow::Result { + type Err = crate::Error; + fn from_str(s: &str) -> Result { ITermDimension::parse(s) } } impl ITermDimension { - fn parse(s: &str) -> anyhow::Result { + fn parse(s: &str) -> Result { if s == "auto" { Ok(ITermDimension::Automatic) } else if s.ends_with("px") { @@ -1031,7 +1031,7 @@ impl ITermProprietary { feature = "cargo-clippy", allow(clippy::cyclomatic_complexity, clippy::cognitive_complexity) )] - fn parse(osc: &[&[u8]]) -> anyhow::Result { + fn parse(osc: &[&[u8]]) -> Result { // iTerm has a number of different styles of OSC parameter // encodings, which makes this section of code a bit gnarly. ensure!(osc.len() > 1, "not enough args"); @@ -1039,7 +1039,7 @@ impl ITermProprietary { let param = String::from_utf8_lossy(osc[1]); let mut iter = param.splitn(2, '='); - let keyword = iter.next().ok_or_else(|| anyhow!("bad params"))?; + let keyword = iter.next().ok_or_else(|| format!("bad params"))?; let p1 = iter.next(); macro_rules! single { @@ -1132,7 +1132,7 @@ impl ITermProprietary { } impl Display for ITermProprietary { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, f: &mut Formatter) -> FmtResult { write!(f, "1337;")?; use self::ITermProprietary::*; match self { diff --git a/termwiz/src/hyperlink.rs b/termwiz/src/hyperlink.rs index f5b4a899a..e57ded0ff 100644 --- a/termwiz/src/hyperlink.rs +++ b/termwiz/src/hyperlink.rs @@ -4,7 +4,7 @@ //! We use that as the foundation of our hyperlink support, and the game //! plan is to then implicitly enable the hyperlink attribute for a cell //! as we recognize linkable input text during print() processing. -use anyhow::{anyhow, ensure, Error}; +use crate::{ensure, format_err, Result}; use regex::{Captures, Regex}; #[cfg(feature = "use_serde")] use serde::{Deserialize, Deserializer, Serialize}; @@ -71,7 +71,7 @@ impl Hyperlink { } } - pub fn parse(osc: &[&[u8]]) -> Result, Error> { + pub fn parse(osc: &[&[u8]]) -> Result> { ensure!(osc.len() == 3, "wrong param count"); if osc[1].is_empty() && osc[2].is_empty() { // Clearing current hyperlink @@ -84,8 +84,8 @@ impl Hyperlink { if !param_str.is_empty() { for pair in param_str.split(':') { let mut iter = pair.splitn(2, '='); - let key = iter.next().ok_or_else(|| anyhow!("bad params"))?; - let value = iter.next().ok_or_else(|| anyhow!("bad params"))?; + let key = iter.next().ok_or_else(|| format_err!("bad params"))?; + let value = iter.next().ok_or_else(|| format_err!("bad params"))?; params.insert(key.to_owned(), value.to_owned()); } } @@ -96,7 +96,7 @@ impl Hyperlink { } impl Display for Hyperlink { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, f: &mut Formatter) -> std::result::Result<(), FmtError> { write!(f, "8;")?; for (idx, (k, v)) in self.params.iter().enumerate() { // TODO: protect against k, v containing : or = @@ -145,7 +145,7 @@ pub struct Rule { } #[cfg(feature = "use_serde")] -fn deserialize_regex<'de, D>(deserializer: D) -> Result +fn deserialize_regex<'de, D>(deserializer: D) -> std::result::Result where D: Deserializer<'de>, { @@ -198,7 +198,7 @@ impl<'t> Match<'t> { impl Rule { /// Construct a new rule. It may fail if the regex is invalid. - pub fn new(regex: &str, format: &str) -> Result { + pub fn new(regex: &str, format: &str) -> Result { Ok(Self { regex: Regex::new(regex)?, format: format.to_owned(), diff --git a/termwiz/src/lib.rs b/termwiz/src/lib.rs index 4932e821b..2d0a7924f 100644 --- a/termwiz/src/lib.rs +++ b/termwiz/src/lib.rs @@ -44,6 +44,7 @@ pub mod caps; pub mod cell; pub mod cellcluster; pub mod color; +pub mod error; pub mod escape; pub mod hyperlink; pub mod image; @@ -58,3 +59,5 @@ pub mod surface; pub mod terminal; #[cfg(feature = "widgets")] pub mod widgets; + +pub use error::{Context, Error, Result}; diff --git a/termwiz/src/lineedit/mod.rs b/termwiz/src/lineedit/mod.rs index 0d121f2a4..88a376db6 100644 --- a/termwiz/src/lineedit/mod.rs +++ b/termwiz/src/lineedit/mod.rs @@ -4,7 +4,7 @@ //! ```no_run //! use termwiz::lineedit::{line_editor_terminal, NopLineEditorHost, LineEditor}; //! -//! fn main() -> anyhow::Result<()> { +//! fn main() -> termwiz::Result<()> { //! let mut terminal = line_editor_terminal()?; //! let mut editor = LineEditor::new(&mut terminal); //! let mut host = NopLineEditorHost::default(); @@ -42,6 +42,7 @@ use crate::input::{InputEvent, KeyCode, KeyEvent, Modifiers}; use crate::surface::change::ChangeSequence; use crate::surface::{Change, Position}; use crate::terminal::{new_terminal, Terminal}; +use crate::{bail, ensure, Result}; use unicode_segmentation::GraphemeCursor; mod actions; @@ -56,7 +57,7 @@ pub use host::*; /// ```no_run /// use termwiz::lineedit::{line_editor_terminal, NopLineEditorHost, LineEditor}; /// -/// fn main() -> anyhow::Result<()> { +/// fn main() -> termwiz::Result<()> { /// let mut terminal = line_editor_terminal()?; /// let mut editor = LineEditor::new(&mut terminal); /// let mut host = NopLineEditorHost::default(); @@ -142,7 +143,7 @@ impl<'term> LineEditor<'term> { /// ```no_run /// use termwiz::caps::{Capabilities, ProbeHints}; /// use termwiz::terminal::new_terminal; - /// use anyhow::Error; + /// use termwiz::Error; /// // Disable mouse input in the line editor /// let hints = ProbeHints::new_from_env() /// .mouse_reporting(Some(false)); @@ -165,7 +166,7 @@ impl<'term> LineEditor<'term> { } } - fn render(&mut self, host: &mut dyn LineEditorHost) -> anyhow::Result<()> { + fn render(&mut self, host: &mut dyn LineEditorHost) -> Result<()> { let screen_size = self.terminal.get_screen_size()?; let mut changes = ChangeSequence::new(screen_size.rows, screen_size.cols); @@ -300,8 +301,8 @@ impl<'term> LineEditor<'term> { /// Control is not returned to the caller until a line has been /// accepted, or until an error is detected. /// Returns Ok(None) if the editor was cancelled eg: via CTRL-C. - pub fn read_line(&mut self, host: &mut dyn LineEditorHost) -> anyhow::Result> { - anyhow::ensure!( + pub fn read_line(&mut self, host: &mut dyn LineEditorHost) -> Result> { + ensure!( self.state == EditorState::Inactive, "recursive call to read_line!" ); @@ -786,11 +787,7 @@ impl<'term> LineEditor<'term> { /// Applies the effect of the specified action to the line editor. /// You don't normally need to call this unless you are defining /// custom key mapping or custom actions in your embedding application. - pub fn apply_action( - &mut self, - host: &mut dyn LineEditorHost, - action: Action, - ) -> anyhow::Result<()> { + pub fn apply_action(&mut self, host: &mut dyn LineEditorHost, action: Action) -> Result<()> { // When searching, reinterpret history next/prev as repeated // search actions in the appropriate direction let action = match (action, &self.state) { @@ -950,7 +947,7 @@ impl<'term> LineEditor<'term> { Ok(()) } - fn read_line_impl(&mut self, host: &mut dyn LineEditorHost) -> anyhow::Result> { + fn read_line_impl(&mut self, host: &mut dyn LineEditorHost) -> Result> { self.line.clear(); self.cursor = 0; self.history_pos = None; @@ -968,7 +965,7 @@ impl<'term> LineEditor<'term> { EditorState::Searching { .. } | EditorState::Editing => {} EditorState::Cancelled => return Ok(None), EditorState::Accepted => return Ok(Some(self.line.clone())), - EditorState::Inactive => anyhow::bail!("editor is inactive during read line!?"), + EditorState::Inactive => bail!("editor is inactive during read line!?"), } } else { self.render(host)?; @@ -980,7 +977,7 @@ impl<'term> LineEditor<'term> { /// Create a `Terminal` with the recommended settings for use with /// a `LineEditor`. -pub fn line_editor_terminal() -> anyhow::Result { +pub fn line_editor_terminal() -> Result { let hints = ProbeHints::new_from_env().mouse_reporting(Some(false)); let caps = Capabilities::new_with_hints(hints)?; new_terminal(caps) diff --git a/termwiz/src/render/mod.rs b/termwiz/src/render/mod.rs index 03eaba089..381fa86c3 100644 --- a/termwiz/src/render/mod.rs +++ b/termwiz/src/render/mod.rs @@ -4,5 +4,5 @@ pub mod windows; pub trait RenderTty: std::io::Write { /// Returns the (cols, rows) for the terminal - fn get_size_in_cells(&mut self) -> anyhow::Result<(usize, usize)>; + fn get_size_in_cells(&mut self) -> crate::Result<(usize, usize)>; } diff --git a/termwiz/src/render/terminfo.rs b/termwiz/src/render/terminfo.rs index 3b49d5f75..4edf27113 100644 --- a/termwiz/src/render/terminfo.rs +++ b/termwiz/src/render/terminfo.rs @@ -8,6 +8,7 @@ use crate::escape::OneBased; use crate::image::TextureCoordinate; use crate::render::RenderTty; use crate::surface::{Change, CursorShape, CursorVisibility, Position}; +use crate::Result; use std::io::Write; use terminfo::{capability as cap, Capability as TermInfoCapability}; @@ -47,7 +48,7 @@ impl TerminfoRenderer { } #[cfg_attr(feature = "cargo-clippy", allow(clippy::cognitive_complexity))] - fn flush_pending_attr(&mut self, out: &mut W) -> anyhow::Result<()> { + fn flush_pending_attr(&mut self, out: &mut W) -> Result<()> { macro_rules! attr_on { ($cap:ident, $sgr:expr) => { if let Some(attr) = self.get_capability::() { @@ -204,7 +205,7 @@ impl TerminfoRenderer { Ok(()) } - fn cursor_up(&mut self, n: u32, out: &mut W) -> anyhow::Result<()> { + fn cursor_up(&mut self, n: u32, out: &mut W) -> Result<()> { if n > 0 { if let Some(attr) = self.get_capability::() { attr.expand().count(n).to(out.by_ref())?; @@ -215,7 +216,7 @@ impl TerminfoRenderer { Ok(()) } - fn cursor_down(&mut self, n: u32, out: &mut W) -> anyhow::Result<()> { + fn cursor_down(&mut self, n: u32, out: &mut W) -> Result<()> { if n > 0 { if let Some(attr) = self.get_capability::() { attr.expand().count(n).to(out.by_ref())?; @@ -226,11 +227,7 @@ impl TerminfoRenderer { Ok(()) } - fn cursor_y_relative( - &mut self, - y: isize, - out: &mut W, - ) -> anyhow::Result<()> { + fn cursor_y_relative(&mut self, y: isize, out: &mut W) -> Result<()> { if y > 0 { self.cursor_down(y as u32, out) } else { @@ -238,7 +235,7 @@ impl TerminfoRenderer { } } - fn cursor_left(&mut self, n: u32, out: &mut W) -> anyhow::Result<()> { + fn cursor_left(&mut self, n: u32, out: &mut W) -> Result<()> { if n > 0 { if let Some(attr) = self.get_capability::() { attr.expand().count(n).to(out.by_ref())?; @@ -249,7 +246,7 @@ impl TerminfoRenderer { Ok(()) } - fn cursor_right(&mut self, n: u32, out: &mut W) -> anyhow::Result<()> { + fn cursor_right(&mut self, n: u32, out: &mut W) -> Result<()> { if n > 0 { if let Some(attr) = self.get_capability::() { attr.expand().count(n).to(out.by_ref())?; @@ -260,11 +257,7 @@ impl TerminfoRenderer { Ok(()) } - fn cursor_x_relative( - &mut self, - x: isize, - out: &mut W, - ) -> anyhow::Result<()> { + fn cursor_x_relative(&mut self, x: isize, out: &mut W) -> Result<()> { if x > 0 { self.cursor_right(x as u32, out) } else { @@ -277,7 +270,7 @@ impl TerminfoRenderer { x: u32, y: u32, out: &mut W, - ) -> anyhow::Result<()> { + ) -> Result<()> { if x == 0 && y == 0 { if let Some(attr) = self.get_capability::() { attr.expand().to(out.by_ref())?; @@ -312,7 +305,7 @@ impl TerminfoRenderer { &mut self, changes: &[Change], out: &mut W, - ) -> anyhow::Result<()> { + ) -> Result<()> { macro_rules! record { ($accesor:ident, $value:expr) => { self.attr_apply(|attr| { @@ -681,6 +674,7 @@ impl TerminfoRenderer { #[cfg(all(test, unix))] mod test { use super::*; + use crate::bail; use crate::caps::ProbeHints; use crate::color::{AnsiColor, ColorAttribute, RgbColor}; use crate::escape::parser::Parser; @@ -689,7 +683,6 @@ mod test { use crate::terminal::unix::{Purge, SetAttributeWhen, UnixTty}; use crate::terminal::ScreenSize; use crate::terminal::{cast, Terminal, TerminalWaker}; - use anyhow::bail; use libc::winsize; use std::io::{Error as IoError, ErrorKind, Read, Result as IoResult, Write}; use std::mem; @@ -736,41 +729,37 @@ mod test { } } impl RenderTty for FakeTty { - fn get_size_in_cells(&mut self) -> anyhow::Result<(usize, usize)> { + fn get_size_in_cells(&mut self) -> Result<(usize, usize)> { Ok((self.size.ws_col as usize, self.size.ws_row as usize)) } } impl UnixTty for FakeTty { - fn get_size(&mut self) -> anyhow::Result { + fn get_size(&mut self) -> Result { Ok(self.size.clone()) } - fn set_size(&mut self, size: winsize) -> anyhow::Result<()> { + fn set_size(&mut self, size: winsize) -> Result<()> { self.size = size.clone(); Ok(()) } - fn get_termios(&mut self) -> anyhow::Result { + fn get_termios(&mut self) -> Result { Ok(self.termios.clone()) } - fn set_termios( - &mut self, - termios: &Termios, - _when: SetAttributeWhen, - ) -> anyhow::Result<()> { + fn set_termios(&mut self, termios: &Termios, _when: SetAttributeWhen) -> Result<()> { self.termios = termios.clone(); Ok(()) } /// Waits until all written data has been transmitted. - fn drain(&mut self) -> anyhow::Result<()> { + fn drain(&mut self) -> Result<()> { Ok(()) } - fn purge(&mut self, _purge: Purge) -> anyhow::Result<()> { + fn purge(&mut self, _purge: Purge) -> Result<()> { Ok(()) } } impl Read for FakeTty { - fn read(&mut self, _buf: &mut [u8]) -> Result { + fn read(&mut self, _buf: &mut [u8]) -> std::result::Result { Err(IoError::new(ErrorKind::Other, "not implemented")) } } @@ -807,27 +796,27 @@ mod test { } impl Terminal for FakeTerm { - fn set_raw_mode(&mut self) -> anyhow::Result<()> { + fn set_raw_mode(&mut self) -> Result<()> { bail!("not implemented"); } - fn set_cooked_mode(&mut self) -> anyhow::Result<()> { + fn set_cooked_mode(&mut self) -> Result<()> { bail!("not implemented"); } - fn enter_alternate_screen(&mut self) -> anyhow::Result<()> { + fn enter_alternate_screen(&mut self) -> Result<()> { bail!("not implemented"); } - fn exit_alternate_screen(&mut self) -> anyhow::Result<()> { + fn exit_alternate_screen(&mut self) -> Result<()> { bail!("not implemented"); } - fn render(&mut self, changes: &[Change]) -> anyhow::Result<()> { + fn render(&mut self, changes: &[Change]) -> Result<()> { self.renderer.render_to(changes, &mut self.write) } - fn get_screen_size(&mut self) -> anyhow::Result { + fn get_screen_size(&mut self) -> Result { let size = self.write.get_size()?; Ok(ScreenSize { rows: cast(size.ws_row)?, @@ -837,7 +826,7 @@ mod test { }) } - fn set_screen_size(&mut self, size: ScreenSize) -> anyhow::Result<()> { + fn set_screen_size(&mut self, size: ScreenSize) -> Result<()> { let size = winsize { ws_row: cast(size.rows)?, ws_col: cast(size.cols)?, @@ -848,11 +837,11 @@ mod test { self.write.set_size(size) } - fn flush(&mut self) -> anyhow::Result<()> { + fn flush(&mut self) -> Result<()> { Ok(()) } - fn poll_input(&mut self, _wait: Option) -> anyhow::Result> { + fn poll_input(&mut self, _wait: Option) -> Result> { bail!("not implemented"); } diff --git a/termwiz/src/render/windows.rs b/termwiz/src/render/windows.rs index e29712df7..d1c0f09b6 100644 --- a/termwiz/src/render/windows.rs +++ b/termwiz/src/render/windows.rs @@ -5,6 +5,7 @@ use crate::cell::{AttributeChange, CellAttributes, Underline}; use crate::color::{AnsiColor, ColorAttribute}; use crate::surface::{Change, Position}; use crate::terminal::windows::ConsoleOutputHandle; +use crate::Result; use num_traits::FromPrimitive; use std::io::Write; use winapi::shared::minwindef::WORD; @@ -152,10 +153,7 @@ impl ScreenBuffer { end } - fn do_cursor_y_scroll( - &mut self, - out: &mut B, - ) -> anyhow::Result<()> { + fn do_cursor_y_scroll(&mut self, out: &mut B) -> Result<()> { if self.cursor_y >= self.rows { self.dirty = true; let lines_to_scroll = self.cursor_y.saturating_sub(self.rows) + 1; @@ -172,7 +170,7 @@ impl ScreenBuffer { x: usize, y: usize, out: &mut B, - ) -> anyhow::Result<()> { + ) -> Result<()> { self.cursor_x = x; self.cursor_y = y; @@ -190,7 +188,7 @@ impl ScreenBuffer { t: &str, attr: WORD, out: &mut B, - ) -> anyhow::Result<()> { + ) -> Result<()> { for c in t.chars() { match c { '\r' => { @@ -222,7 +220,7 @@ impl ScreenBuffer { Ok(()) } - fn flush(&mut self, out: &mut B) -> anyhow::Result<()> { + fn flush(&mut self, out: &mut B) -> Result<()> { self.flush_screen(out)?; let info = out.get_buffer_info()?; out.set_cursor_position( @@ -234,7 +232,7 @@ impl ScreenBuffer { Ok(()) } - fn flush_screen(&mut self, out: &mut B) -> anyhow::Result<()> { + fn flush_screen(&mut self, out: &mut B) -> Result<()> { if self.dirty { out.flush()?; out.set_buffer_contents(&self.buf)?; @@ -244,7 +242,7 @@ impl ScreenBuffer { Ok(()) } - fn reread_buffer(&mut self, out: &mut B) -> anyhow::Result<()> { + fn reread_buffer(&mut self, out: &mut B) -> Result<()> { self.buf = out.get_buffer_contents()?; self.dirty = false; Ok(()) @@ -256,7 +254,7 @@ impl ScreenBuffer { region_size: usize, scroll_count: isize, out: &mut B, - ) -> anyhow::Result<()> { + ) -> Result<()> { if region_size > 0 && scroll_count != 0 { self.flush_screen(out)?; let info = out.get_buffer_info()?; @@ -296,7 +294,7 @@ impl WindowsConsoleRenderer { &mut self, changes: &[Change], out: &mut B, - ) -> anyhow::Result<()> { + ) -> Result<()> { out.flush()?; let info = out.get_buffer_info()?; diff --git a/termwiz/src/terminal/buffered.rs b/termwiz/src/terminal/buffered.rs index 8b393561e..2f2dca952 100644 --- a/termwiz/src/terminal/buffered.rs +++ b/termwiz/src/terminal/buffered.rs @@ -2,7 +2,7 @@ use crate::surface::{SequenceNo, Surface}; use crate::terminal::Terminal; -use anyhow::Error; +use crate::Result; use std::ops::{Deref, DerefMut}; /// `BufferedTerminal` is a convenience wrapper around both @@ -23,7 +23,7 @@ pub struct BufferedTerminal { impl BufferedTerminal { /// Create a new `BufferedTerminal` with a `Surface` of /// a matching size. - pub fn new(mut terminal: T) -> Result { + pub fn new(mut terminal: T) -> Result { let size = terminal.get_screen_size()?; let surface = Surface::new(size.cols, size.rows); Ok(Self { @@ -47,7 +47,7 @@ impl BufferedTerminal { /// Applications typically build in a refresh function (CTRL-L /// is common for unix applications) to request a repaint. /// You can use the `repaint` function for that situation. - pub fn flush(&mut self) -> Result<(), Error> { + pub fn flush(&mut self) -> Result<()> { { let (seq, changes) = self.surface.get_changes(self.seqno); // If we encounter an error during rendering, we want to @@ -64,7 +64,7 @@ impl BufferedTerminal { /// Clears the screen and re-draws the surface contents onto /// the Terminal. - pub fn repaint(&mut self) -> Result<(), Error> { + pub fn repaint(&mut self) -> Result<()> { self.seqno = 0; self.flush() } @@ -93,7 +93,7 @@ impl BufferedTerminal { /// consume the input records. Such a thing is possible, but is /// better suited for a higher level abstraction than this basic /// `BufferedTerminal` interface. - pub fn check_for_resize(&mut self) -> Result { + pub fn check_for_resize(&mut self) -> Result { let size = self.terminal.get_screen_size()?; let (width, height) = self.surface.dimensions(); diff --git a/termwiz/src/terminal/mod.rs b/termwiz/src/terminal/mod.rs index 08cb90a09..0559e0bf3 100644 --- a/termwiz/src/terminal/mod.rs +++ b/termwiz/src/terminal/mod.rs @@ -3,7 +3,7 @@ use crate::caps::Capabilities; use crate::input::InputEvent; use crate::surface::Change; -use anyhow::{anyhow, Error}; +use crate::{format_err, Result}; use num_traits::NumCast; use std::fmt::Display; use std::time::Duration; @@ -55,27 +55,27 @@ pub trait Terminal { /// read as the user presses keys, disables local echo, so keys /// pressed by the user do not implicitly render to the terminal /// output, and disables canonicalization of unix newlines to CRLF. - fn set_raw_mode(&mut self) -> Result<(), Error>; - fn set_cooked_mode(&mut self) -> anyhow::Result<()>; + fn set_raw_mode(&mut self) -> Result<()>; + fn set_cooked_mode(&mut self) -> Result<()>; /// Enter the alternate screen. The alternate screen will be left /// automatically when the `Terminal` is dropped. - fn enter_alternate_screen(&mut self) -> Result<(), Error>; + fn enter_alternate_screen(&mut self) -> Result<()>; /// Exit the alternate screen. - fn exit_alternate_screen(&mut self) -> Result<(), Error>; + fn exit_alternate_screen(&mut self) -> Result<()>; /// Queries the current screen size, returning width, height. - fn get_screen_size(&mut self) -> Result; + fn get_screen_size(&mut self) -> Result; /// Sets the current screen size - fn set_screen_size(&mut self, size: ScreenSize) -> Result<(), Error>; + fn set_screen_size(&mut self, size: ScreenSize) -> Result<()>; /// Render a series of changes to the terminal output - fn render(&mut self, changes: &[Change]) -> Result<(), Error>; + fn render(&mut self, changes: &[Change]) -> Result<()>; /// Flush any buffered output - fn flush(&mut self) -> Result<(), Error>; + fn flush(&mut self) -> Result<()>; /// Check for a parsed input event. /// `wait` indicates the behavior in the case that no input is @@ -89,7 +89,7 @@ pub trait Terminal { /// The possible values returned as `InputEvent`s depend on the /// mode of the terminal. Most values are not returned unless /// the terminal is set to raw mode. - fn poll_input(&mut self, wait: Option) -> Result, Error>; + fn poll_input(&mut self, wait: Option) -> Result>; fn waker(&self) -> TerminalWaker; } @@ -112,10 +112,10 @@ pub type SystemTerminal = WindowsTerminal; /// If you have a more advanced use case you will want to look to the /// constructors for `UnixTerminal` and `WindowsTerminal` and call whichever /// one is most suitable for your needs. -pub fn new_terminal(caps: Capabilities) -> Result { +pub fn new_terminal(caps: Capabilities) -> Result { SystemTerminal::new(caps) } -pub(crate) fn cast(n: T) -> Result { - num_traits::cast(n).ok_or_else(|| anyhow!("{} is out of bounds for this system", n)) +pub(crate) fn cast(n: T) -> Result { + num_traits::cast(n).ok_or_else(|| format_err!("{} is out of bounds for this system", n)) } diff --git a/termwiz/src/terminal/unix.rs b/termwiz/src/terminal/unix.rs index 750f4eae8..39ab5c485 100644 --- a/termwiz/src/terminal/unix.rs +++ b/termwiz/src/terminal/unix.rs @@ -1,5 +1,5 @@ use crate::render::RenderTty; -use anyhow::{anyhow, bail, Context, Error}; +use crate::{bail, Context, Result}; use filedescriptor::{poll, pollfd, FileDescriptor, POLLIN}; use libc::{self, winsize}; use signal_hook::{self, SigId}; @@ -42,13 +42,13 @@ pub enum SetAttributeWhen { } pub trait UnixTty { - fn get_size(&mut self) -> Result; - fn set_size(&mut self, size: winsize) -> Result<(), Error>; - fn get_termios(&mut self) -> Result; - fn set_termios(&mut self, termios: &Termios, when: SetAttributeWhen) -> Result<(), Error>; + fn get_size(&mut self) -> Result; + fn set_size(&mut self, size: winsize) -> Result<()>; + fn get_termios(&mut self) -> Result; + fn set_termios(&mut self, termios: &Termios, when: SetAttributeWhen) -> Result<()>; /// Waits until all written data has been transmitted. - fn drain(&mut self) -> Result<(), Error>; - fn purge(&mut self, purge: Purge) -> Result<(), Error>; + fn drain(&mut self) -> Result<()>; + fn purge(&mut self, purge: Purge) -> Result<()>; } pub struct TtyReadHandle { @@ -60,14 +60,14 @@ impl TtyReadHandle { Self { fd } } - fn set_blocking(&mut self, blocking: Blocking) -> Result<(), Error> { + fn set_blocking(&mut self, blocking: Blocking) -> Result<()> { self.fd.set_non_blocking(blocking == Blocking::DoNotWait)?; Ok(()) } } impl Read for TtyReadHandle { - fn read(&mut self, buf: &mut [u8]) -> Result { + fn read(&mut self, buf: &mut [u8]) -> std::result::Result { let size = unsafe { libc::read(self.fd.as_raw_fd(), buf.as_mut_ptr() as *mut _, buf.len()) }; if size == -1 { @@ -91,7 +91,7 @@ impl TtyWriteHandle { } } - fn flush_local_buffer(&mut self) -> Result<(), IoError> { + fn flush_local_buffer(&mut self) -> std::result::Result<(), IoError> { if !self.write_buffer.is_empty() { self.fd.write_all(&self.write_buffer)?; self.write_buffer.clear(); @@ -101,7 +101,7 @@ impl TtyWriteHandle { } impl Write for TtyWriteHandle { - fn write(&mut self, buf: &[u8]) -> Result { + fn write(&mut self, buf: &[u8]) -> std::result::Result { if self.write_buffer.len() + buf.len() > self.write_buffer.capacity() { self.flush()?; } @@ -112,7 +112,7 @@ impl Write for TtyWriteHandle { } } - fn flush(&mut self) -> Result<(), IoError> { + fn flush(&mut self) -> std::result::Result<(), IoError> { self.flush_local_buffer()?; self.drain() .map_err(|e| IoError::new(ErrorKind::Other, format!("{}", e)))?; @@ -121,14 +121,14 @@ impl Write for TtyWriteHandle { } impl RenderTty for TtyWriteHandle { - fn get_size_in_cells(&mut self) -> anyhow::Result<(usize, usize)> { + fn get_size_in_cells(&mut self) -> Result<(usize, usize)> { let size = self.get_size()?; Ok((size.ws_col as usize, size.ws_row as usize)) } } impl UnixTty for TtyWriteHandle { - fn get_size(&mut self) -> Result { + fn get_size(&mut self) -> Result { let mut size: winsize = unsafe { mem::zeroed() }; if unsafe { libc::ioctl(self.fd.as_raw_fd(), libc::TIOCGWINSZ as _, &mut size) } != 0 { bail!("failed to ioctl(TIOCGWINSZ): {}", IoError::last_os_error()); @@ -136,7 +136,7 @@ impl UnixTty for TtyWriteHandle { Ok(size) } - fn set_size(&mut self, size: winsize) -> Result<(), Error> { + fn set_size(&mut self, size: winsize) -> Result<()> { if unsafe { libc::ioctl( self.fd.as_raw_fd(), @@ -154,11 +154,11 @@ impl UnixTty for TtyWriteHandle { Ok(()) } - fn get_termios(&mut self) -> Result { + fn get_termios(&mut self) -> Result { Termios::from_fd(self.fd.as_raw_fd()).context("get_termios failed") } - fn set_termios(&mut self, termios: &Termios, when: SetAttributeWhen) -> Result<(), Error> { + fn set_termios(&mut self, termios: &Termios, when: SetAttributeWhen) -> Result<()> { let when = match when { SetAttributeWhen::Now => TCSANOW, SetAttributeWhen::AfterDrainOutputQueue => TCSADRAIN, @@ -167,11 +167,11 @@ impl UnixTty for TtyWriteHandle { tcsetattr(self.fd.as_raw_fd(), when, termios).context("set_termios failed") } - fn drain(&mut self) -> Result<(), Error> { + fn drain(&mut self) -> Result<()> { tcdrain(self.fd.as_raw_fd()).context("tcdrain failed") } - fn purge(&mut self, purge: Purge) -> Result<(), Error> { + fn purge(&mut self, purge: Purge) -> Result<()> { let param = match purge { Purge::InputQueue => TCIFLUSH, Purge::OutputQueue => TCOFLUSH, @@ -203,7 +203,7 @@ impl UnixTerminal { /// Note that this will duplicate the underlying file descriptors /// and will no longer participate in the stdin/stdout locking /// provided by the rust standard library. - pub fn new_from_stdio(caps: Capabilities) -> Result { + pub fn new_from_stdio(caps: Capabilities) -> Result { Self::new_with(caps, &stdin(), &stdout()) } @@ -211,7 +211,7 @@ impl UnixTerminal { caps: Capabilities, read: &A, write: &B, - ) -> Result { + ) -> Result { let mut read = TtyReadHandle::new(FileDescriptor::dup(read)?); let mut write = TtyWriteHandle::new(FileDescriptor::dup(write)?); let saved_termios = write.get_termios()?; @@ -248,14 +248,14 @@ impl UnixTerminal { /// (/dev/tty) and build a `UnixTerminal` from there. This will /// yield a terminal even if the stdio streams have been redirected, /// provided that the process has an associated controlling terminal. - pub fn new(caps: Capabilities) -> Result { + pub fn new(caps: Capabilities) -> Result { let file = OpenOptions::new().read(true).write(true).open("/dev/tty")?; Self::new_with(caps, &file, &file) } /// Test whether we caught delivery of SIGWINCH. /// If so, yield an `InputEvent` with the current size of the tty. - fn caught_sigwinch(&mut self) -> Result, Error> { + fn caught_sigwinch(&mut self) -> Result> { let mut buf = [0u8; 64]; match self.sigwinch_pipe.read(&mut buf) { @@ -272,7 +272,7 @@ impl UnixTerminal { { Ok(None) } - Err(e) => Err(anyhow!("failed to read sigwinch pipe {}", e)), + Err(e) => bail!("failed to read sigwinch pipe {}", e), } } } @@ -283,7 +283,7 @@ pub struct UnixTerminalWaker { } impl UnixTerminalWaker { - pub fn wake(&self) -> Result<(), IoError> { + pub fn wake(&self) -> std::result::Result<(), IoError> { let mut pipe = self.pipe.lock().unwrap(); match pipe.write(b"W") { Err(e) => match e.kind() { @@ -296,7 +296,7 @@ impl UnixTerminalWaker { } impl Terminal for UnixTerminal { - fn set_raw_mode(&mut self) -> Result<(), Error> { + fn set_raw_mode(&mut self) -> Result<()> { let mut raw = self.write.get_termios()?; cfmakeraw(&mut raw); self.write @@ -327,12 +327,12 @@ impl Terminal for UnixTerminal { Ok(()) } - fn set_cooked_mode(&mut self) -> anyhow::Result<()> { + fn set_cooked_mode(&mut self) -> Result<()> { self.write .set_termios(&self.saved_termios, SetAttributeWhen::Now) } - fn enter_alternate_screen(&mut self) -> Result<(), Error> { + fn enter_alternate_screen(&mut self) -> Result<()> { if !self.in_alternate_screen { write!( self.write, @@ -346,7 +346,7 @@ impl Terminal for UnixTerminal { Ok(()) } - fn exit_alternate_screen(&mut self) -> Result<(), Error> { + fn exit_alternate_screen(&mut self) -> Result<()> { if self.in_alternate_screen { write!( self.write, @@ -360,7 +360,7 @@ impl Terminal for UnixTerminal { Ok(()) } - fn get_screen_size(&mut self) -> Result { + fn get_screen_size(&mut self) -> Result { let size = self.write.get_size()?; Ok(ScreenSize { rows: cast(size.ws_row)?, @@ -370,7 +370,7 @@ impl Terminal for UnixTerminal { }) } - fn set_screen_size(&mut self, size: ScreenSize) -> Result<(), Error> { + fn set_screen_size(&mut self, size: ScreenSize) -> Result<()> { let size = winsize { ws_row: cast(size.rows)?, ws_col: cast(size.cols)?, @@ -380,14 +380,14 @@ impl Terminal for UnixTerminal { self.write.set_size(size) } - fn render(&mut self, changes: &[Change]) -> Result<(), Error> { + fn render(&mut self, changes: &[Change]) -> Result<()> { self.renderer.render_to(changes, &mut self.write) } - fn flush(&mut self) -> Result<(), Error> { + fn flush(&mut self) -> Result<()> { self.write.flush().context("flush failed") } - fn poll_input(&mut self, wait: Option) -> Result, Error> { + fn poll_input(&mut self, wait: Option) -> Result> { if let Some(event) = self.input_queue.pop_front() { return Ok(Some(event)); } @@ -434,10 +434,10 @@ impl Terminal for UnixTerminal { Ok(None) } } else { - Err(anyhow!("poll(2) error: {}", err)) + bail!("poll(2) error: {}", err) } } - Err(err) => Err(anyhow!("poll(2) error: {}", err)), + Err(err) => bail!("poll(2) error: {}", err), }; }; @@ -462,7 +462,7 @@ impl Terminal for UnixTerminal { } Err(ref e) if e.kind() == ErrorKind::WouldBlock || e.kind() == ErrorKind::Interrupted => {} - Err(e) => return Err(anyhow!("failed to read input {}", e)), + Err(e) => bail!("failed to read input {}", e), } } diff --git a/termwiz/src/terminal/windows.rs b/termwiz/src/terminal/windows.rs index de5c4c2ab..d7b647cdb 100644 --- a/termwiz/src/terminal/windows.rs +++ b/termwiz/src/terminal/windows.rs @@ -1,5 +1,5 @@ use crate::istty::IsTty; -use anyhow::{anyhow, bail, Error}; +use crate::{bail, format_err, Error}; use filedescriptor::{FileDescriptor, OwnedHandle}; use std::cmp::{max, min}; use std::collections::VecDeque; @@ -52,8 +52,8 @@ pub trait ConsoleOutputHandle { fn set_attr(&mut self, attr: u16) -> Result<(), Error>; fn set_cursor_position(&mut self, x: i16, y: i16) -> Result<(), Error>; fn get_buffer_info(&mut self) -> Result; - fn get_buffer_contents(&mut self) -> anyhow::Result>; - fn set_buffer_contents(&mut self, buffer: &[CHAR_INFO]) -> anyhow::Result<()>; + fn get_buffer_contents(&mut self) -> Result>; + fn set_buffer_contents(&mut self, buffer: &[CHAR_INFO]) -> Result<()>; fn set_viewport(&mut self, left: i16, top: i16, right: i16, bottom: i16) -> Result<(), Error>; fn scroll_region( &mut self, @@ -157,7 +157,7 @@ fn dimensions_from_buffer_info(info: CONSOLE_SCREEN_BUFFER_INFO) -> (usize, usiz } impl RenderTty for OutputHandle { - fn get_size_in_cells(&mut self) -> anyhow::Result<(usize, usize)> { + fn get_size_in_cells(&mut self) -> Result<(usize, usize)> { let info = self.get_buffer_info()?; let (cols, rows) = dimensions_from_buffer_info(info); @@ -298,7 +298,7 @@ impl ConsoleOutputHandle for OutputHandle { Ok(()) } - fn get_buffer_contents(&mut self) -> anyhow::Result> { + fn get_buffer_contents(&mut self) -> Result> { let info = self.get_buffer_info()?; let cols = info.dwSize.X as usize; @@ -335,12 +335,12 @@ impl ConsoleOutputHandle for OutputHandle { Ok(res) } - fn set_buffer_contents(&mut self, buffer: &[CHAR_INFO]) -> anyhow::Result<()> { + fn set_buffer_contents(&mut self, buffer: &[CHAR_INFO]) -> Result<()> { let info = self.get_buffer_info()?; let cols = info.dwSize.X as usize; let rows = 1 + info.srWindow.Bottom as usize - info.srWindow.Top as usize; - anyhow::ensure!( + ensure!( rows * cols == buffer.len(), "buffer size doesn't match screen size" ); @@ -548,7 +548,7 @@ impl WindowsTerminal { Ok(terminal) } - fn enable_virtual_terminal_processing_if_needed(&mut self) -> anyhow::Result<()> { + fn enable_virtual_terminal_processing_if_needed(&mut self) -> Result<()> { match &self.renderer { Renderer::Terminfo(_) => self.enable_virtual_terminal_processing(), Renderer::Windows(_) => Ok(()), @@ -605,7 +605,7 @@ impl Terminal for WindowsTerminal { ) } - fn set_cooked_mode(&mut self) -> anyhow::Result<()> { + fn set_cooked_mode(&mut self) -> Result<()> { let mode = self.output_handle.get_output_mode()?; self.output_handle .set_output_mode(mode & !DISABLE_NEWLINE_AUTO_RETURN) @@ -671,7 +671,7 @@ impl Terminal for WindowsTerminal { fn flush(&mut self) -> Result<(), Error> { self.output_handle .flush() - .map_err(|e| anyhow!("flush failed: {}", e)) + .map_err(|e| format_err!("flush failed: {}", e)) } fn poll_input(&mut self, wait: Option) -> Result, Error> { diff --git a/termwiz/src/widgets/layout.rs b/termwiz/src/widgets/layout.rs index f0a6b38b6..d18b09c63 100644 --- a/termwiz/src/widgets/layout.rs +++ b/termwiz/src/widgets/layout.rs @@ -1,7 +1,7 @@ //! This module provides some automatic layout functionality for widgets. //! The parameters are similar to those that you may have encountered //! in HTML, but do not fully recreate the layout model. -use anyhow::{anyhow, Error}; +use crate::{format_err, Error, Result}; use cassowary::strength::{REQUIRED, STRONG, WEAK}; use cassowary::WeightedRelation::*; use cassowary::{AddConstraintError, Expression, Solver, SuggestValueError, Variable}; @@ -185,13 +185,13 @@ pub struct LaidOutWidget { fn suggesterr(e: SuggestValueError) -> Error { match e { - SuggestValueError::UnknownEditVariable => anyhow!("Unknown edit variable"), - SuggestValueError::InternalSolverError(e) => anyhow!("Internal solver error: {}", e), + SuggestValueError::UnknownEditVariable => format_err!("Unknown edit variable"), + SuggestValueError::InternalSolverError(e) => format_err!("Internal solver error: {}", e), } } fn adderr(e: AddConstraintError) -> Error { - anyhow!("{:?}", e) + format_err!("{:?}", e) } impl Default for LayoutState { @@ -246,7 +246,7 @@ impl LayoutState { screen_width: usize, screen_height: usize, root_widget: WidgetId, - ) -> Result, Error> { + ) -> Result> { self.solver .suggest_value(self.screen_width, screen_width as f64) .map_err(suggesterr)?; @@ -279,11 +279,11 @@ impl LayoutState { parent_left: usize, parent_top: usize, results: &mut Vec, - ) -> Result<(), Error> { + ) -> Result<()> { let state = self .widget_states .get(&widget) - .ok_or_else(|| anyhow!("widget has no solver state"))?; + .ok_or_else(|| format_err!("widget has no solver state"))?; let width = self.solver.get_value(state.width) as usize; let height = self.solver.get_value(state.height) as usize; let left = self.solver.get_value(state.left) as usize; @@ -313,11 +313,11 @@ impl LayoutState { parent_height: Variable, parent_left: Option, parent_top: Option, - ) -> Result { + ) -> Result { let state = self .widget_states .get(&widget) - .ok_or_else(|| anyhow!("widget has no solver state"))? + .ok_or_else(|| format_err!("widget has no solver state"))? .clone(); let is_root_widget = parent_left.is_none(); diff --git a/termwiz/src/widgets/mod.rs b/termwiz/src/widgets/mod.rs index 8344e43c4..53c9e89db 100644 --- a/termwiz/src/widgets/mod.rs +++ b/termwiz/src/widgets/mod.rs @@ -4,7 +4,7 @@ use crate::color::ColorAttribute; use crate::input::InputEvent; use crate::surface::{Change, CursorShape, Position, SequenceNo, Surface}; -use anyhow::Error; +use crate::{Error, Result}; use fnv::FnvHasher; use std::collections::{HashMap, VecDeque}; use std::hash::BuildHasherDefault; @@ -309,7 +309,7 @@ impl<'widget> Ui<'widget> { } } - pub fn process_event_queue(&mut self) -> Result<(), Error> { + pub fn process_event_queue(&mut self) -> Result<()> { while let Some(event) = self.input_queue.pop_front() { match event { WidgetEvent::Input(InputEvent::Resized { rows, cols }) => { @@ -354,7 +354,7 @@ impl<'widget> Ui<'widget> { id: WidgetId, screen: &mut Surface, abs_coords: &ScreenRelativeCoords, - ) -> Result<(), Error> { + ) -> Result<()> { let coords = { let render_data = self.render.get_mut(&id).unwrap(); let surface = &mut render_data.surface; @@ -389,7 +389,7 @@ impl<'widget> Ui<'widget> { /// Reconsider the layout constraints and apply them. /// Returns true if the layout was changed, false if no changes were made. - fn compute_layout(&mut self, width: usize, height: usize) -> Result { + fn compute_layout(&mut self, width: usize, height: usize) -> Result { let mut layout = layout::LayoutState::new(); let root = self.graph.root.unwrap(); @@ -421,7 +421,7 @@ impl<'widget> Ui<'widget> { &mut self, layout: &mut layout::LayoutState, widget: WidgetId, - ) -> Result<(), Error> { + ) -> Result<()> { let constraints = self.render[&widget].widget.get_size_constraints(); let children = self.graph.children(widget).to_vec(); @@ -437,7 +437,7 @@ impl<'widget> Ui<'widget> { /// This has the side effect of clearing out any unconsumed input queue. /// Returns true if the Ui may need to be updated again; for example, /// if the most recent update operation changed layout. - pub fn render_to_screen(&mut self, screen: &mut Surface) -> Result { + pub fn render_to_screen(&mut self, screen: &mut Surface) -> Result { if let Some(root) = self.graph.root { let (width, height) = screen.dimensions(); // Render from scratch into a fresh screen buffer diff --git a/wezterm-gui/src/gui/overlay/confirm_close_pane.rs b/wezterm-gui/src/gui/overlay/confirm_close_pane.rs index bfc09c1a9..cd95dea8b 100644 --- a/wezterm-gui/src/gui/overlay/confirm_close_pane.rs +++ b/wezterm-gui/src/gui/overlay/confirm_close_pane.rs @@ -53,7 +53,7 @@ fn run_confirmation_app(message: &str, term: &mut TermWizTerminal) -> anyhow::Re No, } - let render = |term: &mut TermWizTerminal, active: ActiveButton| -> anyhow::Result<()> { + let render = |term: &mut TermWizTerminal, active: ActiveButton| -> termwiz::Result<()> { let mut changes = vec![ Change::ClearScreen(ColorAttribute::Default), Change::CursorVisibility(CursorVisibility::Hidden), diff --git a/wezterm-gui/src/gui/overlay/launcher.rs b/wezterm-gui/src/gui/overlay/launcher.rs index dddfdfeef..7f5e205eb 100644 --- a/wezterm-gui/src/gui/overlay/launcher.rs +++ b/wezterm-gui/src/gui/overlay/launcher.rs @@ -165,7 +165,7 @@ pub fn launcher( active_idx: usize, entries: &[Entry], term: &mut TermWizTerminal, - ) -> anyhow::Result<()> { + ) -> termwiz::Result<()> { let mut changes = vec![ Change::ClearScreen(ColorAttribute::Default), Change::CursorPosition { diff --git a/wezterm-gui/src/gui/overlay/tabnavigator.rs b/wezterm-gui/src/gui/overlay/tabnavigator.rs index efa99af27..137c56d7e 100644 --- a/wezterm-gui/src/gui/overlay/tabnavigator.rs +++ b/wezterm-gui/src/gui/overlay/tabnavigator.rs @@ -26,7 +26,7 @@ pub fn tab_navigator( active_tab_idx: usize, tab_list: &[(String, TabId, usize)], term: &mut TermWizTerminal, - ) -> anyhow::Result<()> { + ) -> termwiz::Result<()> { // let dims = term.get_screen_size()?; let mut changes = vec![ Change::ClearScreen(ColorAttribute::Default),