Mutex comes from tex and we don't want any

This commit is contained in:
Laurenz 2022-01-27 23:07:10 +01:00
parent 4f66907d08
commit c183ed3c15
3 changed files with 45 additions and 75 deletions

View File

@ -30,7 +30,6 @@ use std::collections::HashMap;
use std::io; use std::io;
use std::mem; use std::mem;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Mutex;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use syntect::easy::HighlightLines; use syntect::easy::HighlightLines;
@ -43,7 +42,7 @@ use crate::diag::{At, Error, StrResult, Trace, Tracepoint, TypResult};
use crate::geom::{Angle, Fractional, Length, Paint, Relative, RgbaColor}; use crate::geom::{Angle, Fractional, Length, Paint, Relative, RgbaColor};
use crate::image::ImageStore; use crate::image::ImageStore;
use crate::layout::RootNode; use crate::layout::RootNode;
use crate::library::{self, Decoration, TextNode}; use crate::library::{self, DecoLine, TextNode};
use crate::loading::Loader; use crate::loading::Loader;
use crate::parse; use crate::parse;
use crate::source::{SourceId, SourceStore}; use crate::source::{SourceId, SourceStore};
@ -53,12 +52,10 @@ use crate::syntax::{RedNode, Span, Spanned};
use crate::util::{EcoString, RefMutExt}; use crate::util::{EcoString, RefMutExt};
use crate::Context; use crate::Context;
static THEME: Lazy<Mutex<Theme>> = Lazy::new(|| { static THEME: Lazy<Theme> =
Mutex::new(ThemeSet::load_defaults().themes.remove("InspiredGitHub").unwrap()) Lazy::new(|| ThemeSet::load_defaults().themes.remove("InspiredGitHub").unwrap());
});
static SYNTAXES: Lazy<Mutex<SyntaxSet>> = static SYNTAXES: Lazy<SyntaxSet> = Lazy::new(|| SyntaxSet::load_defaults_newlines());
Lazy::new(|| Mutex::new(SyntaxSet::load_defaults_newlines()));
/// An evaluated module, ready for importing or conversion to a root layout /// An evaluated module, ready for importing or conversion to a root layout
/// tree. /// tree.
@ -237,12 +234,11 @@ impl RawNode {
/// Styled node for a code block, with optional syntax highlighting. /// Styled node for a code block, with optional syntax highlighting.
pub fn highlighted(&self) -> Node { pub fn highlighted(&self) -> Node {
let mut sequence: Vec<Styled<Node>> = vec![]; let mut sequence: Vec<Styled<Node>> = vec![];
let syntaxes = SYNTAXES.lock().unwrap();
let syntax = if let Some(syntax) = self let syntax = if let Some(syntax) = self
.lang .lang
.as_ref() .as_ref()
.and_then(|token| syntaxes.find_syntax_by_token(&token)) .and_then(|token| SYNTAXES.find_syntax_by_token(&token))
{ {
Some(syntax) Some(syntax)
} else if matches!( } else if matches!(
@ -254,8 +250,7 @@ impl RawNode {
return Node::Text(self.text.clone()).monospaced(); return Node::Text(self.text.clone()).monospaced();
}; };
let theme = THEME.lock().unwrap(); let foreground = THEME
let foreground = theme
.settings .settings
.foreground .foreground
.map(RgbaColor::from) .map(RgbaColor::from)
@ -264,28 +259,31 @@ impl RawNode {
match syntax { match syntax {
Some(syntax) => { Some(syntax) => {
let mut highlighter = HighlightLines::new(syntax, &theme); let mut highlighter = HighlightLines::new(syntax, &THEME);
for (i, line) in self.text.lines().enumerate() { for (i, line) in self.text.lines().enumerate() {
if i != 0 { if i != 0 {
sequence.push(Styled::bare(Node::Linebreak)); sequence.push(Styled::bare(Node::Linebreak));
} }
for (style, line) in highlighter.highlight(line, &syntaxes) { for (style, line) in highlighter.highlight(line, &SYNTAXES) {
sequence.push(Self::styled_line(style, line, foreground)); sequence.push(Self::styled_piece(style, line, foreground));
} }
} }
} }
None => { None => {
let red_tree = let green = parse::parse(&self.text);
RedNode::from_root(parse::parse(&self.text), SourceId::from_raw(0)); let red = RedNode::from_root(green, SourceId::from_raw(0));
let highlighter = Highlighter::new(&theme); let highlighter = Highlighter::new(&THEME);
syntax::highlight_syntect( syntax::highlight_syntect(
red_tree.as_ref(), red.as_ref(),
&self.text,
&highlighter, &highlighter,
&mut |style, line| { &mut |range, style| {
sequence.push(Self::styled_line(style, line, foreground)); sequence.push(Self::styled_piece(
style,
&self.text[range],
foreground,
));
}, },
) )
} }
@ -294,26 +292,29 @@ impl RawNode {
Node::Sequence(sequence).monospaced() Node::Sequence(sequence).monospaced()
} }
fn styled_line(style: SynStyle, line: &str, foreground: Paint) -> Styled<Node> { fn styled_piece(style: SynStyle, piece: &str, foreground: Paint) -> Styled<Node> {
let paint = style.foreground.into(); let paint = style.foreground.into();
let text_node = Node::Text(line.into()); let node = Node::Text(piece.into());
let mut style_map = StyleMap::new();
let mut styles = StyleMap::new();
if paint != foreground { if paint != foreground {
style_map.set(TextNode::FILL, paint); styles.set(TextNode::FILL, paint);
} }
if style.font_style.contains(FontStyle::BOLD) { if style.font_style.contains(FontStyle::BOLD) {
style_map.set(TextNode::STRONG, true); styles.set(TextNode::STRONG, true);
}
if style.font_style.contains(FontStyle::ITALIC) {
style_map.set(TextNode::EMPH, true);
}
if style.font_style.contains(FontStyle::UNDERLINE) {
style_map.set(TextNode::LINES, vec![Decoration::underline()]);
} }
Styled::new(text_node, style_map) if style.font_style.contains(FontStyle::ITALIC) {
styles.set(TextNode::EMPH, true);
}
if style.font_style.contains(FontStyle::UNDERLINE) {
styles.set(TextNode::LINES, vec![DecoLine::Underline.into()]);
}
Styled::new(node, styles)
} }
} }

View File

@ -38,33 +38,10 @@ pub struct Decoration {
pub extent: Linear, pub extent: Linear,
} }
impl Decoration { impl From<DecoLine> for Decoration {
/// Create a new underline with default settings. fn from(line: DecoLine) -> Self {
pub const fn underline() -> Self {
Self { Self {
line: DecoLine::Underline, line,
stroke: None,
thickness: None,
offset: None,
extent: Linear::zero(),
}
}
/// Create a new strikethrough with default settings.
pub const fn strikethrough() -> Self {
Self {
line: DecoLine::Underline,
stroke: None,
thickness: None,
offset: None,
extent: Linear::zero(),
}
}
/// Create a new overline with default settings.
pub const fn overline() -> Self {
Self {
line: DecoLine::Overline,
stroke: None, stroke: None,
thickness: None, thickness: None,
offset: None, offset: None,

View File

@ -23,32 +23,24 @@ where
} }
/// Provide syntect highlighting styles for the children of a node. /// Provide syntect highlighting styles for the children of a node.
pub fn highlight_syntect<F>( pub fn highlight_syntect<F>(node: RedRef, highlighter: &Highlighter, f: &mut F)
node: RedRef, where
text: &str, F: FnMut(Range<usize>, Style),
highlighter: &Highlighter,
f: &mut F,
) where
F: FnMut(Style, &str),
{ {
highlight_syntect_impl(node, text, vec![], highlighter, f) highlight_syntect_impl(node, vec![], highlighter, f)
} }
/// Recursive implementation for returning syntect styles. /// Recursive implementation for returning syntect styles.
fn highlight_syntect_impl<F>( fn highlight_syntect_impl<F>(
node: RedRef, node: RedRef,
text: &str,
scopes: Vec<Scope>, scopes: Vec<Scope>,
highlighter: &Highlighter, highlighter: &Highlighter,
f: &mut F, f: &mut F,
) where ) where
F: FnMut(Style, &str), F: FnMut(Range<usize>, Style),
{ {
if node.children().size_hint().0 == 0 { if node.children().size_hint().0 == 0 {
f( f(node.span().to_range(), highlighter.style_for_stack(&scopes));
highlighter.style_for_stack(&scopes),
&text[node.span().to_range()],
);
return; return;
} }
@ -57,7 +49,7 @@ fn highlight_syntect_impl<F>(
if let Some(category) = Category::determine(child, node) { if let Some(category) = Category::determine(child, node) {
scopes.push(Scope::new(category.tm_scope()).unwrap()) scopes.push(Scope::new(category.tm_scope()).unwrap())
} }
highlight_syntect_impl(child, text, scopes, highlighter, f); highlight_syntect_impl(child, scopes, highlighter, f);
} }
} }
@ -230,7 +222,7 @@ impl Category {
} }
/// Return the TextMate grammar scope for the given highlighting category. /// Return the TextMate grammar scope for the given highlighting category.
pub const fn tm_scope(&self) -> &'static str { pub fn tm_scope(&self) -> &'static str {
match self { match self {
Self::Bracket => "punctuation.definition.typst", Self::Bracket => "punctuation.definition.typst",
Self::Punctuation => "punctuation.typst", Self::Punctuation => "punctuation.typst",