Improved highlighting
This commit is contained in:
parent
d45deb2685
commit
ad27219f4c
5 changed files with 41 additions and 12 deletions
15
Cargo.lock
generated
15
Cargo.lock
generated
|
|
@ -91,10 +91,11 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.27"
|
version = "1.2.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc"
|
checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"find-msvc-tools",
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -217,6 +218,12 @@ version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "find-msvc-tools"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "foldhash"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
|
@ -225,9 +232,9 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.4"
|
version = "0.15.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
|
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
"equivalent",
|
"equivalent",
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ pub enum TokenKind {
|
||||||
Special,
|
Special,
|
||||||
/// A program constant or other statically-known name
|
/// A program constant or other statically-known name
|
||||||
Constant,
|
Constant,
|
||||||
|
/// A function call or some other active operation
|
||||||
|
Function,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
@ -146,8 +148,9 @@ pub enum Regex {
|
||||||
Group(Vec<Self>),
|
Group(Vec<Self>),
|
||||||
// (at_least, at_most, _)
|
// (at_least, at_most, _)
|
||||||
Many(usize, usize, Box<Self>),
|
Many(usize, usize, Box<Self>),
|
||||||
// (delimiter, x) - delimit x with `delimiter` on either side (used for raw strings)
|
// (delimiter, x) - parse a pattern, then refer to the substring later in x with `~`
|
||||||
Delim(Box<Self>, Box<Self>),
|
Delim(Box<Self>, Box<Self>),
|
||||||
|
Rewind(Box<Self>),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct State<'a> {
|
struct State<'a> {
|
||||||
|
|
@ -163,7 +166,6 @@ impl State<'_> {
|
||||||
|
|
||||||
fn prev(&self) -> Option<char> {
|
fn prev(&self) -> Option<char> {
|
||||||
self.s[..self.pos].last().copied()
|
self.s[..self.pos].last().copied()
|
||||||
// self.s.get(self.pos.saturating_sub(1)).copied()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skip_if(&mut self, f: impl FnOnce(char) -> bool) -> Option<()> {
|
fn skip_if(&mut self, f: impl FnOnce(char) -> bool) -> Option<()> {
|
||||||
|
|
@ -242,6 +244,14 @@ impl State<'_> {
|
||||||
self.delim = old_delim;
|
self.delim = old_delim;
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
Regex::Rewind(r) => {
|
||||||
|
let old_pos = self.pos;
|
||||||
|
let res = self.go(r);
|
||||||
|
if res.is_some() {
|
||||||
|
self.pos = old_pos;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +275,7 @@ use chumsky::{
|
||||||
impl Regex {
|
impl Regex {
|
||||||
fn parser<'a>() -> impl Parser<'a, &'a str, Self, extra::Err<Rich<'a, char>>> {
|
fn parser<'a>() -> impl Parser<'a, &'a str, Self, extra::Err<Rich<'a, char>>> {
|
||||||
recursive(|regex| {
|
recursive(|regex| {
|
||||||
let metachars = r"{}[]()^$.|*+-?\/@~";
|
let metachars = r"{}[]()^$.|*+-?\/@~%";
|
||||||
let char_ = choice((
|
let char_ = choice((
|
||||||
none_of(metachars),
|
none_of(metachars),
|
||||||
// Escaped meta characters
|
// Escaped meta characters
|
||||||
|
|
@ -307,6 +317,7 @@ impl Regex {
|
||||||
postfix(1, just('*'), |r, _, _| Self::Many(0, !0, Box::new(r))),
|
postfix(1, just('*'), |r, _, _| Self::Many(0, !0, Box::new(r))),
|
||||||
postfix(1, just('+'), |r, _, _| Self::Many(1, !0, Box::new(r))),
|
postfix(1, just('+'), |r, _, _| Self::Many(1, !0, Box::new(r))),
|
||||||
postfix(1, just('?'), |r, _, _| Self::Many(0, 1, Box::new(r))),
|
postfix(1, just('?'), |r, _, _| Self::Many(0, 1, Box::new(r))),
|
||||||
|
postfix(1, just('%'), |r, _, _| Self::Rewind(Box::new(r))),
|
||||||
// Non-standard: `x@y` parses `x` and then `y`. `y` can use `~` to refer to the extra string that was
|
// Non-standard: `x@y` parses `x` and then `y`. `y` can use `~` to refer to the extra string that was
|
||||||
// parsed by `x`. This supports nesting and is intended for context-sensitive patterns like Rust raw
|
// parsed by `x`. This supports nesting and is intended for context-sensitive patterns like Rust raw
|
||||||
// strings.
|
// strings.
|
||||||
|
|
|
||||||
|
|
@ -102,8 +102,10 @@ impl Highlighter {
|
||||||
)
|
)
|
||||||
.with(
|
.with(
|
||||||
TokenKind::Operator,
|
TokenKind::Operator,
|
||||||
r"[(&(mut)?)(\?)(\+=?)(\-=?)(\*=?)(\/=?)(%=?)(!=?)(==?)(&&?=?)(\|\|?=?)(<<?=?)(>>?=?)(\.\.[\.=]?)\\\~\^:;,\@(=>?)]",
|
r"[(&(mut)?)(\?)(\+=?)(\-=?)(\*=?)(\/=?)(\%=?)(!=?)(==?)(&&?=?)(\|\|?=?)(<<?=?)(>>?=?)(\.\.[\.=]?)\\\~\^:;,\@(=>?)]",
|
||||||
)
|
)
|
||||||
|
// Function/method call
|
||||||
|
.with(TokenKind::Function, r"(\.)?\b[a-z_][A-Za-z0-9_]*\b[\(<]%")
|
||||||
// Fields and methods: a.foo
|
// Fields and methods: a.foo
|
||||||
.with(TokenKind::Property, r"\.[a-z_][A-Za-z0-9_]*")
|
.with(TokenKind::Property, r"\.[a-z_][A-Za-z0-9_]*")
|
||||||
// Paths: std::foo::bar
|
// Paths: std::foo::bar
|
||||||
|
|
@ -145,8 +147,10 @@ impl Highlighter {
|
||||||
.with(TokenKind::String, r#"b?'[(\\[nrt\\0(x[0-7A-Za-z][0-7A-Za-z])])[^']]*'"#)
|
.with(TokenKind::String, r#"b?'[(\\[nrt\\0(x[0-7A-Za-z][0-7A-Za-z])])[^']]*'"#)
|
||||||
.with(
|
.with(
|
||||||
TokenKind::Operator,
|
TokenKind::Operator,
|
||||||
r"[(&)(\?)(\+\+)(\-\-)(\+=?)(\-=?)(\*=?)(\/=?)(%=?)(!=?)(==?)(&&?=?)(\|\|?=?)(<<?=?)(>>?=?)(\.\.[\.=]?)\\\~\^:;,\@(=>?)]",
|
r"[(&)(\?)(\+\+)(\-\-)(\+=?)(\-=?)(\*=?)(\/=?)(\%=?)(!=?)(==?)(&&?=?)(\|\|?=?)(<<?=?)(>>?=?)(\.\.[\.=]?)\\\~\^:;,\@(=>?)]",
|
||||||
)
|
)
|
||||||
|
// Function/method call
|
||||||
|
.with(TokenKind::Function, r"(\.)?\b[a-z_][A-Za-z0-9_]*\b[\(<]%")
|
||||||
// Fields and methods: a.foo
|
// Fields and methods: a.foo
|
||||||
.with(TokenKind::Property, r"\.[a-z_][A-Za-z0-9_]*")
|
.with(TokenKind::Property, r"\.[a-z_][A-Za-z0-9_]*")
|
||||||
// Paths: std::foo::bar
|
// Paths: std::foo::bar
|
||||||
|
|
@ -159,7 +163,7 @@ impl Highlighter {
|
||||||
pub fn generic_clike(self) -> Self {
|
pub fn generic_clike(self) -> Self {
|
||||||
self
|
self
|
||||||
// Keywords
|
// Keywords
|
||||||
.with(TokenKind::Keyword, r"\b[(var)(enum)(let)(this)(fn)(struct)(class)(import)(if)(while)(for)(in)(loop)(else)(break)(continue)(const)(static)(type)(extern)(return)(async)(throw)(catch)(union)(auto)(namespace)(public)(private)(function)(func)]\b")
|
.with(TokenKind::Keyword, r"\b[(var)(enum)(let)(this)(fn)(struct)(class)(import)(if)(while)(for)(in)(loop)(else)(break)(continue)(const)(static)(type)(extern)(return)(async)(throw)(catch)(union)(auto)(namespace)(public)(private)(function)(func)(goto)]\b")
|
||||||
// Primitives
|
// Primitives
|
||||||
.with(TokenKind::Type, r"\b[(([(unsigned)(signed)][[:space:]])*u?int[0-9]*(_t)?)(float)(double)(bool)(char)(size_t)(void)]\b")
|
.with(TokenKind::Type, r"\b[(([(unsigned)(signed)][[:space:]])*u?int[0-9]*(_t)?)(float)(double)(bool)(char)(size_t)(void)]\b")
|
||||||
.clike_comments()
|
.clike_comments()
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ pub struct Theme {
|
||||||
pub hl_token_string: Color,
|
pub hl_token_string: Color,
|
||||||
pub hl_token_special: Color,
|
pub hl_token_special: Color,
|
||||||
pub hl_token_constant: Color,
|
pub hl_token_constant: Color,
|
||||||
|
pub hl_token_function: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Theme {
|
impl Default for Theme {
|
||||||
|
|
@ -101,6 +102,7 @@ impl Default for Theme {
|
||||||
hl_token_string: Color::AnsiValue(179),
|
hl_token_string: Color::AnsiValue(179),
|
||||||
hl_token_special: Color::AnsiValue(160),
|
hl_token_special: Color::AnsiValue(160),
|
||||||
hl_token_constant: Color::AnsiValue(81),
|
hl_token_constant: Color::AnsiValue(81),
|
||||||
|
hl_token_function: Color::AnsiValue(122),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -123,6 +125,7 @@ impl Theme {
|
||||||
TokenKind::String => self.hl_token_string,
|
TokenKind::String => self.hl_token_string,
|
||||||
TokenKind::Special => self.hl_token_special,
|
TokenKind::Special => self.hl_token_special,
|
||||||
TokenKind::Constant => self.hl_token_constant,
|
TokenKind::Constant => self.hl_token_constant,
|
||||||
|
TokenKind::Function => self.hl_token_function,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,11 +112,15 @@ impl Element<()> for Root {
|
||||||
}
|
}
|
||||||
Action::Cancel => {
|
Action::Cancel => {
|
||||||
let unsaved = state.buffers.values().filter(|b| b.unsaved).count();
|
let unsaved = state.buffers.values().filter(|b| b.unsaved).count();
|
||||||
if unsaved == 0 {
|
if state.buffers.is_empty() {
|
||||||
return Ok(Resp::end(None));
|
return Ok(Resp::end(None));
|
||||||
} else {
|
} else {
|
||||||
self.tasks.push(Task::Confirm(Confirm {
|
self.tasks.push(Task::Confirm(Confirm {
|
||||||
label: Label(format!("Are you sure you wish to quit? (y/n). Note that {} files are unsaved!", unsaved)),
|
label: Label(if unsaved == 0 {
|
||||||
|
format!("Are you sure you wish to quit? (y/n). You have multiple documents open!")
|
||||||
|
} else {
|
||||||
|
format!("Are you sure you wish to quit? (y/n). Note that {} files are unsaved!", unsaved)
|
||||||
|
}),
|
||||||
action: Action::Quit,
|
action: Action::Quit,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue