1
1
mirror of https://github.com/wez/wezterm.git synced 2025-01-03 11:11:43 +03:00

termwiz: do not depend on derive_builder

derive_builder has some extra dependencies that take a while to compile.
The builder feature can be expressed via a 30-line macro. So let's do
that to make termwiz compile faster.
This commit is contained in:
Jun Wu 2020-02-04 07:20:03 -08:00 committed by Wez Furlong
parent f51650c891
commit ca2e9c013a
6 changed files with 121 additions and 146 deletions

View File

@ -14,7 +14,6 @@ readme = "README.md"
base64 = "0.10"
bitflags = "1.0"
cassowary = {version="0.3", optional=true}
derive_builder = "0.7"
anyhow = "1.0"
filedescriptor = { version="0.7", path = "../filedescriptor" }
fnv = {version="1.0", optional=true}

View File

@ -52,19 +52,19 @@
//! With all this in mind, this module presents a `Capabilities` struct
//! that holds information about a terminal. The `new_from_env` method
//! implements some heuristics (a fancy word for guessing) to compute
//! the terminal capabilities, but also offers a `ProbeHintsBuilder`
//! 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 derive_builder::*;
use semver::Version;
use std::env::var;
use terminfo::{self, capability as cap};
/// Use the `ProbeHintsBuilder` to configure an instance of
builder! {
/// Use the `ProbeHints` to configure an instance of
/// the `ProbeHints` struct. `ProbeHints` are passed to the `Capabilities`
/// constructor to influence the effective set of terminal capabilities.
#[derive(Debug, Default, Builder, Clone)]
#[builder(default)]
#[derive(Debug, Default, Clone)]
pub struct ProbeHints {
/// The contents of the TERM environment variable
term: Option<String>,
@ -109,17 +109,17 @@ pub struct ProbeHints {
/// Whether mouse support is present and should be used
mouse_reporting: Option<bool>,
}
}
impl ProbeHintsBuilder {
pub fn new_from_env() -> ProbeHintsBuilder {
let mut hints = ProbeHintsBuilder::default();
hints.term(var("TERM").ok());
hints.colorterm(var("COLORTERM").ok());
hints.colorterm_bce(var("COLORTERM_BCE").ok());
hints.term_program(var("TERM_PROGRAM").ok());
hints.term_program_version(var("TERM_PROGRAM_VERSION").ok());
hints.terminfo_db(terminfo::Database::from_env().ok());
hints
impl ProbeHints {
pub fn new_from_env() -> Self {
ProbeHints::default()
.term(var("TERM").ok())
.colorterm(var("COLORTERM").ok())
.colorterm_bce(var("COLORTERM_BCE").ok())
.term_program(var("TERM_PROGRAM").ok())
.term_program_version(var("TERM_PROGRAM_VERSION").ok())
.terminfo_db(terminfo::Database::from_env().ok())
}
}
@ -164,11 +164,7 @@ impl Capabilities {
/// This function inspects the environment variables to build
/// up configuration hints.
pub fn new_from_env() -> Result<Self, Error> {
Self::new_with_hints(
ProbeHintsBuilder::new_from_env()
.build()
.map_err(Error::msg)?,
)
Self::new_with_hints(ProbeHints::new_from_env())
}
/// Build a `Capabilities` object based on the provided `ProbeHints` object.
@ -330,8 +326,7 @@ mod test {
#[test]
fn empty_hint() {
let caps =
Capabilities::new_with_hints(ProbeHintsBuilder::default().build().unwrap()).unwrap();
let caps = Capabilities::new_with_hints(ProbeHints::default()).unwrap();
assert_eq!(caps.color_level(), ColorLevel::Sixteen);
assert_eq!(caps.sixel(), false);
@ -342,12 +337,8 @@ mod test {
#[test]
fn bce() {
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
.colorterm_bce(Some("1".into()))
.build()
.unwrap(),
)
let caps =
Capabilities::new_with_hints(ProbeHints::default().colorterm_bce(Some("1".into())))
.unwrap();
assert_eq!(caps.bce(), true);
@ -355,12 +346,8 @@ mod test {
#[test]
fn bce_terminfo() {
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
.terminfo_db(Some(load_terminfo()))
.build()
.unwrap(),
)
let caps =
Capabilities::new_with_hints(ProbeHints::default().terminfo_db(Some(load_terminfo())))
.unwrap();
assert_eq!(caps.bce(), true);
@ -368,12 +355,8 @@ mod test {
#[test]
fn terminfo_color() {
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
.terminfo_db(Some(load_terminfo()))
.build()
.unwrap(),
)
let caps =
Capabilities::new_with_hints(ProbeHints::default().terminfo_db(Some(load_terminfo())))
.unwrap();
assert_eq!(caps.color_level(), ColorLevel::TrueColor);
@ -381,12 +364,8 @@ mod test {
#[test]
fn term_but_not_colorterm() {
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
.term(Some("xterm-256color".into()))
.build()
.unwrap(),
)
let caps =
Capabilities::new_with_hints(ProbeHints::default().term(Some("xterm-256color".into())))
.unwrap();
assert_eq!(caps.color_level(), ColorLevel::TwoFiftySix);
@ -394,12 +373,8 @@ mod test {
#[test]
fn colorterm_but_no_term() {
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
.colorterm(Some("24bit".into()))
.build()
.unwrap(),
)
let caps =
Capabilities::new_with_hints(ProbeHints::default().colorterm(Some("24bit".into())))
.unwrap();
assert_eq!(caps.color_level(), ColorLevel::TrueColor);
@ -408,34 +383,28 @@ mod test {
#[test]
fn term_and_colorterm() {
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
ProbeHints::default()
.term(Some("xterm-256color".into()))
// bogus value
.colorterm(Some("24bot".into()))
.build()
.unwrap(),
.colorterm(Some("24bot".into())),
)
.unwrap();
assert_eq!(caps.color_level(), ColorLevel::TwoFiftySix);
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
ProbeHints::default()
.term(Some("xterm-256color".into()))
.colorterm(Some("24bit".into()))
.build()
.unwrap(),
.colorterm(Some("24bit".into())),
)
.unwrap();
assert_eq!(caps.color_level(), ColorLevel::TrueColor);
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
ProbeHints::default()
.term(Some("xterm-256color".into()))
.colorterm(Some("truecolor".into()))
.build()
.unwrap(),
.colorterm(Some("truecolor".into())),
)
.unwrap();
@ -445,41 +414,33 @@ mod test {
#[test]
fn iterm2_image() {
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
ProbeHints::default()
.term_program(Some("iTerm.app".into()))
.term_program_version(Some("1.0.0".into()))
.build()
.unwrap(),
.term_program_version(Some("1.0.0".into())),
)
.unwrap();
assert_eq!(caps.iterm2_image(), false);
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
ProbeHints::default()
.term_program(Some("iTerm.app".into()))
.term_program_version(Some("2.9.0".into()))
.build()
.unwrap(),
.term_program_version(Some("2.9.0".into())),
)
.unwrap();
assert_eq!(caps.iterm2_image(), false);
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
ProbeHints::default()
.term_program(Some("iTerm.app".into()))
.term_program_version(Some("2.9.20150512".into()))
.build()
.unwrap(),
.term_program_version(Some("2.9.20150512".into())),
)
.unwrap();
assert_eq!(caps.iterm2_image(), true);
let caps = Capabilities::new_with_hints(
ProbeHintsBuilder::default()
ProbeHints::default()
.term_program(Some("iTerm.app".into()))
.term_program_version(Some("3.2.0beta5".into()))
.build()
.unwrap(),
.term_program_version(Some("3.2.0beta5".into())),
)
.unwrap();
assert_eq!(caps.iterm2_image(), true);

View File

@ -46,6 +46,7 @@ pub mod input;
pub mod istty;
pub mod keymap;
pub mod lineedit;
mod macros;
mod readbuf;
pub mod render;
pub mod surface;

View File

@ -34,12 +34,11 @@
//! Ctrl-W | Delete word leading up to cursor
//! Alt-b, Alt-Left | Move the cursor backwards one word
//! Alt-f, Alt-Right | Move the cursor forwards one word
use crate::caps::{Capabilities, ProbeHintsBuilder};
use crate::caps::{Capabilities, ProbeHints};
use crate::cell::unicode_column_width;
use crate::input::{InputEvent, KeyCode, KeyEvent, Modifiers};
use crate::surface::{Change, Position};
use crate::terminal::{new_terminal, Terminal};
use anyhow::Error;
use unicode_segmentation::GraphemeCursor;
mod actions;
@ -118,14 +117,12 @@ impl<T: Terminal> LineEditor<T> {
/// editor:
///
/// ```no_run
/// use termwiz::caps::{Capabilities, ProbeHintsBuilder};
/// use termwiz::caps::{Capabilities, ProbeHints};
/// use termwiz::terminal::new_terminal;
/// use anyhow::Error;
/// // Disable mouse input in the line editor
/// let hints = ProbeHintsBuilder::new_from_env()
/// .mouse_reporting(Some(false))
/// .build()
/// .map_err(Error::msg)?;
/// let hints = ProbeHints::new_from_env()
/// .mouse_reporting(Some(false));
/// let caps = Capabilities::new_with_hints(hints)?;
/// let terminal = new_terminal(caps)?;
/// # Ok::<(), Error>(())
@ -561,10 +558,7 @@ impl<T: Terminal> LineEditor<T> {
/// Create a `Terminal` with the recommended settings, and use that
/// to create a `LineEditor` instance.
pub fn line_editor() -> anyhow::Result<LineEditor<impl Terminal>> {
let hints = ProbeHintsBuilder::new_from_env()
.mouse_reporting(Some(false))
.build()
.map_err(Error::msg)?;
let hints = ProbeHints::new_from_env().mouse_reporting(Some(false));
let caps = Capabilities::new_with_hints(hints)?;
let terminal = new_terminal(caps)?;
Ok(LineEditor::new(terminal))

30
termwiz/src/macros.rs Normal file
View File

@ -0,0 +1,30 @@
#[doc(hidden)]
#[macro_export]
macro_rules! builder {
(
$( #[ $( $meta:tt )* ] )*
$vis:vis struct $name:ident {
$(
$( #[doc=$doc:expr] )*
$field:ident : $type:ty,
)*
}
) => {
$( #[ $( $meta )* ] )*
$vis struct $name {
$(
$( #[doc=$doc] )*
$field : $type,
)*
}
impl $name {
$(
pub fn $field(mut self, value: $type) -> Self {
self.$field = value;
self
}
)*
}
}
}

View File

@ -671,7 +671,7 @@ impl TerminfoRenderer {
#[cfg(all(test, unix))]
mod test {
use super::*;
use crate::caps::ProbeHintsBuilder;
use crate::caps::ProbeHints;
use crate::color::{AnsiColor, ColorAttribute, RgbColor};
use crate::escape::parser::Parser;
use crate::escape::{Action, Esc, EscCode};
@ -692,24 +692,14 @@ mod test {
// Load our own compiled data so that the tests have an
// environment that doesn't vary machine by machine.
let data = include_bytes!("../../data/xterm-256color");
Capabilities::new_with_hints(
ProbeHintsBuilder::default()
.terminfo_db(Some(
Capabilities::new_with_hints(ProbeHints::default().terminfo_db(Some(
terminfo::Database::from_buffer(data.as_ref()).unwrap(),
))
.build()
.unwrap(),
)
)))
.unwrap()
}
fn no_terminfo_all_enabled() -> Capabilities {
Capabilities::new_with_hints(
ProbeHintsBuilder::default()
.color_level(Some(ColorLevel::TrueColor))
.build()
.unwrap(),
)
Capabilities::new_with_hints(ProbeHints::default().color_level(Some(ColorLevel::TrueColor)))
.unwrap()
}