forked from mars/breed
Faster syntax highlighting with a style stack
This commit is contained in:
parent
4f6f17d066
commit
b351dbbcbb
|
@ -25,7 +25,7 @@ use crossterm::{cursor, ExecutableCommand, QueueableCommand};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use ropey::Rope;
|
use ropey::Rope;
|
||||||
use syntect::easy::ScopeRangeIterator;
|
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::theme::{Style, StyleStore};
|
||||||
use crate::{Cursor, Direction};
|
use crate::{Cursor, Direction};
|
||||||
|
@ -150,6 +150,8 @@ impl Buffer {
|
||||||
let mut parser = self.parser.clone();
|
let mut parser = self.parser.clone();
|
||||||
let mut line_buf = String::new();
|
let mut line_buf = String::new();
|
||||||
let mut stack = ScopeStack::new();
|
let mut stack = ScopeStack::new();
|
||||||
|
let mut style_stack = Vec::<Style>::new();
|
||||||
|
let mut styled_buf = Vec::new();
|
||||||
for line in self.text.lines() {
|
for line in self.text.lines() {
|
||||||
// display line to a pre-allocated buffer for fast parsing
|
// display line to a pre-allocated buffer for fast parsing
|
||||||
line_buf.clear();
|
line_buf.clear();
|
||||||
|
@ -161,26 +163,31 @@ impl Buffer {
|
||||||
let stack_ops = parser.parse_line(&line_buf, &self.syntax_set).unwrap();
|
let stack_ops = parser.parse_line(&line_buf, &self.syntax_set).unwrap();
|
||||||
|
|
||||||
// queue the operations on the stack
|
// queue the operations on the stack
|
||||||
let mut line = Vec::new();
|
|
||||||
let range_iter = ScopeRangeIterator::new(&stack_ops, &line_buf);
|
let range_iter = ScopeRangeIterator::new(&stack_ops, &line_buf);
|
||||||
|
styled_buf.clear();
|
||||||
for (range, op) in range_iter {
|
for (range, op) in range_iter {
|
||||||
stack.apply(&op).unwrap();
|
stack
|
||||||
|
.apply_with_hook(&op, |op, _scopes| match op {
|
||||||
|
BasicScopeStackOp::Push(scope) => {
|
||||||
|
let scope = scope.build_string();
|
||||||
|
let style = styles.get_scope(&scope);
|
||||||
|
style_stack.push(style);
|
||||||
|
}
|
||||||
|
BasicScopeStackOp::Pop => {
|
||||||
|
style_stack.pop();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
if range.start == range.end {
|
if range.start == range.end {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut style = Style::default();
|
let style = style_stack.last().cloned().unwrap_or_default();
|
||||||
for scope in stack.scopes.clone() {
|
styled_buf.push((style, range));
|
||||||
// TODO docs say that build_string "shouldn't be done frequently"
|
|
||||||
let scope = scope.build_string();
|
|
||||||
style.apply(&styles.get_scope(&scope));
|
|
||||||
}
|
|
||||||
|
|
||||||
line.push((style, range));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.styled.push(line);
|
self.styled.push(styled_buf.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.style_dirty = false;
|
self.style_dirty = false;
|
||||||
|
|
Loading…
Reference in New Issue