js highlighting
This commit is contained in:
parent
b84cde8e2b
commit
f95d44ec69
|
@ -399,6 +399,7 @@ fn to_syntax(language: &str) -> Syntax {
|
||||||
match language {
|
match language {
|
||||||
"py" => Syntax::python(),
|
"py" => Syntax::python(),
|
||||||
"rs" => Syntax::rust(),
|
"rs" => Syntax::rust(),
|
||||||
|
"js" => Syntax::javascript(),
|
||||||
_ => Syntax::shell(),
|
_ => Syntax::shell(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
use super::Syntax;
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
|
impl Syntax {
|
||||||
|
pub fn javascript() -> Syntax {
|
||||||
|
Syntax {
|
||||||
|
language: "Javascript",
|
||||||
|
case_sensitive: true,
|
||||||
|
comment: "//",
|
||||||
|
comment_multiline: ["/*", "*/"],
|
||||||
|
keywords: BTreeSet::from([
|
||||||
|
"&&", "||", "!", "let", "var", "abstract", "arguments", "await", "break", "case", "catch", "class", "const", "continue",
|
||||||
|
"debugger", "default", "delete", "do", "else", "enum", "eval", "export", "extends", "final", "finally", "for", "function",
|
||||||
|
"goto", "if", "implements", "import", "in", "instanceof", "interface", "let", "native", "new", "package", "private", "protected",
|
||||||
|
"public", "return", "static", "super", "switch", "synchronized", "this","throw", "throws", "transient", "try", "typeof",
|
||||||
|
"var", "volatile", "while", "with", "yield",
|
||||||
|
]),
|
||||||
|
types: BTreeSet::from([
|
||||||
|
"Boolean", "Number", "BigInt", "Undefined", "Null", "String", "Symbol", "byte", "char", "float", "int", "long", "short", "void",
|
||||||
|
]),
|
||||||
|
special: BTreeSet::from(["false", "null", "true"]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
pub mod asm;
|
pub mod asm;
|
||||||
|
pub mod javascript;
|
||||||
pub mod lua;
|
pub mod lua;
|
||||||
pub mod python;
|
pub mod python;
|
||||||
pub mod rust;
|
pub mod rust;
|
||||||
|
@ -18,179 +19,179 @@ type Float = bool;
|
||||||
#[derive(Default, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)]
|
#[derive(Default, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub enum TokenType {
|
pub enum TokenType {
|
||||||
Comment(MultiLine),
|
Comment(MultiLine),
|
||||||
Function,
|
Function,
|
||||||
Keyword,
|
Keyword,
|
||||||
Literal,
|
Literal,
|
||||||
Numeric(Float),
|
Numeric(Float),
|
||||||
Punctuation(char),
|
Punctuation(char),
|
||||||
Special,
|
Special,
|
||||||
Str(char),
|
Str(char),
|
||||||
Type,
|
Type,
|
||||||
Whitespace(char),
|
Whitespace(char),
|
||||||
#[default]
|
#[default]
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
impl std::fmt::Debug for TokenType {
|
impl std::fmt::Debug for TokenType {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let mut name = String::new();
|
let mut name = String::new();
|
||||||
match &self {
|
match &self {
|
||||||
TokenType::Comment(multiline) => {
|
TokenType::Comment(multiline) => {
|
||||||
name.push_str("Comment");
|
name.push_str("Comment");
|
||||||
{
|
{
|
||||||
if *multiline {
|
if *multiline {
|
||||||
name.push_str(" MultiLine");
|
name.push_str(" MultiLine");
|
||||||
} else {
|
} else {
|
||||||
name.push_str(" SingleLine");
|
name.push_str(" SingleLine");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TokenType::Function => name.push_str("Function"),
|
TokenType::Function => name.push_str("Function"),
|
||||||
TokenType::Keyword => name.push_str("Keyword"),
|
TokenType::Keyword => name.push_str("Keyword"),
|
||||||
TokenType::Literal => name.push_str("Literal"),
|
TokenType::Literal => name.push_str("Literal"),
|
||||||
TokenType::Numeric(float) => {
|
TokenType::Numeric(float) => {
|
||||||
name.push_str("Numeric");
|
name.push_str("Numeric");
|
||||||
if *float {
|
if *float {
|
||||||
name.push_str(" Float");
|
name.push_str(" Float");
|
||||||
} else {
|
} else {
|
||||||
name.push_str(" Integer");
|
name.push_str(" Integer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TokenType::Punctuation(_) => name.push_str("Punctuation"),
|
TokenType::Punctuation(_) => name.push_str("Punctuation"),
|
||||||
TokenType::Special => name.push_str("Special"),
|
TokenType::Special => name.push_str("Special"),
|
||||||
TokenType::Str(quote) => {
|
TokenType::Str(quote) => {
|
||||||
name.push_str("Str ");
|
name.push_str("Str ");
|
||||||
name.push(*quote);
|
name.push(*quote);
|
||||||
}
|
}
|
||||||
TokenType::Type => name.push_str("Type"),
|
TokenType::Type => name.push_str("Type"),
|
||||||
TokenType::Whitespace(c) => {
|
TokenType::Whitespace(c) => {
|
||||||
name.push_str("Whitespace");
|
name.push_str("Whitespace");
|
||||||
match c {
|
match c {
|
||||||
' ' => name.push_str(" Space"),
|
' ' => name.push_str(" Space"),
|
||||||
'\t' => name.push_str(" Tab"),
|
'\t' => name.push_str(" Tab"),
|
||||||
'\n' => name.push_str(" New Line"),
|
'\n' => name.push_str(" New Line"),
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
TokenType::Unknown => name.push_str("Unknown"),
|
TokenType::Unknown => name.push_str("Unknown"),
|
||||||
};
|
};
|
||||||
write!(f, "{name}")
|
write!(f, "{name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<char> for TokenType {
|
impl From<char> for TokenType {
|
||||||
fn from(c: char) -> Self {
|
fn from(c: char) -> Self {
|
||||||
match c {
|
match c {
|
||||||
c if c.is_whitespace() => TokenType::Whitespace(c),
|
c if c.is_whitespace() => TokenType::Whitespace(c),
|
||||||
c if QUOTES.contains(&c) => TokenType::Str(c),
|
c if QUOTES.contains(&c) => TokenType::Str(c),
|
||||||
c if c.is_numeric() => TokenType::Numeric(false),
|
c if c.is_numeric() => TokenType::Numeric(false),
|
||||||
c if c.is_alphabetic() || SEPARATORS.contains(&c) => TokenType::Literal,
|
c if c.is_alphabetic() || SEPARATORS.contains(&c) => TokenType::Literal,
|
||||||
c if c.is_ascii_punctuation() => TokenType::Punctuation(c),
|
c if c.is_ascii_punctuation() => TokenType::Punctuation(c),
|
||||||
_ => TokenType::Unknown,
|
_ => TokenType::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
/// Rules for highlighting.
|
/// Rules for highlighting.
|
||||||
pub struct Syntax {
|
pub struct Syntax {
|
||||||
pub language: &'static str,
|
pub language: &'static str,
|
||||||
pub case_sensitive: bool,
|
pub case_sensitive: bool,
|
||||||
pub comment: &'static str,
|
pub comment: &'static str,
|
||||||
pub comment_multiline: [&'static str; 2],
|
pub comment_multiline: [&'static str; 2],
|
||||||
pub keywords: BTreeSet<&'static str>,
|
pub keywords: BTreeSet<&'static str>,
|
||||||
pub types: BTreeSet<&'static str>,
|
pub types: BTreeSet<&'static str>,
|
||||||
pub special: BTreeSet<&'static str>,
|
pub special: BTreeSet<&'static str>,
|
||||||
}
|
}
|
||||||
impl Default for Syntax {
|
impl Default for Syntax {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Syntax::rust()
|
Syntax::rust()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Hash for Syntax {
|
impl Hash for Syntax {
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.language.hash(state);
|
self.language.hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Syntax {
|
impl Syntax {
|
||||||
pub fn new(language: &'static str) -> Self {
|
pub fn new(language: &'static str) -> Self {
|
||||||
Syntax {
|
Syntax {
|
||||||
language,
|
language,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn with_case_sensitive(self, case_sensitive: bool) -> Self {
|
pub fn with_case_sensitive(self, case_sensitive: bool) -> Self {
|
||||||
Syntax {
|
Syntax {
|
||||||
case_sensitive,
|
case_sensitive,
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn with_comment(self, comment: &'static str) -> Self {
|
pub fn with_comment(self, comment: &'static str) -> Self {
|
||||||
Syntax { comment, ..self }
|
Syntax { comment, ..self }
|
||||||
}
|
}
|
||||||
pub fn with_comment_multiline(self, comment_multiline: [&'static str; 2]) -> Self {
|
pub fn with_comment_multiline(self, comment_multiline: [&'static str; 2]) -> Self {
|
||||||
Syntax {
|
Syntax {
|
||||||
comment_multiline,
|
comment_multiline,
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn with_keywords<T: Into<BTreeSet<&'static str>>>(self, keywords: T) -> Self {
|
pub fn with_keywords<T: Into<BTreeSet<&'static str>>>(self, keywords: T) -> Self {
|
||||||
Syntax {
|
Syntax {
|
||||||
keywords: keywords.into(),
|
keywords: keywords.into(),
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn with_types<T: Into<BTreeSet<&'static str>>>(self, types: T) -> Self {
|
pub fn with_types<T: Into<BTreeSet<&'static str>>>(self, types: T) -> Self {
|
||||||
Syntax {
|
Syntax {
|
||||||
types: types.into(),
|
types: types.into(),
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn with_special<T: Into<BTreeSet<&'static str>>>(self, special: T) -> Self {
|
pub fn with_special<T: Into<BTreeSet<&'static str>>>(self, special: T) -> Self {
|
||||||
Syntax {
|
Syntax {
|
||||||
special: special.into(),
|
special: special.into(),
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn language(&self) -> &str {
|
pub fn language(&self) -> &str {
|
||||||
self.language
|
self.language
|
||||||
}
|
}
|
||||||
pub fn comment(&self) -> &str {
|
pub fn comment(&self) -> &str {
|
||||||
self.comment
|
self.comment
|
||||||
}
|
}
|
||||||
pub fn is_keyword(&self, word: &str) -> bool {
|
pub fn is_keyword(&self, word: &str) -> bool {
|
||||||
if self.case_sensitive {
|
if self.case_sensitive {
|
||||||
self.keywords.contains(&word)
|
self.keywords.contains(&word)
|
||||||
} else {
|
} else {
|
||||||
self.keywords.contains(word.to_ascii_uppercase().as_str())
|
self.keywords.contains(word.to_ascii_uppercase().as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn is_type(&self, word: &str) -> bool {
|
pub fn is_type(&self, word: &str) -> bool {
|
||||||
if self.case_sensitive {
|
if self.case_sensitive {
|
||||||
self.types.contains(&word)
|
self.types.contains(&word)
|
||||||
} else {
|
} else {
|
||||||
self.types.contains(word.to_ascii_uppercase().as_str())
|
self.types.contains(word.to_ascii_uppercase().as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn is_special(&self, word: &str) -> bool {
|
pub fn is_special(&self, word: &str) -> bool {
|
||||||
if self.case_sensitive {
|
if self.case_sensitive {
|
||||||
self.special.contains(&word)
|
self.special.contains(&word)
|
||||||
} else {
|
} else {
|
||||||
self.special.contains(word.to_ascii_uppercase().as_str())
|
self.special.contains(word.to_ascii_uppercase().as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Syntax {
|
impl Syntax {
|
||||||
pub fn simple(comment: &'static str) -> Self {
|
pub fn simple(comment: &'static str) -> Self {
|
||||||
Syntax {
|
Syntax {
|
||||||
language: "",
|
language: "",
|
||||||
case_sensitive: false,
|
case_sensitive: false,
|
||||||
comment,
|
comment,
|
||||||
comment_multiline: [comment; 2],
|
comment_multiline: [comment; 2],
|
||||||
keywords: BTreeSet::new(),
|
keywords: BTreeSet::new(),
|
||||||
types: BTreeSet::new(),
|
types: BTreeSet::new(),
|
||||||
special: BTreeSet::new(),
|
special: BTreeSet::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +1,44 @@
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
|
|
||||||
pub struct ShortcutsWindow {
|
pub struct ShortcutsWindow {
|
||||||
pub visible: bool,
|
pub visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShortcutsWindow {
|
impl ShortcutsWindow {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self { visible: false }
|
Self { visible: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show(&mut self, ctx: &egui::Context) {
|
pub fn show(&mut self, ctx: &egui::Context) {
|
||||||
let mut visible = self.visible;
|
let mut visible = self.visible;
|
||||||
egui::Window::new("Shortcuts")
|
egui::Window::new("Shortcuts")
|
||||||
.open(&mut visible)
|
.open(&mut visible)
|
||||||
.vscroll(true)
|
.vscroll(true)
|
||||||
.hscroll(true)
|
.hscroll(true)
|
||||||
.show(ctx, |ui| self.ui(ui));
|
.show(ctx, |ui| self.ui(ui));
|
||||||
self.visible = self.visible && visible;
|
self.visible = self.visible && visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||||
ui.set_min_width(250.0);
|
ui.set_min_width(250.0);
|
||||||
ui.label("Ctrl+S : save file");
|
ui.label("Ctrl+S : save file");
|
||||||
ui.label("Ctrl+Shift+S : save file as");
|
ui.label("Ctrl+Shift+S : save file as");
|
||||||
ui.label("Ctrl+R : reload file");
|
ui.label("Ctrl+R : reload file");
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.label("Ctrl+F : open search window");
|
ui.label("Ctrl+F : open search window");
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.label("Ctrl+Z : undo");
|
ui.label("Ctrl+T : reload tree");
|
||||||
ui.label("Ctrl+Y : redo");
|
ui.separator();
|
||||||
ui.label("Tab on selection : add indent of selection");
|
ui.label("Ctrl+Z : undo");
|
||||||
ui.label("Shift+Tab on selection : remove indent of selection");
|
ui.label("Ctrl+Y : redo");
|
||||||
ui.label("Ctrl+E : comment selection");
|
ui.label("Tab on selection : add indent of selection");
|
||||||
ui.separator();
|
ui.label("Shift+Tab on selection : remove indent of selection");
|
||||||
ui.label("Alt+Arrows : move between tabs");
|
ui.label("Ctrl+E : comment selection");
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.label("Enter (project_mode) : edit item");
|
ui.label("Alt+Arrows : move between tabs");
|
||||||
ui.label("Arrows (project_mode) : change selected item");
|
ui.separator();
|
||||||
ui.label("Shift+Arrows (project_mode) : move selected item");
|
ui.label("Enter (project_mode) : edit item");
|
||||||
}
|
ui.label("Arrows (project_mode) : change selected item");
|
||||||
|
ui.label("Shift+Arrows (project_mode) : move selected item");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue