diff --git a/Cargo.lock b/Cargo.lock index c69d5e7ed..87d867399 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3242,26 +3242,6 @@ dependencies = [ "remove_dir_all", ] -[[package]] -name = "term" -version = "0.1.0" -dependencies = [ - "anyhow", - "bitflags 1.2.1", - "image 0.23.5", - "log", - "num", - "ordered-float", - "palette", - "pretty_assertions", - "serde", - "serde_derive", - "termwiz", - "unicode-segmentation", - "unicode-width", - "url", -] - [[package]] name = "termcolor" version = "1.1.0" @@ -3903,7 +3883,6 @@ dependencies = [ "strsim 0.10.0", "structopt", "tabout", - "term", "terminfo", "termwiz", "textwrap", @@ -3917,12 +3896,33 @@ dependencies = [ "varbincode", "vergen", "walkdir", + "wezterm-term", "winapi 0.3.8", "window", "winrt-notification", "zstd", ] +[[package]] +name = "wezterm-term" +version = "0.1.0" +dependencies = [ + "anyhow", + "bitflags 1.2.1", + "image 0.23.5", + "log", + "num", + "ordered-float", + "palette", + "pretty_assertions", + "serde", + "serde_derive", + "termwiz", + "unicode-segmentation", + "unicode-width", + "url", +] + [[package]] name = "winapi" version = "0.2.8" diff --git a/Cargo.toml b/Cargo.toml index 462273980..5d470e3b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,7 +68,7 @@ ssh2 = "0.8" structopt = "0.3" strsim = "0.10" tabout = { path = "tabout" } -term = { path = "term" } +wezterm-term = { path = "term" } terminfo = "0.7" termwiz = { path = "termwiz" } textwrap = "0.11" diff --git a/src/config/color.rs b/src/config/color.rs index ca61d0afa..029987106 100644 --- a/src/config/color.rs +++ b/src/config/color.rs @@ -28,9 +28,9 @@ pub struct Palette { } impl_lua_conversion!(Palette); -impl From for term::color::ColorPalette { - fn from(cfg: Palette) -> term::color::ColorPalette { - let mut p = term::color::ColorPalette::default(); +impl From for wezterm_term::color::ColorPalette { + fn from(cfg: Palette) -> wezterm_term::color::ColorPalette { + let mut p = wezterm_term::color::ColorPalette::default(); macro_rules! apply_color { ($name:ident) => { if let Some($name) = cfg.$name { @@ -66,10 +66,10 @@ impl From for term::color::ColorPalette { pub struct TabBarColor { /// Specifies the intensity attribute for the tab title text #[serde(default)] - pub intensity: term::Intensity, + pub intensity: wezterm_term::Intensity, /// Specifies the underline attribute for the tab title text #[serde(default)] - pub underline: term::Underline, + pub underline: wezterm_term::Underline, /// Specifies the italic attribute for the tab title text #[serde(default)] pub italic: bool, diff --git a/src/config/font.rs b/src/config/font.rs index b1b2aec6d..3f6d58f15 100644 --- a/src/config/font.rs +++ b/src/config/font.rs @@ -187,17 +187,17 @@ pub struct StyleRule { /// If present, this rule matches when CellAttributes::intensity holds /// a value that matches this rule. Valid values are "Bold", "Normal", /// "Half". - pub intensity: Option, + pub intensity: Option, /// If present, this rule matches when CellAttributes::underline holds /// a value that matches this rule. Valid values are "None", "Single", /// "Double". - pub underline: Option, + pub underline: Option, /// If present, this rule matches when CellAttributes::italic holds /// a value that matches this rule. pub italic: Option, /// If present, this rule matches when CellAttributes::blink holds /// a value that matches this rule. - pub blink: Option, + pub blink: Option, /// If present, this rule matches when CellAttributes::reverse holds /// a value that matches this rule. pub reverse: Option, diff --git a/src/config/mod.rs b/src/config/mod.rs index 9e75c128b..8f1bdc628 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -18,7 +18,6 @@ use std::io::prelude::*; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; use std::time::Duration; -use term; use termwiz::hyperlink; use termwiz::input::{KeyCode, Modifiers}; use termwiz::surface::CursorShape; @@ -713,14 +712,14 @@ impl Config { }); cfg.font_rules.push(StyleRule { - intensity: Some(term::Intensity::Bold), + intensity: Some(wezterm_term::Intensity::Bold), font: bold, ..Default::default() }); cfg.font_rules.push(StyleRule { italic: Some(true), - intensity: Some(term::Intensity::Bold), + intensity: Some(wezterm_term::Intensity::Bold), font: bold_italic, ..Default::default() }); diff --git a/src/config/terminal.rs b/src/config/terminal.rs index 682a919f1..c93430484 100644 --- a/src/config/terminal.rs +++ b/src/config/terminal.rs @@ -1,13 +1,13 @@ //! Bridge our gui config into the terminal crate configuration use crate::config::configuration; -use term::color::ColorPalette; use termwiz::hyperlink::Rule as HyperlinkRule; +use wezterm_term::color::ColorPalette; #[derive(Debug)] pub struct TermConfig; -impl term::TerminalConfiguration for TermConfig { +impl wezterm_term::TerminalConfiguration for TermConfig { fn generation(&self) -> usize { configuration().generation() } diff --git a/src/font/mod.rs b/src/font/mod.rs index 112969d7f..414944bf2 100644 --- a/src/font/mod.rs +++ b/src/font/mod.rs @@ -22,7 +22,7 @@ pub use crate::font::shaper::{FallbackIdx, FontMetrics, GlyphInfo}; use crate::font::shaper::{FontShaper, FontShaperSelection}; use super::config::{configuration, ConfigHandle, TextStyle}; -use term::CellAttributes; +use wezterm_term::CellAttributes; pub struct LoadedFont { rasterizers: Vec>>>, diff --git a/src/frontend/gui/overlay/copy.rs b/src/frontend/gui/overlay/copy.rs index ae9da9ba5..2a2725fc6 100644 --- a/src/frontend/gui/overlay/copy.rs +++ b/src/frontend/gui/overlay/copy.rs @@ -9,12 +9,12 @@ use std::cell::{RefCell, RefMut}; use std::ops::Range; use std::rc::Rc; use std::sync::Arc; -use term::color::ColorPalette; -use term::{ - unicode_column_width, Clipboard, KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex, -}; use unicode_segmentation::*; use url::Url; +use wezterm_term::color::ColorPalette; +use wezterm_term::{ + unicode_column_width, Clipboard, KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex, +}; use window::WindowOps; pub struct CopyOverlay { diff --git a/src/frontend/gui/overlay/search.rs b/src/frontend/gui/overlay/search.rs index d5be082b2..d976b6009 100644 --- a/src/frontend/gui/overlay/search.rs +++ b/src/frontend/gui/overlay/search.rs @@ -11,11 +11,11 @@ use std::collections::HashMap; use std::ops::Range; use std::rc::Rc; use std::sync::Arc; -use term::color::ColorPalette; -use term::{Clipboard, KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex}; use termwiz::cell::{Cell, CellAttributes}; use termwiz::color::AnsiColor; use url::Url; +use wezterm_term::color::ColorPalette; +use wezterm_term::{Clipboard, KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex}; use window::WindowOps; pub struct SearchOverlay { @@ -420,7 +420,7 @@ impl Renderable for SearchRenderable { fn get_cursor_position(&self) -> StableCursorPosition { // move to the search box StableCursorPosition { - x: 8 + term::unicode_column_width(&self.pattern), + x: 8 + wezterm_term::unicode_column_width(&self.pattern), y: self.compute_search_row(), shape: termwiz::surface::CursorShape::SteadyBlock, visibility: termwiz::surface::CursorVisibility::Visible, diff --git a/src/frontend/gui/scrollbar.rs b/src/frontend/gui/scrollbar.rs index 0925f5cde..295fc47b0 100644 --- a/src/frontend/gui/scrollbar.rs +++ b/src/frontend/gui/scrollbar.rs @@ -1,7 +1,7 @@ use crate::mux::renderable::Renderable; use ::window::*; use portable_pty::PtySize; -use term::StableRowIndex; +use wezterm_term::StableRowIndex; pub enum ScrollHit { Above, diff --git a/src/frontend/gui/selection.rs b/src/frontend/gui/selection.rs index 7e042ff18..698613cbb 100644 --- a/src/frontend/gui/selection.rs +++ b/src/frontend/gui/selection.rs @@ -4,8 +4,8 @@ use crate::mux::renderable::Renderable; use serde::{Deserialize, Serialize}; use std::ops::Range; -use term::StableRowIndex; use termwiz::surface::line::DoubleClickRange; +use wezterm_term::StableRowIndex; #[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq)] pub enum SelectionMode { diff --git a/src/frontend/gui/tabbar.rs b/src/frontend/gui/tabbar.rs index bc0e43fcb..590daacf0 100644 --- a/src/frontend/gui/tabbar.rs +++ b/src/frontend/gui/tabbar.rs @@ -1,11 +1,11 @@ use crate::config::TabBarColors; use crate::mux::window::Window as MuxWindow; use std::cell::Ref; -use term::Line; use termwiz::cell::unicode_column_width; use termwiz::cell::{Cell, CellAttributes}; use termwiz::color::ColorSpec; use unicode_segmentation::UnicodeSegmentation; +use wezterm_term::Line; #[derive(Clone, Debug, PartialEq)] pub struct TabBarState { diff --git a/src/frontend/gui/termwindow.rs b/src/frontend/gui/termwindow.rs index f1950e59c..8111def3e 100644 --- a/src/frontend/gui/termwindow.rs +++ b/src/frontend/gui/termwindow.rs @@ -22,8 +22,8 @@ use crate::mux::renderable::{RenderableDimensions, StableCursorPosition}; use crate::mux::tab::{Tab, TabId}; use crate::mux::window::WindowId as MuxWindowId; use crate::mux::Mux; -use ::term::input::MouseButton as TMB; -use ::term::input::MouseEventKind as TMEK; +use ::wezterm_term::input::MouseButton as TMB; +use ::wezterm_term::input::MouseEventKind as TMEK; use ::window::bitmaps::atlas::{OutOfTextureSpace, SpriteSlice}; use ::window::bitmaps::Texture2d; use ::window::glium::uniforms::{ @@ -46,12 +46,12 @@ use std::rc::Rc; use std::sync::Arc; use std::sync::Mutex; use std::time::{Duration, Instant}; -use term::color::ColorPalette; -use term::input::LastMouseClick; -use term::{Line, StableRowIndex, Underline}; use termwiz::color::RgbColor; use termwiz::hyperlink::Hyperlink; use termwiz::surface::{CursorShape, CursorVisibility}; +use wezterm_term::color::ColorPalette; +use wezterm_term::input::LastMouseClick; +use wezterm_term::{Line, StableRowIndex, Underline}; struct RenderScreenLineOpenGLParams<'a> { line_idx: usize, @@ -82,7 +82,7 @@ pub struct ClipboardHelper { clipboard_contents: Arc>>, } -impl term::Clipboard for ClipboardHelper { +impl wezterm_term::Clipboard for ClipboardHelper { fn get_contents(&self) -> anyhow::Result { // Even though we could request the clipboard contents using a call // like `self.window.get_clipboard().wait()` here, that requires @@ -785,7 +785,7 @@ impl TermWindow { }, ); - let clipboard: Arc = Arc::new(ClipboardHelper { + let clipboard: Arc = Arc::new(ClipboardHelper { window: window.clone(), clipboard_contents, }); @@ -1403,7 +1403,7 @@ impl TermWindow { let fonts = Rc::new(FontConfiguration::new()); front_end.spawn_new_window(&fonts, &tab, mux_window_id)?; } else { - let clipboard: Arc = Arc::new(clipboard); + let clipboard: Arc = Arc::new(clipboard); tab.set_clipboard(&clipboard); let mut window = mux .get_window_mut(mux_window_id) @@ -1938,7 +1938,7 @@ impl TermWindow { ) -> anyhow::Result<()> { let palette = tab.palette(); - let background_color = palette.resolve_bg(term::color::ColorAttribute::Default); + let background_color = palette.resolve_bg(wezterm_term::color::ColorAttribute::Default); let (r, g, b, a) = background_color.to_tuple_rgba(); frame.clear_color_srgb(r, g, b, a); @@ -2174,25 +2174,25 @@ impl TermWindow { let bg_color = params.palette.resolve_bg(attrs.background); let fg_color = match attrs.foreground { - term::color::ColorAttribute::Default => { + wezterm_term::color::ColorAttribute::Default => { if let Some(fg) = style.foreground { fg } else { params.palette.resolve_fg(attrs.foreground) } } - term::color::ColorAttribute::PaletteIndex(idx) if idx < 8 => { + wezterm_term::color::ColorAttribute::PaletteIndex(idx) if idx < 8 => { // For compatibility purposes, switch to a brighter version // of one of the standard ANSI colors when Bold is enabled. // This lifts black to dark grey. - let idx = if attrs.intensity() == term::Intensity::Bold { + let idx = if attrs.intensity() == wezterm_term::Intensity::Bold { idx + 8 } else { idx }; params .palette - .resolve_fg(term::color::ColorAttribute::PaletteIndex(idx)) + .resolve_fg(wezterm_term::color::ColorAttribute::PaletteIndex(idx)) } _ => params.palette.resolve_fg(attrs.foreground), }; @@ -2460,23 +2460,23 @@ impl TermWindow { let bg_color = palette.resolve_bg(attrs.background); let fg_color = match attrs.foreground { - term::color::ColorAttribute::Default => { + wezterm_term::color::ColorAttribute::Default => { if let Some(fg) = style.foreground { fg } else { palette.resolve_fg(attrs.foreground) } } - term::color::ColorAttribute::PaletteIndex(idx) if idx < 8 => { + wezterm_term::color::ColorAttribute::PaletteIndex(idx) if idx < 8 => { // For compatibility purposes, switch to a brighter version // of one of the standard ANSI colors when Bold is enabled. // This lifts black to dark grey. - let idx = if attrs.intensity() == term::Intensity::Bold { + let idx = if attrs.intensity() == wezterm_term::Intensity::Bold { idx + 8 } else { idx }; - palette.resolve_fg(term::color::ColorAttribute::PaletteIndex(idx)) + palette.resolve_fg(wezterm_term::color::ColorAttribute::PaletteIndex(idx)) } _ => palette.resolve_fg(attrs.foreground), }; @@ -3141,7 +3141,7 @@ impl TermWindow { return; } - let mouse_event = term::MouseEvent { + let mouse_event = wezterm_term::MouseEvent { kind: match event.kind { WMEK::Move => TMEK::Move, WMEK::VertWheel(_) | WMEK::HorzWheel(_) | WMEK::Press(_) => TMEK::Press, diff --git a/src/frontend/gui/utilsprites.rs b/src/frontend/gui/utilsprites.rs index 40c1e39d2..c3a68b5d4 100644 --- a/src/frontend/gui/utilsprites.rs +++ b/src/frontend/gui/utilsprites.rs @@ -5,8 +5,8 @@ use ::window::bitmaps::atlas::{OutOfTextureSpace, Sprite}; use ::window::bitmaps::{BitmapImage, Image, Texture2d}; use ::window::*; use std::rc::Rc; -use term::Underline; use termwiz::surface::CursorShape; +use wezterm_term::Underline; #[derive(Copy, Clone)] pub struct RenderMetrics { diff --git a/src/keyassignment.rs b/src/keyassignment.rs index 865b46794..abbe4c78d 100644 --- a/src/keyassignment.rs +++ b/src/keyassignment.rs @@ -5,8 +5,8 @@ use crate::mux::tab::Pattern; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::path::PathBuf; -use term::input::MouseButton; -use term::{KeyCode, KeyModifiers}; +use wezterm_term::input::MouseButton; +use wezterm_term::{KeyCode, KeyModifiers}; /// A mouse event that can trigger an action #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Hash)] diff --git a/src/localtab.rs b/src/localtab.rs index 5d4cc140a..762cdce5f 100644 --- a/src/localtab.rs +++ b/src/localtab.rs @@ -7,9 +7,9 @@ use async_trait::async_trait; use portable_pty::{Child, MasterPty, PtySize}; use std::cell::{RefCell, RefMut}; use std::sync::Arc; -use term::color::ColorPalette; -use term::{Clipboard, KeyCode, KeyModifiers, MouseEvent, StableRowIndex, Terminal}; use url::Url; +use wezterm_term::color::ColorPalette; +use wezterm_term::{Clipboard, KeyCode, KeyModifiers, MouseEvent, StableRowIndex, Terminal}; pub struct LocalTab { tab_id: TabId, diff --git a/src/mux/domain.rs b/src/mux/domain.rs index 33ea4ea12..fbc814f43 100644 --- a/src/mux/domain.rs +++ b/src/mux/domain.rs @@ -126,7 +126,7 @@ impl Domain for LocalDomain { let writer = pair.master.try_clone_writer()?; - let terminal = term::Terminal::new( + let terminal = wezterm_term::Terminal::new( size.rows as usize, size.cols as usize, size.pixel_width as usize, diff --git a/src/mux/renderable.rs b/src/mux/renderable.rs index c3bd43cd0..1f7d1449c 100644 --- a/src/mux/renderable.rs +++ b/src/mux/renderable.rs @@ -3,7 +3,7 @@ use downcast_rs::{impl_downcast, Downcast}; use rangeset::RangeSet; use serde::{Deserialize, Serialize}; use std::ops::Range; -use term::{Line, StableRowIndex, Terminal}; +use wezterm_term::{Line, StableRowIndex, Terminal}; /// Describes the location of the cursor #[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Deserialize, Serialize)] @@ -34,7 +34,7 @@ pub struct RenderableDimensions { pub scrollback_top: StableRowIndex, } -/// Renderable allows passing something that isn't an actual term::Terminal +/// Renderable allows passing something that isn't an actual wezterm_term::Terminal /// instance into the renderer, which opens up remoting of the terminal /// surfaces via a multiplexer. pub trait Renderable: Downcast { diff --git a/src/mux/tab.rs b/src/mux/tab.rs index 5f688ccbb..baa3ccc15 100644 --- a/src/mux/tab.rs +++ b/src/mux/tab.rs @@ -7,9 +7,9 @@ use portable_pty::PtySize; use serde::{Deserialize, Serialize}; use std::cell::RefMut; use std::sync::{Arc, Mutex}; -use term::color::ColorPalette; -use term::{Clipboard, KeyCode, KeyModifiers, MouseEvent, StableRowIndex}; use url::Url; +use wezterm_term::color::ColorPalette; +use wezterm_term::{Clipboard, KeyCode, KeyModifiers, MouseEvent, StableRowIndex}; static TAB_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsize::new(0); pub type TabId = usize; diff --git a/src/mux/window.rs b/src/mux/window.rs index e62695bc4..77625a2c6 100644 --- a/src/mux/window.rs +++ b/src/mux/window.rs @@ -1,7 +1,7 @@ use crate::mux::{Tab, TabId}; use std::rc::Rc; use std::sync::Arc; -use term::Clipboard; +use wezterm_term::Clipboard; static WIN_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsize::new(0); pub type WindowId = usize; diff --git a/src/server/codec.rs b/src/server/codec.rs index 73b7561cf..353816c23 100644 --- a/src/server/codec.rs +++ b/src/server/codec.rs @@ -25,11 +25,11 @@ use std::convert::TryInto; use std::io::Cursor; use std::ops::Range; use std::sync::Arc; -use term::StableRowIndex; use termwiz::hyperlink::Hyperlink; use termwiz::surface::Line; use url::Url; use varbincode; +use wezterm_term::StableRowIndex; /// Returns the encoded length of the leb128 representation of value fn encoded_length(value: u64) -> usize { @@ -515,7 +515,7 @@ impl Into for std::time::SystemTime { #[derive(Deserialize, Serialize, PartialEq, Debug)] pub struct SendMouseEvent { pub tab_id: TabId, - pub event: term::input::MouseEvent, + pub event: wezterm_term::input::MouseEvent, } #[derive(Deserialize, Serialize, PartialEq, Debug)] diff --git a/src/server/listener/sessionhandler.rs b/src/server/listener/sessionhandler.rs index 66f600f54..6b020560a 100644 --- a/src/server/listener/sessionhandler.rs +++ b/src/server/listener/sessionhandler.rs @@ -12,9 +12,9 @@ use std::collections::HashMap; use std::rc::Rc; use std::sync::{Arc, Mutex}; use std::time::Instant; -use term::terminal::Clipboard; -use term::StableRowIndex; use url::Url; +use wezterm_term::terminal::Clipboard; +use wezterm_term::StableRowIndex; #[derive(Default, Debug)] struct PerTab { diff --git a/src/server/tab/clienttab.rs b/src/server/tab/clienttab.rs index 3f3bbda49..2bfeb00d2 100644 --- a/src/server/tab/clienttab.rs +++ b/src/server/tab/clienttab.rs @@ -16,10 +16,10 @@ use std::cell::RefCell; use std::cell::RefMut; use std::rc::Rc; use std::sync::Arc; -use term::color::ColorPalette; -use term::{Clipboard, KeyCode, KeyModifiers, MouseEvent}; use termwiz::input::KeyEvent; use url::Url; +use wezterm_term::color::ColorPalette; +use wezterm_term::{Clipboard, KeyCode, KeyModifiers, MouseEvent}; pub struct ClientTab { client: Arc, diff --git a/src/server/tab/mousestate.rs b/src/server/tab/mousestate.rs index c76aa445e..0cc4ef529 100644 --- a/src/server/tab/mousestate.rs +++ b/src/server/tab/mousestate.rs @@ -5,7 +5,7 @@ use std::cell::RefCell; use std::collections::VecDeque; use std::rc::Rc; use std::sync::atomic::{AtomicBool, Ordering}; -use term::{MouseButton, MouseEvent, MouseEventKind}; +use wezterm_term::{MouseButton, MouseEvent, MouseEventKind}; pub struct MouseState { pending: AtomicBool, diff --git a/src/server/tab/renderable.rs b/src/server/tab/renderable.rs index c7e28c652..a45d74d3b 100644 --- a/src/server/tab/renderable.rs +++ b/src/server/tab/renderable.rs @@ -15,11 +15,11 @@ use std::ops::Range; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::{Duration, Instant}; -use term::{KeyCode, KeyModifiers}; -use term::{Line, StableRowIndex}; use termwiz::cell::{Cell, CellAttributes, Underline}; use termwiz::color::AnsiColor; use url::Url; +use wezterm_term::{KeyCode, KeyModifiers}; +use wezterm_term::{Line, StableRowIndex}; const MAX_POLL_INTERVAL: Duration = Duration::from_secs(30); const BASE_POLL_INTERVAL: Duration = Duration::from_millis(20); @@ -654,7 +654,7 @@ impl Renderable for RenderableState { let col = inner .dimensions .cols - .saturating_sub(term::unicode_column_width(&status)); + .saturating_sub(wezterm_term::unicode_column_width(&status)); let mut attr = CellAttributes::default(); attr.foreground = AnsiColor::White.into(); diff --git a/src/ssh.rs b/src/ssh.rs index c5eeb28c4..87187011a 100644 --- a/src/ssh.rs +++ b/src/ssh.rs @@ -252,7 +252,7 @@ impl Domain for RemoteSshDomain { let writer = pair.master.try_clone_writer()?; - let terminal = term::Terminal::new( + let terminal = wezterm_term::Terminal::new( size.rows as usize, size.cols as usize, size.pixel_width as usize, diff --git a/src/termwiztermtab.rs b/src/termwiztermtab.rs index 2205667e9..e20a91d95 100644 --- a/src/termwiztermtab.rs +++ b/src/termwiztermtab.rs @@ -22,8 +22,6 @@ use std::io::Write; use std::rc::Rc; use std::sync::Arc; use std::time::Duration; -use term::color::ColorPalette; -use term::{KeyCode, KeyModifiers, MouseEvent}; use termwiz::caps::{Capabilities, ColorLevel, ProbeHints}; use termwiz::input::{InputEvent, KeyEvent, MouseEvent as TermWizMouseEvent}; use termwiz::lineedit::*; @@ -31,6 +29,8 @@ use termwiz::render::terminfo::TerminfoRenderer; use termwiz::surface::Change; use termwiz::terminal::{ScreenSize, Terminal, TerminalWaker}; use url::Url; +use wezterm_term::color::ColorPalette; +use wezterm_term::{KeyCode, KeyModifiers, MouseEvent}; struct TermWizTerminalDomain { domain_id: DomainId, @@ -82,7 +82,7 @@ impl Domain for TermWizTerminalDomain { pub struct TermWizTerminalTab { tab_id: TabId, domain_id: DomainId, - terminal: RefCell, + terminal: RefCell, input_tx: Sender, dead: RefCell, writer: RefCell>, @@ -99,7 +99,7 @@ impl TermWizTerminalTab { ) -> Self { let tab_id = alloc_tab_id(); - let terminal = RefCell::new(term::Terminal::new( + let terminal = RefCell::new(wezterm_term::Terminal::new( height, width, 0, @@ -175,8 +175,8 @@ impl Tab for TermWizTerminalTab { } fn mouse_event(&self, event: MouseEvent) -> anyhow::Result<()> { - use term::input::MouseButton; use termwiz::input::MouseButtons as Buttons; + use wezterm_term::input::MouseButton; let mouse_buttons = match event.button { MouseButton::Left => Buttons::LEFT, diff --git a/term/Cargo.toml b/term/Cargo.toml index 36a691e6c..57322f2c6 100644 --- a/term/Cargo.toml +++ b/term/Cargo.toml @@ -1,8 +1,14 @@ [package] authors = ["Wez Furlong "] -name = "term" +name = "wezterm-term" version = "0.1.0" edition = "2018" +repository = "https://github.com/wez/wezterm" +description = "The Virtual Terminal Emulator core from wezterm; helpful for implementing terminal emulators" +license = "MIT" +documentation = "https://docs.rs/wezterm-term" +keywords = ["terminal", "emulator", "vte"] +readme = "README.md" [dependencies] bitflags = "1.0" @@ -22,4 +28,5 @@ url = "2" pretty_assertions = "0.6" [dependencies.termwiz] +version = "0.10" path = "../termwiz" diff --git a/term/README.md b/term/README.md new file mode 100644 index 000000000..f7598d2e3 --- /dev/null +++ b/term/README.md @@ -0,0 +1,21 @@ +# wezterm-term + +This crate provides the core of the virtual terminal emulator implementation +used by [wezterm](https://wezfurlong.org/wezterm/). The home for this +crate is in the wezterm repo and development is tracked at +. + +It is full featured, providing terminal escape sequence parsing, keyboard +and mouse input encoding, a model for the screen cells including scrollback, +sixel and iTerm2 image support, OSC 8 Hyperlinks and a wide range of +terminal cell attributes. + +This crate does not provide any kind of gui, nor does it directly +manage a PTY; you provide a `std::io::Write` implementation that +could connect to a PTY, and supply bytes to the model via the +`advance_bytes` method. + +The entrypoint to the crate is the [Terminal](terminal/struct.Terminal.html) +struct. + +License: MIT diff --git a/term/src/config.rs b/term/src/config.rs index 8ba25b6d9..d31b49316 100644 --- a/term/src/config.rs +++ b/term/src/config.rs @@ -1,6 +1,11 @@ use crate::color::ColorPalette; use termwiz::hyperlink::Rule as HyperlinkRule; +/// TerminalConfiguration allows for the embedding application to pass configuration +/// information to the Terminal. +/// The configuration can be changed at runtime; provided that the implementation +/// increments the generation counter appropriately, the changes will be detected +/// and applied at the next appropriate opportunity. pub trait TerminalConfiguration: std::fmt::Debug { /// Returns a generation counter for the active /// configuration. If the implementation may be @@ -11,35 +16,28 @@ pub trait TerminalConfiguration: std::fmt::Debug { 0 } + /// Returns the size of the scrollback in terms of the number of rows. fn scrollback_size(&self) -> usize { 3500 } - // TODO: expose is_double_click_word in config file - fn is_double_click_word(&self, s: &str) -> bool { - match s.len() { - 1 => match s.chars().nth(0).unwrap() { - ' ' | '\t' | '\n' | '{' | '[' | '}' | ']' | '(' | ')' | '"' | '\'' => false, - _ => true, - }, - 0 => false, - _ => true, - } - } - + /// Return true if the embedding application wants to use CSI-u encoding + /// for keys that would otherwise be ambiguous. + /// fn enable_csi_u_key_encoding(&self) -> bool { false } - // TODO: expose scroll_to_bottom_on_key_input in config file - fn scroll_to_bottom_on_key_input(&self) -> bool { - true - } - /// Returns the current generation and its associated hyperlink rules. + /// hyperlink rules are used to recognize and automatically generate + /// hyperlink attributes for runs of text that match the provided rules. fn hyperlink_rules(&self) -> (usize, Vec) { (self.generation(), vec![]) } + /// Returns the default color palette for the application. + /// Various escape sequences can dynamically modify the effective + /// color palette for a terminal instance at runtime, but this method + /// defines the initial palette. fn color_palette(&self) -> ColorPalette; } diff --git a/term/src/lib.rs b/term/src/lib.rs index f0df17213..bb66acf48 100644 --- a/term/src/lib.rs +++ b/term/src/lib.rs @@ -1,4 +1,20 @@ -//! Terminal model +//! This crate provides the core of the virtual terminal emulator implementation +//! used by [wezterm](https://wezfurlong.org/wezterm/). The home for this +//! crate is in the wezterm repo and development is tracked at +//! . +//! +//! It is full featured, providing terminal escape sequence parsing, keyboard +//! and mouse input encoding, a model for the screen cells including scrollback, +//! sixel and iTerm2 image support, OSC 8 Hyperlinks and a wide range of +//! terminal cell attributes. +//! +//! This crate does not provide any kind of gui, nor does it directly +//! manage a PTY; you provide a `std::io::Write` implementation that +//! could connect to a PTY, and supply bytes to the model via the +//! `advance_bytes` method. +//! +//! The entrypoint to the crate is the [Terminal](terminal/struct.Terminal.html) +//! struct. use serde_derive::*; use anyhow::Error; @@ -103,7 +119,7 @@ pub mod color; mod test; pub const CSI: &str = "\x1b["; -pub const OSC: &[u8] = b"\x1b]"; -pub const ST: &[u8] = b"\x1b\\"; +pub const OSC: &str = "\x1b]"; +pub const ST: &str = "\x1b\\"; pub const SS3: &str = "\x1bO"; -pub const DCS: &[u8] = b"\x1bP"; +pub const DCS: &str = "\x1bP"; diff --git a/term/src/screen.rs b/term/src/screen.rs index b198ff880..7e356690e 100644 --- a/term/src/screen.rs +++ b/term/src/screen.rs @@ -375,11 +375,13 @@ impl Screen { self.phys_to_stable_row_index(self.phys_row(vis)) } + /// ```norun /// --------- /// | /// |--- top /// | /// |--- bottom + /// ``` /// /// scroll the region up by num_rows. Any rows that would be scrolled /// beyond the top get removed from the screen. @@ -479,11 +481,13 @@ impl Screen { } } + /// ```norun /// --------- /// | /// |--- top /// | /// |--- bottom + /// ``` /// /// scroll the region down by num_rows. Any rows that would be scrolled /// beyond the bottom get removed from the screen. diff --git a/term/src/terminal.rs b/term/src/terminal.rs index 3772e08d0..a9e69e6ff 100644 --- a/term/src/terminal.rs +++ b/term/src/terminal.rs @@ -17,6 +17,7 @@ impl Clipboard for Box { } } +/// Represents an instance of a terminal emulator. pub struct Terminal { /// The terminal model/state state: TerminalState, @@ -39,6 +40,22 @@ impl DerefMut for Terminal { } impl Terminal { + /// Construct a new Terminal. + /// `physical_rows` and `physical_cols` describe the dimensions + /// of the visible portion of the terminal display in terms of + /// the number of text cells. + /// + /// `pixel_width` and `pixel_height` describe the dimensions of + /// that same visible area but in pixels. + /// + /// `term_program` and `term_version` are required to identify + /// the host terminal program; they are used to respond to the + /// terminal identification sequence `\033[>q`. + /// + /// `writer` is anything that implements `std::io::Write`; it + /// is used to send input to the connected program; both keyboard + /// and mouse input is encoded and written to that stream, as + /// are answerback responses to a number of escape sequences. pub fn new( physical_rows: usize, physical_cols: usize, @@ -65,7 +82,11 @@ impl Terminal { } } - /// Feed the terminal parser a slice of bytes of input. + /// Feed the terminal parser a slice of bytes from the output + /// of the associated program. + /// The slice is not required to be a complete sequence of escape + /// characters; it is valid to feed in chunks of data as they arrive. + /// The output is parsed and applied to the terminal model. pub fn advance_bytes>(&mut self, bytes: B) { let bytes = bytes.as_ref(); diff --git a/term/src/terminalstate.rs b/term/src/terminalstate.rs index 478ff12f4..9b5fea49e 100644 --- a/term/src/terminalstate.rs +++ b/term/src/terminalstate.rs @@ -170,6 +170,7 @@ impl ScreenOrAlt { } } +/// Manages the state for the terminal pub struct TerminalState { config: Arc, @@ -285,6 +286,9 @@ fn default_color_map() -> HashMap { } impl TerminalState { + /// Constructs the terminal state. + /// You generally want the `Terminal` struct rather than this one; + /// Terminal contains and dereferences to `TerminalState`. pub fn new( physical_rows: usize, physical_cols: usize, @@ -342,10 +346,16 @@ impl TerminalState { self.clipboard.replace(Arc::clone(clipboard)); } + /// Returns the title text associated with the terminal session. + /// The title can be changed by the application using a number + /// of escape sequences. pub fn get_title(&self) -> &str { &self.title } + /// Returns the current working directory associated with the + /// terminal session. The working directory can be changed by + /// the applicaiton using the OSC 7 escape sequence. pub fn get_current_dir(&self) -> Option<&Url> { self.current_dir.as_ref() } @@ -374,10 +384,14 @@ impl TerminalState { self.palette.as_mut().unwrap() } + /// Returns a reference to the active screen (either the primary or + /// the alternate screen). pub fn screen(&self) -> &Screen { &self.screen } + /// Returns a mutable reference to the active screen (either the primary or + /// the alternate screen). pub fn screen_mut(&mut self) -> &mut Screen { &mut self.screen } @@ -547,6 +561,9 @@ impl TerminalState { Ok(()) } + /// Informs the terminal of a mouse event. + /// If mouse reporting has been activated, the mouse event will be encoded + /// appropriately and written to the associated writer. pub fn mouse_event(&mut self, mut event: MouseEvent) -> Result<(), Error> { // Clamp the mouse coordinates to the size of the model. // This situation can trigger for example when the @@ -583,21 +600,30 @@ impl TerminalState { } } + /// Discards the scrollback, leaving only the data that is present + /// in the viewport. pub fn erase_scrollback(&mut self) { self.screen_mut().erase_scrollback(); } + /// Returns true if the associated application has enabled any of the + /// supported mouse reporting modes. + /// This is useful for the hosting GUI application to decide how best + /// to dispatch mouse events to the terminal. pub fn is_mouse_grabbed(&self) -> bool { self.mouse_tracking || self.button_event_mouse || self.any_event_mouse } + /// Returns true if the associated application has enabled + /// bracketed paste mode, which can be helpful to the hosting + /// GUI application to decide about fragmenting a large paste. pub fn bracketed_paste_enabled(&self) -> bool { self.bracketed_paste } /// Send text to the terminal that is the result of pasting. /// If bracketed paste mode is enabled, the paste is enclosed - /// in the bracketing, otherwise it is fed to the pty as-is. + /// in the bracketing, otherwise it is fed to the writer as-is. pub fn send_paste(&mut self, text: &str) -> Result<(), Error> { if self.bracketed_paste { let buf = format!("\x1b[200~{}\x1b[201~", text); @@ -868,6 +894,8 @@ impl TerminalState { Ok(()) } + /// Informs the terminal that the viewport of the window has resized to the + /// specified dimensions. pub fn resize( &mut self, physical_rows: usize, @@ -1273,11 +1301,11 @@ impl TerminalState { self.writer.write(b"\x1b[>0;0;0c").ok(); } Device::RequestTerminalNameAndVersion => { - self.writer.write(DCS).ok(); + self.writer.write(DCS.as_bytes()).ok(); self.writer .write(format!(">|{} {}", self.term_program, self.term_version).as_bytes()) .ok(); - self.writer.write(ST).ok(); + self.writer.write(ST.as_bytes()).ok(); } Device::StatusReport => { self.writer.write(b"\x1b[0n").ok();