From fdd5c426b92c6cf164803d591a3da3c26f4214c5 Mon Sep 17 00:00:00 2001 From: Roman Chumak Date: Thu, 11 Jan 2024 09:46:30 +0300 Subject: [PATCH 1/2] no egui --- Cargo.toml | 9 ++++++--- src/highlighting.rs | 18 +++++++++++------- src/lib.rs | 5 +++++ src/themes/mod.rs | 14 +++++++++++++- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 681411b..95bdd89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "egui_code_editor" authors = ["Roman Chumak "] -version = "0.2.1" +version = "0.2.2" edition = "2021" license = "MIT" repository = "https://github.com/p4ymak/egui_code_editor" @@ -11,12 +11,15 @@ categories = ["gui", "text-editors"] keywords = ["egui", "GUI", "editor", "syntax", "highlighting"] [dependencies] -egui = "0.25.0" +egui = {version = "0.25.0", optional = true} [lib] name = "egui_code_editor" - +[features] +default = ["egui"] +egui = ["dep:egui"] +no_egui = [] [[example]] name = "demo" diff --git a/src/highlighting.rs b/src/highlighting.rs index 4aea0cc..a591349 100644 --- a/src/highlighting.rs +++ b/src/highlighting.rs @@ -1,12 +1,14 @@ -use std::mem; - -use crate::Syntax; - -use super::syntax::{TokenType, QUOTES, SEPARATORS}; -use super::CodeEditor; +use super::{ + syntax::{Syntax, TokenType, QUOTES, SEPARATORS}, + CodeEditor, +}; +#[cfg(feature = "egui")] use egui::text::LayoutJob; +use std::mem; +#[cfg(feature = "egui")] pub type HighlightCache = egui::util::cache::FrameCache; +#[cfg(feature = "egui")] pub fn highlight(ctx: &egui::Context, cache: &CodeEditor, text: &str) -> LayoutJob { ctx.memory_mut(|mem| mem.caches.cache::().get((cache, text))) } @@ -16,7 +18,7 @@ pub struct Highlighter { ty: TokenType, buffer: String, } - +#[cfg(feature = "egui")] impl egui::util::cache::ComputerMut<(&CodeEditor, &str), LayoutJob> for Highlighter { fn compute(&mut self, (cache, text): (&CodeEditor, &str)) -> LayoutJob { self.highlight(cache, text) @@ -79,6 +81,7 @@ impl Highlighter { token } + #[cfg(feature = "egui")] pub fn highlight(&mut self, editor: &CodeEditor, text: &str) -> LayoutJob { *self = Highlighter::default(); let mut job = LayoutJob::default(); @@ -230,6 +233,7 @@ impl Highlighter { } } +#[cfg(feature = "egui")] impl CodeEditor { fn append(&self, job: &mut LayoutJob, token: &Highlighter) { job.append(token.buffer(), 0.0, self.format(token.ty())); diff --git a/src/lib.rs b/src/lib.rs index 6162ccb..4895ed9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,6 +22,7 @@ mod syntax; mod tests; mod themes; +#[cfg(feature = "egui")] use egui::widgets::text_edit::TextEditOutput; use highlighting::highlight; pub use highlighting::Highlighter; @@ -104,6 +105,7 @@ impl CodeEditor { } #[must_use] + #[cfg(feature = "egui")] /// Use UI font size pub fn with_ui_fontsize(self, ui: &mut egui::Ui) -> Self { CodeEditor { @@ -161,12 +163,14 @@ impl CodeEditor { } #[must_use] + #[cfg(feature = "egui")] pub fn format(&self, ty: TokenType) -> egui::text::TextFormat { let font_id = egui::FontId::monospace(self.fontsize); let color = self.theme.type_color(ty); egui::text::TextFormat::simple(font_id, color) } + #[cfg(feature = "egui")] fn numlines_show(&self, ui: &mut egui::Ui, text: &str) { let total = if text.ends_with('\n') || text.is_empty() { text.lines().count() + 1 @@ -212,6 +216,7 @@ impl CodeEditor { ); } + #[cfg(feature = "egui")] /// Show Code Editor pub fn show(&mut self, ui: &mut egui::Ui, text: &mut String) -> TextEditOutput { let mut text_edit_output: Option = None; diff --git a/src/themes/mod.rs b/src/themes/mod.rs index 1158ca5..acda3d6 100644 --- a/src/themes/mod.rs +++ b/src/themes/mod.rs @@ -5,11 +5,13 @@ pub mod gruvbox; pub mod sonokai; use super::syntax::TokenType; +#[cfg(feature = "egui")] use egui::Color32; +#[cfg(feature = "egui")] pub const ERROR_COLOR: Color32 = Color32::from_rgb(255, 0, 255); -/// Array of default themes. +/// Array of default themes. pub const DEFAULT_THEMES: [ColorTheme; 8] = [ ColorTheme::AYU, ColorTheme::AYU_MIRAGE, @@ -21,6 +23,7 @@ pub const DEFAULT_THEMES: [ColorTheme; 8] = [ ColorTheme::SONOKAI, ]; +#[cfg(feature = "egui")] fn color_from_hex(hex: &str) -> Option { if hex == "none" { return Some(Color32::from_rgba_premultiplied(255, 0, 255, 0)); @@ -61,23 +64,31 @@ impl ColorTheme { pub fn name(&self) -> &str { self.name } + #[must_use] pub fn is_dark(&self) -> bool { self.dark } + #[must_use] + #[cfg(feature = "egui")] pub fn bg(&self) -> Color32 { color_from_hex(self.bg).unwrap_or(ERROR_COLOR) } + #[must_use] + #[cfg(feature = "egui")] pub fn cursor(&self) -> Color32 { color_from_hex(self.cursor).unwrap_or(ERROR_COLOR) } + #[must_use] + #[cfg(feature = "egui")] pub fn selection(&self) -> Color32 { color_from_hex(self.selection).unwrap_or(ERROR_COLOR) } + #[cfg(feature = "egui")] pub fn modify_style(&self, ui: &mut egui::Ui, fontsize: f32) { let style = ui.style_mut(); style.visuals.widgets.noninteractive.bg_fill = self.bg(); @@ -106,6 +117,7 @@ impl ColorTheme { } #[must_use] + #[cfg(feature = "egui")] pub fn type_color(&self, ty: TokenType) -> Color32 { match ty { TokenType::Comment(_) => color_from_hex(self.comments), From 7f51b7b73fdfee72234c6b2d9280963a8b5b7049 Mon Sep 17 00:00:00 2001 From: Roman Chumak Date: Sat, 13 Jan 2024 16:06:47 +0300 Subject: [PATCH 2/2] no_egui, Comment Multiline fixed --- Cargo.toml | 1 - examples/demo.rs | 36 ++++++++++++------------- src/highlighting.rs | 56 +++++++++++++++++++++------------------ src/lib.rs | 17 +++--------- src/syntax/asm.rs | 1 - src/syntax/lua.rs | 1 - src/syntax/mod.rs | 6 ----- src/syntax/rust.rs | 1 - src/syntax/shell.rs | 1 - src/syntax/sql.rs | 1 - src/tests.rs | 64 ++++++++++++++++++++++----------------------- src/themes/mod.rs | 8 ------ 12 files changed, 83 insertions(+), 110 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 95bdd89..dd5d067 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,6 @@ name = "egui_code_editor" [features] default = ["egui"] egui = ["dep:egui"] -no_egui = [] [[example]] name = "demo" diff --git a/examples/demo.rs b/examples/demo.rs index c190751..ee75f68 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -1,7 +1,7 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release use eframe::{self, egui, CreationContext}; -use egui_code_editor::{self, highlighting::Highlighter, CodeEditor, ColorTheme, Syntax}; +use egui_code_editor::{self, highlighting::Token, CodeEditor, ColorTheme, Syntax}; const THEMES: [ColorTheme; 8] = [ ColorTheme::AYU, @@ -97,7 +97,7 @@ fn main() -> Result<(), eframe::Error> { .with_resizable(true) .with_maximized(false) .with_drag_and_drop(true) - .with_inner_size([900.0, 280.0]) + .with_inner_size([900.0, 600.0]) .with_min_inner_size([280.0, 280.0]), ..Default::default() @@ -179,22 +179,22 @@ impl eframe::App for CodeEditorDemo { .vscroll(true); editor.show(ui, &mut self.code); - egui::CollapsingHeader::new("Debug").show(ui, |ui| { - egui::ScrollArea::both() - .auto_shrink([false; 2]) - .show(ui, |ui| { - for token in Highlighter::default().tokens(&self.syntax, &self.code) { - ui.horizontal(|h| { - let fmt = editor.format(token.ty()); - h.label(egui::text::LayoutJob::single_section( - format!("{:?}", token.ty()), - fmt, - )); - h.label(token.buffer()); - }); - } - }); - }); + ui.separator(); + + egui::ScrollArea::both() + .auto_shrink([false; 2]) + .show(ui, |ui| { + for token in Token::default().tokens(&self.syntax, &self.code) { + ui.horizontal(|h| { + let fmt = editor.format(token.ty()); + h.label(egui::text::LayoutJob::single_section( + format!("{:?}", token.ty()), + fmt, + )); + h.label(token.buffer()); + }); + } + }); }); } } diff --git a/src/highlighting.rs b/src/highlighting.rs index a591349..08dcd29 100644 --- a/src/highlighting.rs +++ b/src/highlighting.rs @@ -1,32 +1,15 @@ -use super::{ - syntax::{Syntax, TokenType, QUOTES, SEPARATORS}, - CodeEditor, -}; -#[cfg(feature = "egui")] -use egui::text::LayoutJob; +use super::syntax::{Syntax, TokenType, QUOTES, SEPARATORS}; use std::mem; -#[cfg(feature = "egui")] -pub type HighlightCache = egui::util::cache::FrameCache; -#[cfg(feature = "egui")] -pub fn highlight(ctx: &egui::Context, cache: &CodeEditor, text: &str) -> LayoutJob { - ctx.memory_mut(|mem| mem.caches.cache::().get((cache, text))) -} - #[derive(Default, Debug, PartialEq, PartialOrd)] -pub struct Highlighter { +pub struct Token { ty: TokenType, buffer: String, } -#[cfg(feature = "egui")] -impl egui::util::cache::ComputerMut<(&CodeEditor, &str), LayoutJob> for Highlighter { - fn compute(&mut self, (cache, text): (&CodeEditor, &str)) -> LayoutJob { - self.highlight(cache, text) - } -} -impl Highlighter { + +impl Token { pub fn new>(ty: TokenType, buffer: S) -> Self { - Highlighter { + Token { ty, buffer: buffer.into(), } @@ -60,7 +43,7 @@ impl Highlighter { fn drain(&mut self, ty: TokenType) -> Option { let mut token = None; if !self.buffer().is_empty() { - token = Some(Highlighter { + token = Some(Token { buffer: mem::take(&mut self.buffer), ty: self.ty, }); @@ -83,7 +66,7 @@ impl Highlighter { #[cfg(feature = "egui")] pub fn highlight(&mut self, editor: &CodeEditor, text: &str) -> LayoutJob { - *self = Highlighter::default(); + *self = Token::default(); let mut job = LayoutJob::default(); for c in text.chars() { for token in self.automata(c, &editor.syntax) { @@ -122,8 +105,9 @@ impl Highlighter { self.buffer.push(c); } (Ty::Comment(true), _) => { + self.buffer.push(c); if self.buffer.ends_with(syntax.comment_multiline[1]) { - tokens.extend(self.drain(Ty::Whitespace(c))); + tokens.extend(self.drain(Ty::Unknown)); } } (Ty::Literal | Ty::Punctuation(_), Ty::Whitespace(_)) => { @@ -233,9 +217,29 @@ impl Highlighter { } } +#[cfg(feature = "egui")] +use super::CodeEditor; +#[cfg(feature = "egui")] +use egui::text::LayoutJob; + +#[cfg(feature = "egui")] +impl egui::util::cache::ComputerMut<(&CodeEditor, &str), LayoutJob> for Token { + fn compute(&mut self, (cache, text): (&CodeEditor, &str)) -> LayoutJob { + self.highlight(cache, text) + } +} + +#[cfg(feature = "egui")] +pub type HighlightCache = egui::util::cache::FrameCache; + +#[cfg(feature = "egui")] +pub fn highlight(ctx: &egui::Context, cache: &CodeEditor, text: &str) -> LayoutJob { + ctx.memory_mut(|mem| mem.caches.cache::().get((cache, text))) +} + #[cfg(feature = "egui")] impl CodeEditor { - fn append(&self, job: &mut LayoutJob, token: &Highlighter) { + fn append(&self, job: &mut LayoutJob, token: &Token) { job.append(token.buffer(), 0.0, self.format(token.ty())); } } diff --git a/src/lib.rs b/src/lib.rs index 4895ed9..2e8d97f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,11 +24,11 @@ mod themes; #[cfg(feature = "egui")] use egui::widgets::text_edit::TextEditOutput; +#[cfg(feature = "egui")] use highlighting::highlight; -pub use highlighting::Highlighter; +pub use highlighting::Token; use std::hash::{Hash, Hasher}; -pub use syntax::Syntax; -use syntax::TokenType; +pub use syntax::{Syntax, TokenType}; pub use themes::ColorTheme; pub use themes::DEFAULT_THEMES; @@ -72,7 +72,6 @@ impl Default for CodeEditor { } impl CodeEditor { - #[must_use] pub fn id_source(self, id_source: impl Into) -> Self { CodeEditor { id: id_source.into(), @@ -80,7 +79,6 @@ impl CodeEditor { } } - #[must_use] /// Minimum number of rows to show. /// /// **Default: 10** @@ -88,7 +86,6 @@ impl CodeEditor { CodeEditor { rows, ..self } } - #[must_use] /// Use custom Color Theme /// /// **Default: Gruvbox** @@ -96,7 +93,6 @@ impl CodeEditor { CodeEditor { theme, ..self } } - #[must_use] /// Use custom font size /// /// **Default: 10.0** @@ -104,7 +100,6 @@ impl CodeEditor { CodeEditor { fontsize, ..self } } - #[must_use] #[cfg(feature = "egui")] /// Use UI font size pub fn with_ui_fontsize(self, ui: &mut egui::Ui) -> Self { @@ -114,7 +109,6 @@ impl CodeEditor { } } - #[must_use] /// Show or hide lines numbering /// /// **Default: true** @@ -122,7 +116,6 @@ impl CodeEditor { CodeEditor { numlines, ..self } } - #[must_use] /// Use custom syntax for highlighting /// /// **Default: Rust** @@ -130,14 +123,12 @@ impl CodeEditor { CodeEditor { syntax, ..self } } - #[must_use] /// Turn on/off scrolling on the vertical axis. /// /// **Default: true** pub fn vscroll(self, vscroll: bool) -> Self { CodeEditor { vscroll, ..self } } - #[must_use] /// Should the containing area shrink if the content is small? /// /// **Default: false** @@ -145,7 +136,6 @@ impl CodeEditor { CodeEditor { shrink, ..self } } - #[must_use] /// Stick to bottom /// The scroll handle will stick to the bottom position even while the content size /// changes dynamically. This can be useful to simulate terminal UIs or log/info scrollers. @@ -162,7 +152,6 @@ impl CodeEditor { } } - #[must_use] #[cfg(feature = "egui")] pub fn format(&self, ty: TokenType) -> egui::text::TextFormat { let font_id = egui::FontId::monospace(self.fontsize); diff --git a/src/syntax/asm.rs b/src/syntax/asm.rs index 8a8b3b1..96796b9 100644 --- a/src/syntax/asm.rs +++ b/src/syntax/asm.rs @@ -2,7 +2,6 @@ use super::Syntax; use std::collections::BTreeSet; impl Syntax { - #[must_use] pub fn asm() -> Self { Syntax { language: "Assembly", diff --git a/src/syntax/lua.rs b/src/syntax/lua.rs index 87293c4..1555ca7 100644 --- a/src/syntax/lua.rs +++ b/src/syntax/lua.rs @@ -2,7 +2,6 @@ use super::Syntax; use std::collections::BTreeSet; impl Syntax { - #[must_use] pub fn lua() -> Syntax { Syntax { language: "Lua", diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 2ca02fd..44dfeb8 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -151,15 +151,12 @@ impl Syntax { } } - #[must_use] pub fn language(&self) -> &str { self.language } - #[must_use] pub fn comment(&self) -> &str { self.comment } - #[must_use] pub fn is_keyword(&self, word: &str) -> bool { if self.case_sensitive { self.keywords.contains(&word) @@ -167,7 +164,6 @@ impl Syntax { self.keywords.contains(word.to_ascii_uppercase().as_str()) } } - #[must_use] pub fn is_type(&self, word: &str) -> bool { if self.case_sensitive { self.types.contains(&word) @@ -175,7 +171,6 @@ impl Syntax { self.types.contains(word.to_ascii_uppercase().as_str()) } } - #[must_use] pub fn is_special(&self, word: &str) -> bool { if self.case_sensitive { self.special.contains(&word) @@ -186,7 +181,6 @@ impl Syntax { } impl Syntax { - #[must_use] pub fn simple(comment: &'static str) -> Self { Syntax { language: "", diff --git a/src/syntax/rust.rs b/src/syntax/rust.rs index 966a596..94f6f64 100644 --- a/src/syntax/rust.rs +++ b/src/syntax/rust.rs @@ -2,7 +2,6 @@ use super::Syntax; use std::collections::BTreeSet; impl Syntax { - #[must_use] pub fn rust() -> Self { Syntax { language: "Rust", diff --git a/src/syntax/shell.rs b/src/syntax/shell.rs index a22a696..9834c49 100644 --- a/src/syntax/shell.rs +++ b/src/syntax/shell.rs @@ -2,7 +2,6 @@ use super::Syntax; use std::collections::BTreeSet; impl Syntax { - #[must_use] pub fn shell() -> Self { Syntax { language: "Shell", diff --git a/src/syntax/sql.rs b/src/syntax/sql.rs index ef77427..b942313 100644 --- a/src/syntax/sql.rs +++ b/src/syntax/sql.rs @@ -2,7 +2,6 @@ use super::Syntax; use std::collections::BTreeSet; impl Syntax { - #[must_use] pub fn sql() -> Self { Syntax { language: "SQL", diff --git a/src/tests.rs b/src/tests.rs index b116278..fa35dc7 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -3,19 +3,19 @@ use super::*; #[test] fn numeric_float() { assert_eq!( - Highlighter::default().tokens(&Syntax::default(), "3.14"), - [Highlighter::new(TokenType::Numeric(true), "3.14")] + Token::default().tokens(&Syntax::default(), "3.14"), + [Token::new(TokenType::Numeric(true), "3.14")] ); } #[test] fn numeric_float_desription() { assert_eq!( - Highlighter::default().tokens(&Syntax::default(), "3.14_f32"), + Token::default().tokens(&Syntax::default(), "3.14_f32"), [ - Highlighter::new(TokenType::Numeric(true), "3.14"), - Highlighter::new(TokenType::Numeric(true), "_"), - Highlighter::new(TokenType::Numeric(true), "f32") + Token::new(TokenType::Numeric(true), "3.14"), + Token::new(TokenType::Numeric(true), "_"), + Token::new(TokenType::Numeric(true), "f32") ] ); } @@ -23,11 +23,11 @@ fn numeric_float_desription() { #[test] fn numeric_float_second_dot() { assert_eq!( - Highlighter::default().tokens(&Syntax::default(), "3.14.032"), + Token::default().tokens(&Syntax::default(), "3.14.032"), [ - Highlighter::new(TokenType::Numeric(true), "3.14"), - Highlighter::new(TokenType::Punctuation('.'), "."), - Highlighter::new(TokenType::Numeric(false), "032") + Token::new(TokenType::Numeric(true), "3.14"), + Token::new(TokenType::Punctuation('.'), "."), + Token::new(TokenType::Numeric(false), "032") ] ); } @@ -36,30 +36,30 @@ fn numeric_float_second_dot() { fn simple_rust() { let syntax = Syntax::rust(); let input = vec![ - Highlighter::new(TokenType::Keyword, "fn"), - Highlighter::new(TokenType::Whitespace(' '), " "), - Highlighter::new(TokenType::Function, "function"), - Highlighter::new(TokenType::Punctuation('('), "("), - Highlighter::new(TokenType::Str('\"'), "\"String\""), - Highlighter::new(TokenType::Punctuation(')'), ")"), - Highlighter::new(TokenType::Punctuation('{'), "{"), - Highlighter::new(TokenType::Whitespace('\n'), "\n"), - Highlighter::new(TokenType::Whitespace('\t'), "\t"), - Highlighter::new(TokenType::Keyword, "let"), - Highlighter::new(TokenType::Whitespace(' '), " "), - Highlighter::new(TokenType::Literal, "x_0"), - Highlighter::new(TokenType::Punctuation(':'), ":"), - Highlighter::new(TokenType::Whitespace(' '), " "), - Highlighter::new(TokenType::Type, "f32"), - Highlighter::new(TokenType::Whitespace(' '), " "), - Highlighter::new(TokenType::Punctuation('='), "="), - Highlighter::new(TokenType::Numeric(true), "13.34"), - Highlighter::new(TokenType::Punctuation(';'), ";"), - Highlighter::new(TokenType::Whitespace('\n'), "\n"), - Highlighter::new(TokenType::Punctuation('}'), "}"), + Token::new(TokenType::Keyword, "fn"), + Token::new(TokenType::Whitespace(' '), " "), + Token::new(TokenType::Function, "function"), + Token::new(TokenType::Punctuation('('), "("), + Token::new(TokenType::Str('\"'), "\"String\""), + Token::new(TokenType::Punctuation(')'), ")"), + Token::new(TokenType::Punctuation('{'), "{"), + Token::new(TokenType::Whitespace('\n'), "\n"), + Token::new(TokenType::Whitespace('\t'), "\t"), + Token::new(TokenType::Keyword, "let"), + Token::new(TokenType::Whitespace(' '), " "), + Token::new(TokenType::Literal, "x_0"), + Token::new(TokenType::Punctuation(':'), ":"), + Token::new(TokenType::Whitespace(' '), " "), + Token::new(TokenType::Type, "f32"), + Token::new(TokenType::Whitespace(' '), " "), + Token::new(TokenType::Punctuation('='), "="), + Token::new(TokenType::Numeric(true), "13.34"), + Token::new(TokenType::Punctuation(';'), ";"), + Token::new(TokenType::Whitespace('\n'), "\n"), + Token::new(TokenType::Punctuation('}'), "}"), ]; let str = input.iter().map(|h| h.buffer()).collect::(); - let output = Highlighter::default().tokens(&syntax, &str); + let output = Token::default().tokens(&syntax, &str); println!("{str}"); assert_eq!(input, output); } diff --git a/src/themes/mod.rs b/src/themes/mod.rs index acda3d6..fadf606 100644 --- a/src/themes/mod.rs +++ b/src/themes/mod.rs @@ -60,29 +60,24 @@ impl Default for ColorTheme { } } impl ColorTheme { - #[must_use] pub fn name(&self) -> &str { self.name } - #[must_use] pub fn is_dark(&self) -> bool { self.dark } - #[must_use] #[cfg(feature = "egui")] pub fn bg(&self) -> Color32 { color_from_hex(self.bg).unwrap_or(ERROR_COLOR) } - #[must_use] #[cfg(feature = "egui")] pub fn cursor(&self) -> Color32 { color_from_hex(self.cursor).unwrap_or(ERROR_COLOR) } - #[must_use] #[cfg(feature = "egui")] pub fn selection(&self) -> Color32 { color_from_hex(self.selection).unwrap_or(ERROR_COLOR) @@ -100,7 +95,6 @@ impl ColorTheme { style.visuals.text_cursor.width = fontsize * 0.1; } - #[must_use] pub const fn type_color_str(&self, ty: TokenType) -> &'static str { match ty { TokenType::Comment(_) => self.comments, @@ -116,7 +110,6 @@ impl ColorTheme { } } - #[must_use] #[cfg(feature = "egui")] pub fn type_color(&self, ty: TokenType) -> Color32 { match ty { @@ -134,7 +127,6 @@ impl ColorTheme { .unwrap_or(ERROR_COLOR) } - #[must_use] pub fn monocolor( dark: bool, bg: &'static str,