1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-25 02:13:09 +03:00

term: rename crate to wezterm-term in advance of publishing

Add some more docs and remove a couple of dead bits of code.
This commit is contained in:
Wez Furlong 2020-06-13 09:04:13 -07:00
parent 78d25fc1a3
commit d547d938d8
34 changed files with 211 additions and 117 deletions

42
Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -28,9 +28,9 @@ pub struct Palette {
}
impl_lua_conversion!(Palette);
impl From<Palette> for term::color::ColorPalette {
fn from(cfg: Palette) -> term::color::ColorPalette {
let mut p = term::color::ColorPalette::default();
impl From<Palette> 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<Palette> 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,

View File

@ -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<term::Intensity>,
pub intensity: Option<wezterm_term::Intensity>,
/// If present, this rule matches when CellAttributes::underline holds
/// a value that matches this rule. Valid values are "None", "Single",
/// "Double".
pub underline: Option<term::Underline>,
pub underline: Option<wezterm_term::Underline>,
/// If present, this rule matches when CellAttributes::italic holds
/// a value that matches this rule.
pub italic: Option<bool>,
/// If present, this rule matches when CellAttributes::blink holds
/// a value that matches this rule.
pub blink: Option<term::Blink>,
pub blink: Option<wezterm_term::Blink>,
/// If present, this rule matches when CellAttributes::reverse holds
/// a value that matches this rule.
pub reverse: Option<bool>,

View File

@ -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()
});

View File

@ -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()
}

View File

@ -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<RefCell<Option<Box<dyn FontRasterizer>>>>,

View File

@ -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 {

View File

@ -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,

View File

@ -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,

View File

@ -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 {

View File

@ -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 {

View File

@ -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<Mutex<Option<String>>>,
}
impl term::Clipboard for ClipboardHelper {
impl wezterm_term::Clipboard for ClipboardHelper {
fn get_contents(&self) -> anyhow::Result<String> {
// 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<dyn term::Clipboard> = Arc::new(ClipboardHelper {
let clipboard: Arc<dyn wezterm_term::Clipboard> = 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<dyn term::Clipboard> = Arc::new(clipboard);
let clipboard: Arc<dyn wezterm_term::Clipboard> = 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,

View File

@ -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 {

View File

@ -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)]

View File

@ -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,

View File

@ -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,

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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<InputSerial> 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)]

View File

@ -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 {

View File

@ -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<ClientInner>,

View File

@ -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,

View File

@ -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();

View File

@ -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,

View File

@ -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<term::Terminal>,
terminal: RefCell<wezterm_term::Terminal>,
input_tx: Sender<InputEvent>,
dead: RefCell<bool>,
writer: RefCell<Vec<u8>>,
@ -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,

View File

@ -1,8 +1,14 @@
[package]
authors = ["Wez Furlong <wez@wezfurlong.org>"]
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"

21
term/README.md Normal file
View File

@ -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
<https://github.com/wez/wezterm/>.
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

View File

@ -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.
/// <http://www.leonerd.org.uk/hacks/fixterms/>
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<HyperlinkRule>) {
(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;
}

View File

@ -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
//! <https://github.com/wez/wezterm/>.
//!
//! 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";

View File

@ -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.

View File

@ -17,6 +17,7 @@ impl Clipboard for Box<dyn Clipboard> {
}
}
/// 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<B: AsRef<[u8]>>(&mut self, bytes: B) {
let bytes = bytes.as_ref();

View File

@ -170,6 +170,7 @@ impl ScreenOrAlt {
}
}
/// Manages the state for the terminal
pub struct TerminalState {
config: Arc<dyn TerminalConfiguration>,
@ -285,6 +286,9 @@ fn default_color_map() -> HashMap<u16, RgbColor> {
}
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();