105 lines
2.2 KiB
Rust
105 lines
2.2 KiB
Rust
use std::{
|
|
fmt,
|
|
ops::Index,
|
|
slice::{self, SliceIndex},
|
|
};
|
|
|
|
use crate::{
|
|
highlight::LineHighlight,
|
|
text::{Span, Text, TextLike, TextLikeMut},
|
|
};
|
|
|
|
pub struct Line {
|
|
pub text: Text,
|
|
pub highlight: LineHighlight,
|
|
pub highlight_dirty: bool,
|
|
}
|
|
|
|
impl Line {
|
|
pub fn new() -> Self {
|
|
Self::from(Text::new())
|
|
}
|
|
|
|
#[inline]
|
|
pub fn len(&self) -> usize {
|
|
self.text.len()
|
|
}
|
|
|
|
#[inline]
|
|
pub fn is_empty(&self) -> bool {
|
|
self.text.is_empty()
|
|
}
|
|
}
|
|
|
|
impl TextLike for Line {
|
|
type Iter<'a>
|
|
= slice::Iter<'a, char>
|
|
where
|
|
Self: 'a;
|
|
type Span<'a>
|
|
= Span<'a>
|
|
where
|
|
Self: 'a;
|
|
|
|
#[inline]
|
|
fn display_width(&self, tab_width: usize) -> usize {
|
|
self.text.display_width(tab_width)
|
|
}
|
|
#[inline]
|
|
fn iter(&self) -> Self::Iter<'_> {
|
|
self.text.iter()
|
|
}
|
|
#[inline]
|
|
fn span<R: SliceIndex<[char], Output = [char]>>(&self, range: R) -> Self::Span<'_> {
|
|
self.text.span(range)
|
|
}
|
|
#[inline]
|
|
fn skip_to_width(&self, offset: usize, tab_width: usize) -> (Self::Span<'_>, usize, usize) {
|
|
self.text.skip_to_width(offset, tab_width)
|
|
}
|
|
}
|
|
|
|
impl TextLikeMut for Line {
|
|
fn split_off(&mut self, at: usize) -> Self {
|
|
let tail = self.text.split_off(at);
|
|
self.highlight_dirty = true;
|
|
Self::from(tail)
|
|
}
|
|
fn extend(&mut self, other: Self) {
|
|
self.text.extend(other.text);
|
|
self.highlight_dirty = true;
|
|
}
|
|
fn remove(&mut self, at: usize) {
|
|
self.text.remove(at);
|
|
self.highlight_dirty = true;
|
|
}
|
|
fn insert(&mut self, at: usize, ch: char) {
|
|
self.text.insert(at, ch);
|
|
self.highlight_dirty = true;
|
|
}
|
|
}
|
|
|
|
impl From<Text> for Line {
|
|
fn from(text: Text) -> Self {
|
|
Self {
|
|
text,
|
|
highlight: LineHighlight::default(),
|
|
highlight_dirty: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Index<usize> for Line {
|
|
type Output = char;
|
|
|
|
fn index(&self, index: usize) -> &Self::Output {
|
|
&self.text[index]
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Line {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
fmt::Display::fmt(&self.text, f)
|
|
}
|
|
}
|