mirror of
https://github.com/wez/wezterm.git
synced 2024-11-26 08:25:50 +03:00
feed unicode version config through to Line for ls-fonts
This makes the reported metrics show correctly for: ``` wezterm -n --config "font=wezterm.font('Noto Sans Mono CJK JP')" \ --config treat_east_asian_ambiguous_width_as_wide=true \ ls-fonts --text ".☆a☆☆☆☆" ``` refs: https://github.com/wez/wezterm/issues/1888
This commit is contained in:
parent
c0cd6b1f29
commit
fb635c4362
@ -510,7 +510,7 @@ mod test {
|
||||
.collect::<Vec<String>>();
|
||||
let n_chunks = chunks.len();
|
||||
for (idx, chunk) in chunks.into_iter().enumerate() {
|
||||
let mut line = Line::from_text(&chunk, &Default::default(), SEQ_ZERO);
|
||||
let mut line = Line::from_text(&chunk, &Default::default(), SEQ_ZERO, None);
|
||||
if idx < n_chunks - 1 {
|
||||
line.set_last_cell_was_wrapped(true, SEQ_ZERO);
|
||||
}
|
||||
@ -877,10 +877,10 @@ mod test {
|
||||
let attr = Default::default();
|
||||
let logical = LogicalLine {
|
||||
physical_lines: vec![
|
||||
Line::from_text("hello", &attr, SEQ_ZERO),
|
||||
Line::from_text("yo", &attr, SEQ_ZERO),
|
||||
Line::from_text("hello", &attr, SEQ_ZERO, None),
|
||||
Line::from_text("yo", &attr, SEQ_ZERO, None),
|
||||
],
|
||||
logical: Line::from_text("helloyo", &attr, SEQ_ZERO),
|
||||
logical: Line::from_text("helloyo", &attr, SEQ_ZERO, None),
|
||||
first_row: 0,
|
||||
};
|
||||
|
||||
|
@ -13,7 +13,7 @@ fn test_789() {
|
||||
let black = CellAttributes::default()
|
||||
.set_background(AnsiColor::Black)
|
||||
.clone();
|
||||
let mut line = Line::from_text("foo", &black, SEQ_ZERO);
|
||||
let mut line = Line::from_text("foo", &black, SEQ_ZERO, None);
|
||||
line.resize(8, 0);
|
||||
for x in 3..8 {
|
||||
line.set_cell(x, Cell::blank_with_attrs(black.clone()), 0);
|
||||
|
@ -450,7 +450,7 @@ fn test_semantic() {
|
||||
let mut input = CellAttributes::default();
|
||||
input.set_semantic_type(SemanticType::Input);
|
||||
|
||||
let mut prompt_line = Line::from_text("> ls -l ", &output, SEQ_ZERO);
|
||||
let mut prompt_line = Line::from_text("> ls -l ", &output, SEQ_ZERO, None);
|
||||
for i in 0..2 {
|
||||
prompt_line.cells_mut()[i]
|
||||
.attrs_mut()
|
||||
@ -503,11 +503,11 @@ fn test_semantic() {
|
||||
line!(),
|
||||
&term.screen().visible_lines(),
|
||||
&[
|
||||
Line::from_text("hello ", &output, SEQ_ZERO),
|
||||
Line::from_text("there ", &output, SEQ_ZERO),
|
||||
Line::from_text("three ", &output, SEQ_ZERO),
|
||||
Line::from_text("hello ", &output, SEQ_ZERO, None),
|
||||
Line::from_text("there ", &output, SEQ_ZERO, None),
|
||||
Line::from_text("three ", &output, SEQ_ZERO, None),
|
||||
prompt_line,
|
||||
Line::from_text("some file ", &output, SEQ_ZERO),
|
||||
Line::from_text("some file ", &output, SEQ_ZERO, None),
|
||||
],
|
||||
Compare::TEXT | Compare::ATTRS,
|
||||
);
|
||||
@ -1121,7 +1121,7 @@ fn test_hyperlinks() {
|
||||
line!(),
|
||||
&term.screen().visible_lines(),
|
||||
&[
|
||||
Line::from_text("hello", &linked, SEQ_ZERO),
|
||||
Line::from_text("hello", &linked, SEQ_ZERO, None),
|
||||
" ".into(),
|
||||
" ".into(),
|
||||
],
|
||||
@ -1140,7 +1140,7 @@ fn test_hyperlinks() {
|
||||
&term.screen().visible_lines(),
|
||||
&[
|
||||
Line::from_text_with_wrapped_last_col("hello", &linked, SEQ_ZERO),
|
||||
Line::from_text("hey!!", &linked, SEQ_ZERO),
|
||||
Line::from_text("hey!!", &linked, SEQ_ZERO, None),
|
||||
" ".into(),
|
||||
],
|
||||
Compare::TEXT | Compare::ATTRS,
|
||||
@ -1155,7 +1155,7 @@ fn test_hyperlinks() {
|
||||
term.soft_reset();
|
||||
term.print("00t");
|
||||
|
||||
let mut partial_line = Line::from_text("wo00t", &CellAttributes::default(), SEQ_ZERO);
|
||||
let mut partial_line = Line::from_text("wo00t", &CellAttributes::default(), SEQ_ZERO, None);
|
||||
partial_line.set_cell(
|
||||
0,
|
||||
Cell::new(
|
||||
|
@ -489,7 +489,7 @@ where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let text = String::deserialize(deserializer)?;
|
||||
Ok(TeenyString::from_str(&text, None))
|
||||
Ok(TeenyString::from_str(&text, None, None))
|
||||
}
|
||||
|
||||
#[cfg(feature = "use_serde")]
|
||||
@ -577,7 +577,11 @@ impl TeenyString {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(s: &str, width: Option<usize>) -> Self {
|
||||
pub fn from_str(
|
||||
s: &str,
|
||||
width: Option<usize>,
|
||||
unicode_version: Option<UnicodeVersion>,
|
||||
) -> Self {
|
||||
// De-fang the input text such that it has no special meaning
|
||||
// to a terminal. All control and movement characters are rewritten
|
||||
// as a space.
|
||||
@ -596,7 +600,7 @@ impl TeenyString {
|
||||
|
||||
let bytes = s.as_bytes();
|
||||
let len = bytes.len();
|
||||
let width = width.unwrap_or_else(|| grapheme_column_width(s, None));
|
||||
let width = width.unwrap_or_else(|| grapheme_column_width(s, unicode_version));
|
||||
|
||||
if len < std::mem::size_of::<usize>() {
|
||||
debug_assert!(width < 3);
|
||||
@ -651,7 +655,7 @@ impl TeenyString {
|
||||
|
||||
pub fn from_char(c: char) -> Self {
|
||||
let mut bytes = [0u8; 8];
|
||||
Self::from_str(c.encode_utf8(&mut bytes), None)
|
||||
Self::from_str(c.encode_utf8(&mut bytes), None, None)
|
||||
}
|
||||
|
||||
pub fn width(&self) -> usize {
|
||||
@ -705,7 +709,7 @@ impl std::clone::Clone for TeenyString {
|
||||
if Self::is_marker_bit_set(self.0) {
|
||||
Self(self.0)
|
||||
} else {
|
||||
Self::from_str(self.str(), None)
|
||||
Self::from_str(self.str(), None, None)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -791,8 +795,12 @@ impl Cell {
|
||||
/// over. This function technically allows for an arbitrary string to
|
||||
/// be passed but it should not be used to hold strings other than
|
||||
/// graphemes.
|
||||
pub fn new_grapheme(text: &str, attrs: CellAttributes) -> Self {
|
||||
let storage = TeenyString::from_str(text, None);
|
||||
pub fn new_grapheme(
|
||||
text: &str,
|
||||
attrs: CellAttributes,
|
||||
unicode_version: Option<UnicodeVersion>,
|
||||
) -> Self {
|
||||
let storage = TeenyString::from_str(text, None, unicode_version);
|
||||
|
||||
Self {
|
||||
text: storage,
|
||||
@ -801,7 +809,7 @@ impl Cell {
|
||||
}
|
||||
|
||||
pub fn new_grapheme_with_width(text: &str, width: usize, attrs: CellAttributes) -> Self {
|
||||
let storage = TeenyString::from_str(text, Some(width));
|
||||
let storage = TeenyString::from_str(text, Some(width), None);
|
||||
Self {
|
||||
text: storage,
|
||||
attrs,
|
||||
@ -955,7 +963,7 @@ mod test {
|
||||
let s = TeenyString::from_char('a');
|
||||
assert_eq!(s.as_bytes(), &[b'a']);
|
||||
|
||||
let longer = TeenyString::from_str("hellothere", None);
|
||||
let longer = TeenyString::from_str("hellothere", None, None);
|
||||
assert_eq!(longer.as_bytes(), b"hellothere");
|
||||
|
||||
assert_eq!(
|
||||
@ -984,7 +992,7 @@ mod test {
|
||||
}
|
||||
|
||||
for g in &["", " ", "\n", "\r", "\t", "\r\n"] {
|
||||
let cell = Cell::new_grapheme(g, CellAttributes::default());
|
||||
let cell = Cell::new_grapheme(g, CellAttributes::default(), None);
|
||||
assert_eq!(cell.str(), " ");
|
||||
}
|
||||
}
|
||||
@ -1006,6 +1014,7 @@ mod test {
|
||||
let cell = Cell::new_grapheme(
|
||||
women_holding_hands_dark_skin_tone_medium_light_skin_tone,
|
||||
CellAttributes::default(),
|
||||
None,
|
||||
);
|
||||
assert_eq!(
|
||||
cell.str(),
|
||||
@ -1063,7 +1072,7 @@ mod test {
|
||||
vec!["x".to_string(), "\u{3000}".to_string(), "x".to_string()],
|
||||
);
|
||||
|
||||
let c = Cell::new_grapheme("\u{3000}", CellAttributes::blank());
|
||||
let c = Cell::new_grapheme("\u{3000}", CellAttributes::blank(), None);
|
||||
assert_eq!(c.width(), 2);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::cell::{Cell, CellAttributes, SemanticType};
|
||||
use crate::cell::{Cell, CellAttributes, SemanticType, UnicodeVersion};
|
||||
use crate::cellcluster::CellCluster;
|
||||
use crate::hyperlink::Rule;
|
||||
use crate::surface::{Change, SequenceNo, SEQ_ZERO};
|
||||
@ -120,11 +120,16 @@ impl Line {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_text(s: &str, attrs: &CellAttributes, seqno: SequenceNo) -> Line {
|
||||
pub fn from_text(
|
||||
s: &str,
|
||||
attrs: &CellAttributes,
|
||||
seqno: SequenceNo,
|
||||
unicode_version: Option<UnicodeVersion>,
|
||||
) -> Line {
|
||||
let mut cells = Vec::new();
|
||||
|
||||
for sub in s.graphemes(true) {
|
||||
let cell = Cell::new_grapheme(sub, attrs.clone());
|
||||
let cell = Cell::new_grapheme(sub, attrs.clone(), unicode_version);
|
||||
let width = cell.width();
|
||||
cells.push(cell);
|
||||
for _ in 1..width {
|
||||
@ -145,7 +150,7 @@ impl Line {
|
||||
attrs: &CellAttributes,
|
||||
seqno: SequenceNo,
|
||||
) -> Line {
|
||||
let mut line = Self::from_text(s, attrs, seqno);
|
||||
let mut line = Self::from_text(s, attrs, seqno, None);
|
||||
line.cells
|
||||
.last_mut()
|
||||
.map(|cell| cell.attrs_mut().set_wrapped(true));
|
||||
@ -445,6 +450,7 @@ impl Line {
|
||||
Some(ref link) if link.is_implicit() => Some(Cell::new_grapheme(
|
||||
cell.str(),
|
||||
cell.attrs().clone().set_hyperlink(None).clone(),
|
||||
None,
|
||||
)),
|
||||
_ => None,
|
||||
};
|
||||
@ -661,7 +667,7 @@ impl Line {
|
||||
seqno: SequenceNo,
|
||||
) {
|
||||
for (i, c) in text.graphemes(true).enumerate() {
|
||||
let cell = Cell::new_grapheme(c, attr.clone());
|
||||
let cell = Cell::new_grapheme(c, attr.clone(), None);
|
||||
let width = cell.width();
|
||||
self.set_cell(i + start_idx, cell, seqno);
|
||||
|
||||
@ -922,7 +928,7 @@ impl Line {
|
||||
|
||||
impl<'a> From<&'a str> for Line {
|
||||
fn from(s: &str) -> Line {
|
||||
Line::from_text(s, &CellAttributes::default(), SEQ_ZERO)
|
||||
Line::from_text(s, &CellAttributes::default(), SEQ_ZERO, None)
|
||||
}
|
||||
}
|
||||
|
||||
@ -953,11 +959,11 @@ mod test {
|
||||
assert_eq!(
|
||||
line.cells().to_vec(),
|
||||
vec![
|
||||
Cell::new_grapheme("❤", CellAttributes::default()),
|
||||
Cell::new_grapheme("❤", CellAttributes::default(), None),
|
||||
Cell::new(' ', CellAttributes::default()), // double width spacer
|
||||
Cell::new_grapheme("😍", CellAttributes::default()),
|
||||
Cell::new_grapheme("😍", CellAttributes::default(), None),
|
||||
Cell::new(' ', CellAttributes::default()), // double width spacer
|
||||
Cell::new_grapheme("🤢", CellAttributes::default()),
|
||||
Cell::new_grapheme("🤢", CellAttributes::default(), None),
|
||||
Cell::new(' ', CellAttributes::default()), // double width spacer
|
||||
Cell::new(' ', CellAttributes::default()),
|
||||
Cell::new('h', hyperlink_attr.clone()),
|
||||
@ -982,7 +988,8 @@ mod test {
|
||||
Cell::new_grapheme(
|
||||
// man: dark skin tone, red hair ZWJ emoji grapheme
|
||||
"\u{1f468}\u{1f3fe}\u{200d}\u{1f9b0}",
|
||||
CellAttributes::default()
|
||||
CellAttributes::default(),
|
||||
None,
|
||||
),
|
||||
Cell::new(' ', CellAttributes::default()), // double width spacer
|
||||
Cell::new(' ', CellAttributes::default()),
|
||||
|
@ -442,7 +442,7 @@ impl Surface {
|
||||
self.xpos = 0;
|
||||
}
|
||||
|
||||
let cell = Cell::new_grapheme(g, self.attributes.clone());
|
||||
let cell = Cell::new_grapheme(g, self.attributes.clone(), None);
|
||||
// the max(1) here is to ensure that we advance to the next cell
|
||||
// position for zero-width graphemes. We want to make sure that
|
||||
// they occupy a cell so that we can re-emit them when we output them.
|
||||
|
@ -248,7 +248,7 @@ impl RenderableInner {
|
||||
.set_underline(Underline::Double)
|
||||
.clone();
|
||||
|
||||
let text_line = Line::from_text(text, &attrs, SEQ_ZERO);
|
||||
let text_line = Line::from_text(text, &attrs, SEQ_ZERO, None);
|
||||
|
||||
if row == 0 {
|
||||
for cell in text_line.cells() {
|
||||
|
@ -16,7 +16,7 @@ use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use structopt::StructOpt;
|
||||
use termwiz::cell::CellAttributes;
|
||||
use termwiz::cell::{CellAttributes, UnicodeVersion};
|
||||
use termwiz::surface::{Line, SEQ_ZERO};
|
||||
use wezterm_bidi::Direction;
|
||||
use wezterm_client::domain::{ClientDomain, ClientDomainConfig};
|
||||
@ -701,8 +701,18 @@ pub fn run_ls_fonts(config: config::ConfigHandle, cmd: &LsFontsCommand) -> anyho
|
||||
None
|
||||
};
|
||||
|
||||
let unicode_version = UnicodeVersion {
|
||||
version: config.unicode_version,
|
||||
ambiguous_are_wide: config.treat_east_asian_ambiguous_width_as_wide,
|
||||
};
|
||||
|
||||
if let Some(text) = &cmd.text {
|
||||
let line = Line::from_text(text, &CellAttributes::default(), SEQ_ZERO);
|
||||
let line = Line::from_text(
|
||||
text,
|
||||
&CellAttributes::default(),
|
||||
SEQ_ZERO,
|
||||
Some(unicode_version),
|
||||
);
|
||||
let cell_clusters = line.cluster(bidi_hint);
|
||||
let ft_lib = wezterm_font::ftwrap::Library::new()?;
|
||||
|
||||
|
@ -151,7 +151,7 @@ mod test {
|
||||
T: Texture2d,
|
||||
T: std::fmt::Debug,
|
||||
{
|
||||
let line = Line::from_text(text, &CellAttributes::default(), SEQ_ZERO);
|
||||
let line = Line::from_text(text, &CellAttributes::default(), SEQ_ZERO, None);
|
||||
eprintln!("{:?}", line);
|
||||
let cell_clusters = line.cluster(None);
|
||||
assert_eq!(cell_clusters.len(), 1);
|
||||
@ -294,7 +294,7 @@ mod test {
|
||||
);
|
||||
let style = TextStyle::default();
|
||||
let font = fonts.resolve_font(&style).unwrap();
|
||||
let line = Line::from_text(&text, &CellAttributes::default(), SEQ_ZERO);
|
||||
let line = Line::from_text(&text, &CellAttributes::default(), SEQ_ZERO, None);
|
||||
let cell_clusters = line.cluster(None);
|
||||
let cluster = &cell_clusters[0];
|
||||
let presentation_width = PresentationWidth::with_cluster(&cluster);
|
||||
|
@ -161,7 +161,7 @@ impl TabBarState {
|
||||
line: Line::with_width(1, SEQ_ZERO),
|
||||
items: vec![TabEntry {
|
||||
item: TabBarItem::None,
|
||||
title: Line::from_text(" ", &CellAttributes::blank(), 1),
|
||||
title: Line::from_text(" ", &CellAttributes::blank(), 1, None),
|
||||
x: 1,
|
||||
width: 1,
|
||||
}],
|
||||
@ -386,7 +386,7 @@ fn parse_status_text(text: &str, default_cell: CellAttributes) -> Line {
|
||||
|
||||
fn flush_print(buf: &mut String, cells: &mut Vec<Cell>, pen: &CellAttributes) {
|
||||
for g in unicode_segmentation::UnicodeSegmentation::graphemes(buf.as_str(), true) {
|
||||
let cell = Cell::new_grapheme(g, pen.clone());
|
||||
let cell = Cell::new_grapheme(g, pen.clone(), None);
|
||||
let width = cell.width();
|
||||
cells.push(cell);
|
||||
for _ in 1..width {
|
||||
|
Loading…
Reference in New Issue
Block a user