mirror of
https://github.com/wez/wezterm.git
synced 2024-11-27 12:23:46 +03:00
move CellCluster to termwiz
This commit is contained in:
parent
d7943681de
commit
2c7a27c42a
@ -1,5 +1,6 @@
|
||||
use std::ops::Range;
|
||||
use std::str;
|
||||
use termwiz::cellcluster::CellCluster;
|
||||
use termwiz::hyperlink::Rule;
|
||||
|
||||
use super::*;
|
||||
@ -19,41 +20,6 @@ pub struct Line {
|
||||
has_implicit_hyperlinks: ImplicitHyperlinks,
|
||||
}
|
||||
|
||||
/// A `CellCluster` is another representation of a Line.
|
||||
/// A `Vec<CellCluster>` is produced by walking through the Cells in
|
||||
/// a line and collecting succesive Cells with the same attributes
|
||||
/// together into a `CellCluster` instance. Additional metadata to
|
||||
/// aid in font rendering is also collected.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CellCluster {
|
||||
pub attrs: CellAttributes,
|
||||
pub text: String,
|
||||
pub byte_to_cell_idx: Vec<usize>,
|
||||
}
|
||||
|
||||
impl CellCluster {
|
||||
/// Start off a new cluster with some initial data
|
||||
fn new(attrs: CellAttributes, text: &str, cell_idx: usize) -> CellCluster {
|
||||
let mut idx = Vec::new();
|
||||
for _ in 0..text.len() {
|
||||
idx.push(cell_idx);
|
||||
}
|
||||
CellCluster {
|
||||
attrs,
|
||||
text: text.into(),
|
||||
byte_to_cell_idx: idx,
|
||||
}
|
||||
}
|
||||
|
||||
/// Add to this cluster
|
||||
fn add(&mut self, text: &str, cell_idx: usize) {
|
||||
for _ in 0..text.len() {
|
||||
self.byte_to_cell_idx.push(cell_idx);
|
||||
}
|
||||
self.text.push_str(text);
|
||||
}
|
||||
}
|
||||
|
||||
impl Line {
|
||||
/// Create a new line with the specified number of columns.
|
||||
/// Each cell has the default attributes.
|
||||
@ -197,39 +163,8 @@ impl Line {
|
||||
s
|
||||
}
|
||||
|
||||
/// Compute the list of CellClusters for this line
|
||||
pub fn cluster(&self) -> Vec<CellCluster> {
|
||||
let mut last_cluster = None;
|
||||
let mut clusters = Vec::new();
|
||||
|
||||
for (cell_idx, c) in self.visible_cells() {
|
||||
let cell_str = c.str();
|
||||
|
||||
last_cluster = match last_cluster.take() {
|
||||
None => {
|
||||
// Start new cluster
|
||||
Some(CellCluster::new(c.attrs().clone(), cell_str, cell_idx))
|
||||
}
|
||||
Some(mut last) => {
|
||||
if last.attrs != *c.attrs() {
|
||||
// Flush pending cluster and start a new one
|
||||
clusters.push(last);
|
||||
Some(CellCluster::new(c.attrs().clone(), cell_str, cell_idx))
|
||||
} else {
|
||||
// Add to current cluster
|
||||
last.add(cell_str, cell_idx);
|
||||
Some(last)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(cluster) = last_cluster {
|
||||
// Don't forget to include any pending cluster on the final step!
|
||||
clusters.push(cluster);
|
||||
}
|
||||
|
||||
clusters
|
||||
CellCluster::make_cluster(self.visible_cells())
|
||||
}
|
||||
|
||||
pub fn from_text(s: &str, attrs: &CellAttributes) -> Line {
|
||||
|
72
termwiz/src/cellcluster.rs
Normal file
72
termwiz/src/cellcluster.rs
Normal file
@ -0,0 +1,72 @@
|
||||
use cell::{Cell, CellAttributes};
|
||||
|
||||
/// A `CellCluster` is another representation of a Line.
|
||||
/// A `Vec<CellCluster>` is produced by walking through the Cells in
|
||||
/// a line and collecting succesive Cells with the same attributes
|
||||
/// together into a `CellCluster` instance. Additional metadata to
|
||||
/// aid in font rendering is also collected.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CellCluster {
|
||||
pub attrs: CellAttributes,
|
||||
pub text: String,
|
||||
pub byte_to_cell_idx: Vec<usize>,
|
||||
}
|
||||
|
||||
impl CellCluster {
|
||||
/// Compute the list of CellClusters from a set of visible cells.
|
||||
/// The input is typically the result of calling `Line::visible_cells()`.
|
||||
pub fn make_cluster<'a>(iter: impl Iterator<Item = (usize, &'a Cell)>) -> Vec<CellCluster> {
|
||||
let mut last_cluster = None;
|
||||
let mut clusters = Vec::new();
|
||||
|
||||
for (cell_idx, c) in iter {
|
||||
let cell_str = c.str();
|
||||
|
||||
last_cluster = match last_cluster.take() {
|
||||
None => {
|
||||
// Start new cluster
|
||||
Some(CellCluster::new(c.attrs().clone(), cell_str, cell_idx))
|
||||
}
|
||||
Some(mut last) => {
|
||||
if last.attrs != *c.attrs() {
|
||||
// Flush pending cluster and start a new one
|
||||
clusters.push(last);
|
||||
Some(CellCluster::new(c.attrs().clone(), cell_str, cell_idx))
|
||||
} else {
|
||||
// Add to current cluster
|
||||
last.add(cell_str, cell_idx);
|
||||
Some(last)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(cluster) = last_cluster {
|
||||
// Don't forget to include any pending cluster on the final step!
|
||||
clusters.push(cluster);
|
||||
}
|
||||
|
||||
clusters
|
||||
}
|
||||
|
||||
/// Start off a new cluster with some initial data
|
||||
fn new(attrs: CellAttributes, text: &str, cell_idx: usize) -> CellCluster {
|
||||
let mut idx = Vec::new();
|
||||
for _ in 0..text.len() {
|
||||
idx.push(cell_idx);
|
||||
}
|
||||
CellCluster {
|
||||
attrs,
|
||||
text: text.into(),
|
||||
byte_to_cell_idx: idx,
|
||||
}
|
||||
}
|
||||
|
||||
/// Add to this cluster
|
||||
fn add(&mut self, text: &str, cell_idx: usize) {
|
||||
for _ in 0..text.len() {
|
||||
self.byte_to_cell_idx.push(cell_idx);
|
||||
}
|
||||
self.text.push_str(text);
|
||||
}
|
||||
}
|
@ -67,6 +67,7 @@ extern crate unicode_width;
|
||||
|
||||
pub mod caps;
|
||||
pub mod cell;
|
||||
pub mod cellcluster;
|
||||
pub mod color;
|
||||
pub mod escape;
|
||||
pub mod hyperlink;
|
||||
|
@ -1,4 +1,5 @@
|
||||
use cell::{Cell, CellAttributes};
|
||||
use cellcluster::CellCluster;
|
||||
use hyperlink::Rule;
|
||||
use range::in_range;
|
||||
use std::rc::Rc;
|
||||
@ -217,6 +218,10 @@ impl Line {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn cluster(&self) -> Vec<CellCluster> {
|
||||
CellCluster::make_cluster(self.visible_cells())
|
||||
}
|
||||
|
||||
pub fn cells(&self) -> &[Cell] {
|
||||
&self.cells
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user