diff --git a/src/buffer.rs b/src/buffer.rs index 73975d5..b8a8be2 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -21,11 +21,11 @@ use std::io::Write; use std::ops::Range; use std::sync::Arc; -use crossterm::{cursor, ExecutableCommand}; +use crossterm::{cursor, ExecutableCommand, QueueableCommand}; use parking_lot::Mutex; use ropey::Rope; use syntect::easy::ScopeRangeIterator; -use syntect::parsing::{ParseState, Scope, ScopeStack, SyntaxSet}; +use syntect::parsing::{BasicScopeStackOp, ParseState, Scope, ScopeStack, SyntaxSet}; use crate::theme::{Style, StyleStore}; use crate::{Cursor, Direction}; @@ -33,7 +33,7 @@ use crate::{Cursor, Direction}; #[derive(Clone, Debug)] pub struct Buffer { styles: Arc>, - pub text: Rope, + text: Rope, syntax_set: Arc, parser: ParseState, style_dirty: bool, @@ -41,6 +41,12 @@ pub struct Buffer { styled: Vec)>>, } +impl AsRef for Buffer { + fn as_ref(&self) -> &Rope { + &self.text + } +} + impl Buffer { pub fn from_str(styles: Arc>, text: &str) -> Self { let syntax_set = SyntaxSet::load_defaults_nonewlines(); @@ -68,7 +74,7 @@ impl Buffer { cols: u16, rows: u16, scroll: Cursor, - out: &mut (impl ExecutableCommand + Write), + out: &mut impl Write, ) -> crossterm::Result { self.parse(); @@ -78,8 +84,9 @@ impl Buffer { let gutter_width = linenr_width + 1; let text_width = cols as usize - gutter_width as usize; - out.execute(cursor::MoveTo(0, 0))?; + out.queue(cursor::MoveTo(0, 0))?; + let mut line_buf = Vec::::with_capacity(text_width); for (row, line) in (0..rows).zip(self.text.lines_at(scroll.line)) { // only the last line is empty and should be skipped if line.len_chars() == 0 { @@ -92,6 +99,7 @@ impl Buffer { let lhs = scroll.column; let width = line.len_chars(); + line_buf.clear(); if lhs < width { let window = text_width.min(width - lhs); let rhs = lhs + window; @@ -101,7 +109,7 @@ impl Buffer { if range.start < range.end { // this range is in view so display let content = line.slice(range.clone()); - style.print_styled(out, content)?; + style.print_styled(&mut line_buf, content)?; } if range.end >= rhs { @@ -111,7 +119,8 @@ impl Buffer { } } - out.execute(cursor::MoveToNextLine(1))?; + out.write_all(&line_buf)?; + out.queue(cursor::MoveToNextLine(1))?; } Ok(gutter_width) @@ -141,6 +150,11 @@ impl Buffer { let mut parser = self.parser.clone(); let mut line_buf = String::new(); let mut stack = ScopeStack::new(); + let mut styled_buf = Vec::new(); + + let mut style_stack = Vec::