Skip to content

Commit

Permalink
Merge branch 'no_egui'
Browse files Browse the repository at this point in the history
  • Loading branch information
p4ymak committed Jan 13, 2024
2 parents 0550fca + 7f51b7b commit 25928b8
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 110 deletions.
8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "egui_code_editor"
authors = ["Roman Chumak <p4ymak@yandex.ru>"]
version = "0.2.1"
version = "0.2.2"
edition = "2021"
license = "MIT"
repository = "https://github.com/p4ymak/egui_code_editor"
Expand All @@ -11,12 +11,14 @@ 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"]

[[example]]
name = "demo"
Expand Down
36 changes: 18 additions & 18 deletions examples/demo.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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());
});
}
});
});
}
}
54 changes: 31 additions & 23 deletions src/highlighting.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
use super::syntax::{Syntax, TokenType, QUOTES, SEPARATORS};
use std::mem;

use crate::Syntax;

use super::syntax::{TokenType, QUOTES, SEPARATORS};
use super::CodeEditor;
use egui::text::LayoutJob;

pub type HighlightCache = egui::util::cache::FrameCache<LayoutJob, Highlighter>;
pub fn highlight(ctx: &egui::Context, cache: &CodeEditor, text: &str) -> LayoutJob {
ctx.memory_mut(|mem| mem.caches.cache::<HighlightCache>().get((cache, text)))
}

#[derive(Default, Debug, PartialEq, PartialOrd)]
pub struct Highlighter {
pub struct Token {
ty: TokenType,
buffer: String,
}

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<S: Into<String>>(ty: TokenType, buffer: S) -> Self {
Highlighter {
Token {
ty,
buffer: buffer.into(),
}
Expand Down Expand Up @@ -58,7 +43,7 @@ impl Highlighter {
fn drain(&mut self, ty: TokenType) -> Option<Self> {
let mut token = None;
if !self.buffer().is_empty() {
token = Some(Highlighter {
token = Some(Token {
buffer: mem::take(&mut self.buffer),
ty: self.ty,
});
Expand All @@ -79,8 +64,9 @@ impl Highlighter {
token
}

#[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) {
Expand Down Expand Up @@ -119,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(_)) => {
Expand Down Expand Up @@ -230,8 +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<LayoutJob, Token>;

#[cfg(feature = "egui")]
pub fn highlight(ctx: &egui::Context, cache: &CodeEditor, text: &str) -> LayoutJob {
ctx.memory_mut(|mem| mem.caches.cache::<HighlightCache>().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()));
}
}
22 changes: 8 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ mod syntax;
mod tests;
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;

Expand Down Expand Up @@ -71,39 +72,35 @@ impl Default for CodeEditor {
}

impl CodeEditor {
#[must_use]
pub fn id_source(self, id_source: impl Into<String>) -> Self {
CodeEditor {
id: id_source.into(),
..self
}
}

#[must_use]
/// Minimum number of rows to show.
///
/// **Default: 10**
pub fn with_rows(self, rows: usize) -> Self {
CodeEditor { rows, ..self }
}

#[must_use]
/// Use custom Color Theme
///
/// **Default: Gruvbox**
pub fn with_theme(self, theme: ColorTheme) -> Self {
CodeEditor { theme, ..self }
}

#[must_use]
/// Use custom font size
///
/// **Default: 10.0**
pub fn with_fontsize(self, fontsize: f32) -> Self {
CodeEditor { fontsize, ..self }
}

#[must_use]
#[cfg(feature = "egui")]
/// Use UI font size
pub fn with_ui_fontsize(self, ui: &mut egui::Ui) -> Self {
CodeEditor {
Expand All @@ -112,38 +109,33 @@ impl CodeEditor {
}
}

#[must_use]
/// Show or hide lines numbering
///
/// **Default: true**
pub fn with_numlines(self, numlines: bool) -> Self {
CodeEditor { numlines, ..self }
}

#[must_use]
/// Use custom syntax for highlighting
///
/// **Default: Rust**
pub fn with_syntax(self, syntax: Syntax) -> Self {
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**
pub fn auto_shrink(self, shrink: bool) -> Self {
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.
Expand All @@ -160,13 +152,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
Expand Down Expand Up @@ -212,6 +205,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<TextEditOutput> = None;
Expand Down
1 change: 0 additions & 1 deletion src/syntax/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use super::Syntax;
use std::collections::BTreeSet;

impl Syntax {
#[must_use]
pub fn asm() -> Self {
Syntax {
language: "Assembly",
Expand Down
1 change: 0 additions & 1 deletion src/syntax/lua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use super::Syntax;
use std::collections::BTreeSet;

impl Syntax {
#[must_use]
pub fn lua() -> Syntax {
Syntax {
language: "Lua",
Expand Down
6 changes: 0 additions & 6 deletions src/syntax/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,31 +151,26 @@ 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)
} else {
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)
} else {
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)
Expand All @@ -186,7 +181,6 @@ impl Syntax {
}

impl Syntax {
#[must_use]
pub fn simple(comment: &'static str) -> Self {
Syntax {
language: "",
Expand Down
1 change: 0 additions & 1 deletion src/syntax/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use super::Syntax;
use std::collections::BTreeSet;

impl Syntax {
#[must_use]
pub fn rust() -> Self {
Syntax {
language: "Rust",
Expand Down
1 change: 0 additions & 1 deletion src/syntax/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use super::Syntax;
use std::collections::BTreeSet;

impl Syntax {
#[must_use]
pub fn shell() -> Self {
Syntax {
language: "Shell",
Expand Down
1 change: 0 additions & 1 deletion src/syntax/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use super::Syntax;
use std::collections::BTreeSet;

impl Syntax {
#[must_use]
pub fn sql() -> Self {
Syntax {
language: "SQL",
Expand Down
Loading

0 comments on commit 25928b8

Please sign in to comment.