Reuse syntaxes and themes lazily in iced_highlighter

This commit is contained in:
Héctor Ramón Jiménez 2023-09-19 21:57:09 +02:00
parent d9fbecf0d8
commit a9ee8f62fd
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
2 changed files with 26 additions and 26 deletions

View file

@ -13,4 +13,5 @@ keywords.workspace = true
[dependencies] [dependencies]
iced_core.workspace = true iced_core.workspace = true
once_cell.workspace = true
syntect.workspace = true syntect.workspace = true

View file

@ -3,20 +3,26 @@ use iced_core as core;
use crate::core::text::highlighter::{self, Format}; use crate::core::text::highlighter::{self, Format};
use crate::core::{Color, Font}; use crate::core::{Color, Font};
use once_cell::sync::Lazy;
use std::ops::Range; use std::ops::Range;
use syntect::highlighting; use syntect::highlighting;
use syntect::parsing; use syntect::parsing;
static SYNTAXES: Lazy<parsing::SyntaxSet> =
Lazy::new(|| parsing::SyntaxSet::load_defaults_nonewlines());
static THEMES: Lazy<highlighting::ThemeSet> =
Lazy::new(|| highlighting::ThemeSet::load_defaults());
const LINES_PER_SNAPSHOT: usize = 50;
pub struct Highlighter { pub struct Highlighter {
syntaxes: parsing::SyntaxSet, syntax: &'static parsing::SyntaxReference,
syntax: parsing::SyntaxReference, highlighter: highlighting::Highlighter<'static>,
theme: highlighting::Theme,
caches: Vec<(parsing::ParseState, parsing::ScopeStack)>, caches: Vec<(parsing::ParseState, parsing::ScopeStack)>,
current_line: usize, current_line: usize,
} }
const LINES_PER_SNAPSHOT: usize = 50;
impl highlighter::Highlighter for Highlighter { impl highlighter::Highlighter for Highlighter {
type Settings = Settings; type Settings = Settings;
type Highlight = Highlight; type Highlight = Highlight;
@ -25,40 +31,33 @@ impl highlighter::Highlighter for Highlighter {
Box<dyn Iterator<Item = (Range<usize>, Self::Highlight)> + 'a>; Box<dyn Iterator<Item = (Range<usize>, Self::Highlight)> + 'a>;
fn new(settings: &Self::Settings) -> Self { fn new(settings: &Self::Settings) -> Self {
let syntaxes = parsing::SyntaxSet::load_defaults_nonewlines(); let syntax = SYNTAXES
let syntax = syntaxes
.find_syntax_by_token(&settings.extension) .find_syntax_by_token(&settings.extension)
.unwrap_or_else(|| syntaxes.find_syntax_plain_text()); .unwrap_or_else(|| SYNTAXES.find_syntax_plain_text());
let theme = highlighting::ThemeSet::load_defaults() let highlighter = highlighting::Highlighter::new(
.themes &THEMES.themes[settings.theme.key()],
.remove(settings.theme.key()) );
.unwrap();
let parser = parsing::ParseState::new(syntax); let parser = parsing::ParseState::new(syntax);
let stack = parsing::ScopeStack::new(); let stack = parsing::ScopeStack::new();
Highlighter { Highlighter {
syntax: syntax.clone(), syntax,
syntaxes, highlighter,
theme,
caches: vec![(parser, stack)], caches: vec![(parser, stack)],
current_line: 0, current_line: 0,
} }
} }
fn update(&mut self, new_settings: &Self::Settings) { fn update(&mut self, new_settings: &Self::Settings) {
self.syntax = self self.syntax = SYNTAXES
.syntaxes
.find_syntax_by_token(&new_settings.extension) .find_syntax_by_token(&new_settings.extension)
.unwrap_or_else(|| self.syntaxes.find_syntax_plain_text()) .unwrap_or_else(|| SYNTAXES.find_syntax_plain_text());
.clone();
self.theme = highlighting::ThemeSet::load_defaults() self.highlighter = highlighting::Highlighter::new(
.themes &THEMES.themes[new_settings.theme.key()],
.remove(new_settings.theme.key()) );
.unwrap();
// Restart the highlighter // Restart the highlighter
self.change_line(0); self.change_line(0);
@ -99,9 +98,9 @@ impl highlighter::Highlighter for Highlighter {
let (parser, stack) = let (parser, stack) =
self.caches.last_mut().expect("Caches must not be empty"); self.caches.last_mut().expect("Caches must not be empty");
let ops = parser.parse_line(line, &self.syntaxes).unwrap_or_default(); let ops = parser.parse_line(line, &SYNTAXES).unwrap_or_default();
let highlighter = highlighting::Highlighter::new(&self.theme); let highlighter = &self.highlighter;
Box::new( Box::new(
ScopeRangeIterator { ScopeRangeIterator {