change to pepegsitter
This commit is contained in:
parent
1346d8ddbf
commit
0e48b78f1a
18 changed files with 217 additions and 185 deletions
80
Cargo.lock
generated
80
Cargo.lock
generated
|
@ -1649,22 +1649,6 @@ dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "inkjet"
|
|
||||||
version = "0.10.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cdd9fd670f1a42725a90e7a97f5e6a777fc56f9031c1ee0ebcea8f91a6bb9c2f"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"cc",
|
|
||||||
"once_cell",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
"toml",
|
|
||||||
"tree-sitter",
|
|
||||||
"tree-sitter-highlight",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inout"
|
name = "inout"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -2203,12 +2187,13 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"careless",
|
"careless",
|
||||||
"funnylog",
|
"funnylog",
|
||||||
"inkjet",
|
|
||||||
"kdl",
|
"kdl",
|
||||||
"log",
|
"log",
|
||||||
"miette",
|
"miette",
|
||||||
"ming",
|
"ming",
|
||||||
|
"pepegsitter",
|
||||||
"serde",
|
"serde",
|
||||||
|
"tree-sitter-highlight",
|
||||||
"widestring",
|
"widestring",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2560,6 +2545,17 @@ dependencies = [
|
||||||
"hmac",
|
"hmac",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pepegsitter"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "215b00db1f5bfe7f8f1a3edb0e1ac9c4a42ffc4e50afd929c1e6a6f36d620cca"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"tree-sitter",
|
||||||
|
"tree-sitter-highlight",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
@ -2718,7 +2714,7 @@ version = "3.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
|
checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"toml_edit 0.21.1",
|
"toml_edit",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3160,15 +3156,6 @@ dependencies = [
|
||||||
"syn 2.0.63",
|
"syn 2.0.63",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_spanned"
|
|
||||||
version = "0.6.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
|
@ -3676,26 +3663,11 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml"
|
|
||||||
version = "0.8.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
"serde_spanned",
|
|
||||||
"toml_datetime",
|
|
||||||
"toml_edit 0.22.12",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.6.5"
|
version = "0.6.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
|
@ -3705,20 +3677,7 @@ checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"winnow 0.5.40",
|
"winnow",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml_edit"
|
|
||||||
version = "0.22.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef"
|
|
||||||
dependencies = [
|
|
||||||
"indexmap",
|
|
||||||
"serde",
|
|
||||||
"serde_spanned",
|
|
||||||
"toml_datetime",
|
|
||||||
"winnow 0.6.8",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4351,15 +4310,6 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winnow"
|
|
||||||
version = "0.6.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wio"
|
name = "wio"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
|
|
@ -10,10 +10,11 @@ anyhow.workspace = true
|
||||||
widestring = "1.1.0"
|
widestring = "1.1.0"
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
inkjet = { version = "0.10.5", features = ["language-rust", "language-toml", "language-zig"], default-features = false }
|
|
||||||
careless = { git = "https://codeberg.org/minky/careless", version = "0.1.0" }
|
careless = { git = "https://codeberg.org/minky/careless", version = "0.1.0" }
|
||||||
kdl = { version = "4.6.0", default-features = false }
|
kdl = { version = "4.6.0", default-features = false }
|
||||||
miette = { workspace = true, features = ["fancy"] }
|
miette = { workspace = true, features = ["fancy"] }
|
||||||
|
pepegsitter = { version = "0.2.2", features = ["tree-sitter-highlight"] }
|
||||||
|
tree-sitter-highlight = "0.20.1"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
|
|
|
@ -11,17 +11,21 @@ use std::{
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use futures::{channel::oneshot, future::{LocalBoxFuture, FutureExt}, Future};
|
use futures::{
|
||||||
|
channel::oneshot,
|
||||||
|
future::{FutureExt, LocalBoxFuture},
|
||||||
|
Future,
|
||||||
|
};
|
||||||
use slotmap::SlotMap;
|
use slotmap::SlotMap;
|
||||||
use time::UtcOffset;
|
use time::UtcOffset;
|
||||||
|
|
||||||
pub use async_context::*;
|
pub use async_context::*;
|
||||||
use collections::{FxHashMap, FxHashSet, VecDeque};
|
use collections::{FxHashMap, FxHashSet, VecDeque};
|
||||||
pub use entity_map::*;
|
pub use entity_map::*;
|
||||||
use util::http::{self, HttpClient};
|
|
||||||
pub use model_context::*;
|
pub use model_context::*;
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub use test_context::*;
|
pub use test_context::*;
|
||||||
|
use util::http::{self, HttpClient};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
|
@ -13,8 +13,8 @@ use image::{ImageBuffer, ImageError};
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use media::core_video::CVImageBuffer;
|
use media::core_video::CVImageBuffer;
|
||||||
|
|
||||||
use util::http;
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use util::http;
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
/// A source of image content.
|
/// A source of image content.
|
||||||
|
|
|
@ -14,8 +14,8 @@ use crate::{
|
||||||
use collections::VecDeque;
|
use collections::VecDeque;
|
||||||
use refineable::Refineable as _;
|
use refineable::Refineable as _;
|
||||||
use std::{cell::RefCell, ops::Range, rc::Rc};
|
use std::{cell::RefCell, ops::Range, rc::Rc};
|
||||||
use util::sum_tree::{self, Bias, SumTree};
|
|
||||||
use taffy::style::Overflow;
|
use taffy::style::Overflow;
|
||||||
|
use util::sum_tree::{self, Bias, SumTree};
|
||||||
|
|
||||||
/// Construct a new list element
|
/// Construct a new list element
|
||||||
pub fn list(state: ListState) -> List {
|
pub fn list(state: ListState) -> List {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use crate::{AppContext, PlatformDispatcher};
|
use crate::{AppContext, PlatformDispatcher};
|
||||||
|
use futures::FutureExt;
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
|
future::Future,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
mem,
|
mem,
|
||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
|
@ -14,7 +15,6 @@ use std::{
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use futures::FutureExt;
|
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use util::TryFutureExt;
|
use util::TryFutureExt;
|
||||||
use waker_fn::waker_fn;
|
use waker_fn::waker_fn;
|
||||||
|
|
|
@ -111,11 +111,11 @@ impl<T: Clone + Debug + Default> Point<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Splats a `value` across both `x` and `y`
|
/// Splats a `value` across both `x` and `y`
|
||||||
pub const fn all(value: T) -> Self where T: Copy {
|
pub const fn all(value: T) -> Self
|
||||||
Self {
|
where
|
||||||
x: value,
|
T: Copy,
|
||||||
y: value
|
{
|
||||||
}
|
Self { x: value, y: value }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms the point to a `Point<U>` by applying the given function to both coordinates.
|
/// Transforms the point to a `Point<U>` by applying the given function to both coordinates.
|
||||||
|
|
|
@ -125,18 +125,17 @@ pub use element::*;
|
||||||
pub use elements::*;
|
pub use elements::*;
|
||||||
pub use executor::*;
|
pub use executor::*;
|
||||||
pub use geometry::*;
|
pub use geometry::*;
|
||||||
pub use ming_macros::{register_action, test, IntoElement, Render};
|
|
||||||
pub use input::*;
|
pub use input::*;
|
||||||
pub use interactive::*;
|
pub use interactive::*;
|
||||||
use key_dispatch::*;
|
use key_dispatch::*;
|
||||||
pub use keymap::*;
|
pub use keymap::*;
|
||||||
|
pub use ming_macros::{register_action, test, IntoElement, Render};
|
||||||
pub use platform::*;
|
pub use platform::*;
|
||||||
pub use refineable::*;
|
pub use refineable::*;
|
||||||
pub use scene::*;
|
pub use scene::*;
|
||||||
use seal::Sealed;
|
use seal::Sealed;
|
||||||
pub use shared_string::*;
|
pub use shared_string::*;
|
||||||
pub use shared_uri::*;
|
pub use shared_uri::*;
|
||||||
pub use tokio::time::Sleep as Timer;
|
|
||||||
pub use style::*;
|
pub use style::*;
|
||||||
pub use styled::*;
|
pub use styled::*;
|
||||||
pub use subscription::*;
|
pub use subscription::*;
|
||||||
|
@ -145,6 +144,7 @@ pub use taffy::{AvailableSpace, LayoutId};
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub use test::*;
|
pub use test::*;
|
||||||
pub use text_system::*;
|
pub use text_system::*;
|
||||||
|
pub use tokio::time::Sleep as Timer;
|
||||||
pub use util::arc_cow::ArcCow;
|
pub use util::arc_cow::ArcCow;
|
||||||
pub use view::*;
|
pub use view::*;
|
||||||
pub use window::*;
|
pub use window::*;
|
||||||
|
|
|
@ -58,10 +58,10 @@ pub(crate) use cosmic_text::*;
|
||||||
pub(crate) use linux::*;
|
pub(crate) use linux::*;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub(crate) use mac::*;
|
pub(crate) use mac::*;
|
||||||
pub use util::semver::SemanticVersion;
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub(crate) use test::*;
|
pub(crate) use test::*;
|
||||||
use time::UtcOffset;
|
use time::UtcOffset;
|
||||||
|
pub use util::semver::SemanticVersion;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub(crate) use windows::*;
|
pub(crate) use windows::*;
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@ use copypasta::{ClipboardContext, ClipboardProvider};
|
||||||
use futures::channel::oneshot::{self, Receiver};
|
use futures::channel::oneshot::{self, Receiver};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use util::semver::SemanticVersion;
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use time::UtcOffset;
|
use time::UtcOffset;
|
||||||
|
use util::semver::SemanticVersion;
|
||||||
use windows::{
|
use windows::{
|
||||||
core::*,
|
core::*,
|
||||||
Wdk::System::SystemServices::*,
|
Wdk::System::SystemServices::*,
|
||||||
|
|
|
@ -652,8 +652,9 @@ impl<'de> serde::Deserialize<'de> for FontWeight {
|
||||||
where
|
where
|
||||||
E: serde::de::Error,
|
E: serde::de::Error,
|
||||||
{
|
{
|
||||||
v.parse()
|
v.parse().map_err(|()| {
|
||||||
.map_err(|()| E::custom("expected a font weight value (e.g. 'normal' or 'bold')"))
|
E::custom("expected a font weight value (e.g. 'normal' or 'bold')")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,10 @@ pub trait FluentBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Imperatively modify self with the given closure.
|
/// Imperatively modify self with the given closure.
|
||||||
fn apply(mut self, f: impl FnOnce(&mut Self)) -> Self where Self: Sized {
|
fn apply(mut self, f: impl FnOnce(&mut Self)) -> Self
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
f(&mut self);
|
f(&mut self);
|
||||||
|
|
||||||
self
|
self
|
||||||
|
|
|
@ -3,17 +3,18 @@ use proc_macro2::{Ident, Span, TokenStream};
|
||||||
use quote::{format_ident, quote, ToTokens};
|
use quote::{format_ident, quote, ToTokens};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use syn::{
|
use syn::{
|
||||||
parse2, parse_quote, punctuated::Punctuated, spanned::Spanned as _, Expr,
|
parse2, parse_quote, punctuated::Punctuated, spanned::Spanned as _, Expr, FnArg, ItemFn, Lit,
|
||||||
FnArg, ItemFn, Lit, Meta, PatLit as ExprLit, Token, Type,
|
Meta, PatLit as ExprLit, Token, Type,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn test(args: TS, function: TS) -> TS {
|
pub fn test(args: TS, function: TS) -> TS {
|
||||||
test_impl(args.into(), function.into()).map_or_else(|e| e.into_compile_error().into(), |ts| ts.into())
|
test_impl(args.into(), function.into())
|
||||||
|
.map_or_else(|e| e.into_compile_error().into(), |ts| ts.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_impl(args: TokenStream, function: TokenStream) -> syn::Result<TokenStream> {
|
fn test_impl(args: TokenStream, function: TokenStream) -> syn::Result<TokenStream> {
|
||||||
let Meta::List(args) = parse2(args)? else {
|
let Meta::List(args) = parse2(args)? else {
|
||||||
return Err(syn::Error::new(Span::call_site(), "invalid attr"))
|
return Err(syn::Error::new(Span::call_site(), "invalid attr"));
|
||||||
};
|
};
|
||||||
let mut max_retries = 0;
|
let mut max_retries = 0;
|
||||||
let mut num_iterations = 1;
|
let mut num_iterations = 1;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
pub mod arc_cow;
|
pub mod arc_cow;
|
||||||
pub mod http;
|
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
|
pub mod http;
|
||||||
pub mod paths;
|
pub mod paths;
|
||||||
pub mod serde;
|
|
||||||
pub mod semver;
|
pub mod semver;
|
||||||
|
pub mod serde;
|
||||||
pub mod sum_tree;
|
pub mod sum_tree;
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub mod test;
|
pub mod test;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use careless::prelude::*;
|
use careless::prelude::*;
|
||||||
use inkjet::tree_sitter_highlight::{Error, HighlightEvent, Highlighter};
|
use funnylog::warn;
|
||||||
use std::{ops::Range, path::PathBuf};
|
use std::{ops::Range, path::PathBuf};
|
||||||
|
use tree_sitter_highlight::{Error, HighlightConfiguration, HighlightEvent, Highlighter};
|
||||||
use widestring::Utf16String;
|
use widestring::Utf16String;
|
||||||
|
|
||||||
use crate::editor::Theme;
|
use crate::editor::{Highlight, Theme};
|
||||||
use crate::vim::Mode;
|
use crate::vim::Mode;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -15,7 +16,7 @@ pub struct Buffer {
|
||||||
pub selected: Option<Range<usize>>,
|
pub selected: Option<Range<usize>>,
|
||||||
pub name: SharedString,
|
pub name: SharedString,
|
||||||
pub modified: bool,
|
pub modified: bool,
|
||||||
pub mode: Mode
|
pub mode: Mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Buffer {
|
impl Buffer {
|
||||||
|
@ -28,7 +29,7 @@ impl Buffer {
|
||||||
marked: None,
|
marked: None,
|
||||||
selected: None,
|
selected: None,
|
||||||
modified: false,
|
modified: false,
|
||||||
mode: Mode::default()
|
mode: Mode::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,33 +41,35 @@ impl Buffer {
|
||||||
selected: None,
|
selected: None,
|
||||||
name: SharedString::from_static("<scratch>"),
|
name: SharedString::from_static("<scratch>"),
|
||||||
modified: false,
|
modified: false,
|
||||||
mode: Mode::default()
|
mode: Mode::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn styled(&self, default_style: &TextStyle, theme: &Theme) -> Vec<StyledText> {
|
pub fn styled(&self, default_style: &TextStyle, theme: &Theme) -> Vec<StyledText> {
|
||||||
let text = self.text.to_string();
|
let text = self.text.to_string();
|
||||||
|
|
||||||
if let Some(language) = self
|
if let Some(mut language) = self
|
||||||
.path
|
.path
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|path| path.extension())
|
.and_then(|path| path.extension())
|
||||||
.and_then(|extension| {
|
.and_then(|extension| {
|
||||||
inkjet::Language::from_token(extension.to_str()?).map(|lang| lang.config())
|
Language::from_token(extension.to_str()?).map(|lang| lang.config())
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
let (indices, highlights): (Vec<&str>, Vec<&Highlight>) =
|
||||||
|
theme.highlights.iter().map(|(name, hl)| (name.as_str(), hl)).unzip();
|
||||||
|
language.configure(&indices);
|
||||||
let mut hl = Highlighter::new();
|
let mut hl = Highlighter::new();
|
||||||
let mut lines = vec![];
|
let mut lines = vec![];
|
||||||
|
|
||||||
for line in text.lines() {
|
for line in text.lines() {
|
||||||
// damnation
|
// damnation
|
||||||
match hl
|
match hl
|
||||||
.highlight(language, line.as_bytes(), None, |lang| {
|
.highlight(&language, line.as_bytes(), None, |lang| None)
|
||||||
inkjet::Language::from_token(lang).map(|lang| lang.config())
|
|
||||||
})
|
|
||||||
.and_then(|hls| {
|
.and_then(|hls| {
|
||||||
Ok(StyledText::new(Arc::from(line)).with_runs(
|
Ok(StyledText::new(Arc::from(line)).with_runs(
|
||||||
MingHighlighter::new(hls, default_style, theme).try_to_collect()?,
|
MingHighlighter::new(hls, default_style, &highlights)
|
||||||
|
.try_to_collect()?,
|
||||||
))
|
))
|
||||||
}) {
|
}) {
|
||||||
Ok(styled) => lines.push(styled),
|
Ok(styled) => lines.push(styled),
|
||||||
|
@ -92,17 +95,17 @@ impl Buffer {
|
||||||
pub struct MingHighlighter<'a, I> {
|
pub struct MingHighlighter<'a, I> {
|
||||||
iter: I,
|
iter: I,
|
||||||
default_style: &'a TextStyle,
|
default_style: &'a TextStyle,
|
||||||
theme: &'a Theme,
|
highlights: &'a [&'a Highlight],
|
||||||
current_hl_idx: Option<usize>,
|
current_hl_idx: Option<usize>,
|
||||||
current_span: Option<Range<usize>>,
|
current_span: Option<Range<usize>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I> MingHighlighter<'a, I> {
|
impl<'a, I> MingHighlighter<'a, I> {
|
||||||
pub fn new(iter: I, default_style: &'a TextStyle, theme: &'a Theme) -> Self {
|
pub fn new(iter: I, default_style: &'a TextStyle, highlights: &'a [&'a Highlight]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
iter,
|
iter,
|
||||||
default_style,
|
default_style,
|
||||||
theme,
|
highlights,
|
||||||
current_hl_idx: None,
|
current_hl_idx: None,
|
||||||
current_span: None,
|
current_span: None,
|
||||||
}
|
}
|
||||||
|
@ -122,9 +125,8 @@ impl<I: Iterator<Item = Result<HighlightEvent, Error>>> Iterator for MingHighlig
|
||||||
self.current_span = Some(start..end);
|
self.current_span = Some(start..end);
|
||||||
|
|
||||||
self.default_style.to_run(end - start).apply(|run| {
|
self.default_style.to_run(end - start).apply(|run| {
|
||||||
if let Some(hl) = self
|
if let Some(hl) =
|
||||||
.current_hl_idx
|
self.current_hl_idx.and_then(|idx| self.highlights.get(idx))
|
||||||
.and_then(|idx| self.theme.highlight_indices.get(idx))
|
|
||||||
{
|
{
|
||||||
hl.apply_to_run(run)
|
hl.apply_to_run(run)
|
||||||
}
|
}
|
||||||
|
@ -143,3 +145,24 @@ impl<I: Iterator<Item = Result<HighlightEvent, Error>>> Iterator for MingHighlig
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum Language {
|
||||||
|
Rust,
|
||||||
|
Toml,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Language {
|
||||||
|
pub fn from_token(token: &str) -> Option<Self> {
|
||||||
|
Some(match token {
|
||||||
|
"rs" | "rust" => Self::Rust,
|
||||||
|
"toml" => Self::Toml,
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn config(&self) -> HighlightConfiguration {
|
||||||
|
match self {
|
||||||
|
Self::Rust => pepegsitter::rust::highlight(),
|
||||||
|
Self::Toml => pepegsitter::toml::highlight(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub struct Theme {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub background_color: Rgba,
|
pub background_color: Rgba,
|
||||||
pub text_color: Rgba,
|
pub text_color: Rgba,
|
||||||
pub highlight_indices: Vec<Highlight>,
|
pub highlights: Vec<(String, Highlight)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rgba_from_kdl(value: &KdlValue) -> miette::Result<Rgba> {
|
fn rgba_from_kdl(value: &KdlValue) -> miette::Result<Rgba> {
|
||||||
|
@ -103,18 +103,12 @@ impl Theme {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_kdl_document(document: KdlDocument) -> miette::Result<Self> {
|
pub fn from_kdl_document(document: KdlDocument) -> miette::Result<Self> {
|
||||||
let highlight_indices = match document.get("highlights").and_then(|node| node.children()) {
|
let highlights = match document.get("highlights").and_then(|node| node.children()) {
|
||||||
Some(doc) => {
|
Some(doc) => doc
|
||||||
let mut indices = vec![];
|
.nodes()
|
||||||
|
.iter()
|
||||||
for name in inkjet::constants::HIGHLIGHT_NAMES {
|
.map(|node| Highlight::from_kdl_node(node).map(|hl| (node.name().to_string(), hl)))
|
||||||
let Some(node) = doc.get(*name) else { continue };
|
.try_to_collect()?,
|
||||||
|
|
||||||
indices.push(Highlight::from_kdl_node(node)?);
|
|
||||||
}
|
|
||||||
|
|
||||||
indices
|
|
||||||
}
|
|
||||||
None => Default::default(),
|
None => Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,7 +127,7 @@ impl Theme {
|
||||||
.get_arg("text_color")
|
.get_arg("text_color")
|
||||||
.context("no background_color attr")
|
.context("no background_color attr")
|
||||||
.and_then(rgba_from_kdl)?,
|
.and_then(rgba_from_kdl)?,
|
||||||
highlight_indices,
|
highlights,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,7 +192,6 @@ impl Editor {
|
||||||
let buf = self.buf.read(cx);
|
let buf = self.buf.read(cx);
|
||||||
|
|
||||||
div()
|
div()
|
||||||
.debug()
|
|
||||||
.flex()
|
.flex()
|
||||||
.flex_row()
|
.flex_row()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
|
@ -233,16 +226,15 @@ impl Editor {
|
||||||
impl Render for Editor {
|
impl Render for Editor {
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
cx.focus(&self.focus_handle);
|
cx.focus(&self.focus_handle);
|
||||||
let styled = {
|
|
||||||
// -1 read...
|
|
||||||
let style = &self.settings.read(cx).style;
|
|
||||||
|
|
||||||
div()
|
div()
|
||||||
.font_family(style.font_family.clone())
|
.map(|div| {
|
||||||
.text_color(style.theme.text_color)
|
let style = &self.settings.read(cx).style;
|
||||||
};
|
|
||||||
|
|
||||||
styled.key_context("Editor")
|
div.font_family(style.font_family.clone())
|
||||||
|
.text_color(style.theme.text_color)
|
||||||
|
})
|
||||||
|
.key_context("Editor")
|
||||||
.on_action(cx.listener(|me, event: &action::CursorDown, cx| {
|
.on_action(cx.listener(|me, event: &action::CursorDown, cx| {
|
||||||
me.cursor.y = me.cursor.y.saturating_add(1).min(
|
me.cursor.y = me.cursor.y.saturating_add(1).min(
|
||||||
me.buf
|
me.buf
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::fmt::write;
|
use std::{any::TypeId, fmt::write};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -122,6 +122,7 @@ impl Element for EditorElement {
|
||||||
) {
|
) {
|
||||||
let focus_handle = self.editor.focus_handle(cx);
|
let focus_handle = self.editor.focus_handle(cx);
|
||||||
let key_context = self.editor.read(cx).key_context(cx);
|
let key_context = self.editor.read(cx).key_context(cx);
|
||||||
|
|
||||||
cx.set_focus_handle(&focus_handle);
|
cx.set_focus_handle(&focus_handle);
|
||||||
cx.set_key_context(key_context);
|
cx.set_key_context(key_context);
|
||||||
cx.handle_input(
|
cx.handle_input(
|
||||||
|
@ -129,68 +130,124 @@ impl Element for EditorElement {
|
||||||
ElementInputHandler::new(bounds, self.editor.clone()),
|
ElementInputHandler::new(bounds, self.editor.clone()),
|
||||||
);
|
);
|
||||||
|
|
||||||
let view = self.editor.clone();
|
let styled_bounds: Arc<[Bounds<Pixels>]> = Arc::from(
|
||||||
let font_size = self.style.font_size.to_pixels(px(4.));
|
request_layout
|
||||||
let hb = prepaint.hb.clone();
|
.styled
|
||||||
|
.iter()
|
||||||
|
.map(|(_, _, b)| *b)
|
||||||
|
.collect::<Vec<Bounds<Pixels>>>(),
|
||||||
|
);
|
||||||
|
|
||||||
let styled_bounds = request_layout
|
cx.on_action(TypeId::of::<action::CursorUp>(), {
|
||||||
.styled
|
let view = self.editor.clone();
|
||||||
.iter()
|
let styled_bounds = styled_bounds.clone();
|
||||||
.map(|(_, _, b)| *b)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
cx.on_mouse_event(move |scroll: &ScrollWheelEvent, dispatch, cx| {
|
move |_event, _dispatch, cx| {
|
||||||
if !dispatch.bubble() || !hb.is_hovered(cx) {
|
view.update(cx, |editor, cx| {
|
||||||
return;
|
if editor.cursor.y == 0 {
|
||||||
}
|
return;
|
||||||
|
|
||||||
view.update(cx, |editor, cx| {
|
|
||||||
let prev_editor_scroll = editor.scroll;
|
|
||||||
let change = match scroll.delta {
|
|
||||||
ScrollDelta::Lines(pnt) => {
|
|
||||||
let mut lines = pnt.y.abs();
|
|
||||||
let mut do_scroll = px(0.);
|
|
||||||
|
|
||||||
for bounds in styled_bounds.iter() {
|
|
||||||
if lines <= 1. {
|
|
||||||
do_scroll += px(bounds.size.height.0 * lines);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
do_scroll += bounds.size.height;
|
|
||||||
lines -= 1.;
|
|
||||||
}
|
|
||||||
|
|
||||||
point(px(0.), do_scroll * pnt.y.signum())
|
|
||||||
}
|
}
|
||||||
ScrollDelta::Pixels(pix) => pix,
|
|
||||||
};
|
|
||||||
|
|
||||||
editor.scroll = (editor.scroll + change).clamp(
|
editor.cursor.y = editor.cursor.y.saturating_sub(1);
|
||||||
&point(bounds.size.width, bounds.size.height).negate(),
|
|
||||||
&Point::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let prev_ruler = editor.ruler;
|
let line_bounds = styled_bounds
|
||||||
let next_ruler = (editor.scroll.y.0 / bounds.size.height.0 * 100.).abs().floor() as u8;
|
.iter()
|
||||||
|
.take(editor.cursor.y)
|
||||||
|
.fold(px(0.), |px, bounds| px + bounds.size.height);
|
||||||
|
|
||||||
if prev_ruler != next_ruler {
|
if line_bounds > bounds.size.height {
|
||||||
editor.ruler = next_ruler;
|
editor.scroll.y = -line_bounds;
|
||||||
cx.notify();
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
log::trace!(
|
|
||||||
"[{prev_editor_scroll:#?} -> {:#?}] [{prev_ruler}% -> {next_ruler}%] {scroll:#?}",
|
|
||||||
editor.scroll
|
|
||||||
);
|
|
||||||
|
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if !change.is_zero() {
|
cx.on_action(TypeId::of::<action::CursorDown>(), {
|
||||||
cx.refresh();
|
let view = self.editor.clone();
|
||||||
|
let styled_bounds = styled_bounds.clone();
|
||||||
|
|
||||||
|
move |_event, _dispatch, cx| {
|
||||||
|
view.update(cx, |editor, cx| {
|
||||||
|
if editor.cursor.y == editor.buf.read(cx).text.chars().filter(|char| *char == '\n').count() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.cursor.y += 1;
|
||||||
|
|
||||||
|
let line_bounds = styled_bounds
|
||||||
|
.iter()
|
||||||
|
.take(editor.cursor.y)
|
||||||
|
.fold(px(0.), |px, bounds| px + bounds.size.height);
|
||||||
|
|
||||||
|
if line_bounds > bounds.size.height {
|
||||||
|
editor.scroll.y = -line_bounds;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.stop_propagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.on_mouse_event({
|
||||||
|
let view = self.editor.clone();
|
||||||
|
let hb = prepaint.hb.clone();
|
||||||
|
let styled_bounds = styled_bounds.clone();
|
||||||
|
|
||||||
|
move |scroll: &ScrollWheelEvent, dispatch, cx| {
|
||||||
|
if !dispatch.bubble() || !hb.is_hovered(cx) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
view.update(cx, |editor, cx| {
|
||||||
|
let prev_editor_scroll = editor.scroll;
|
||||||
|
let change = match scroll.delta {
|
||||||
|
ScrollDelta::Lines(pnt) => {
|
||||||
|
let mut lines = pnt.y.abs();
|
||||||
|
let mut do_scroll = px(0.);
|
||||||
|
|
||||||
|
for bounds in styled_bounds.iter() {
|
||||||
|
if lines <= 1. {
|
||||||
|
do_scroll += px(bounds.size.height.0 * lines);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_scroll += bounds.size.height;
|
||||||
|
lines -= 1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
point(px(0.), do_scroll * pnt.y.signum())
|
||||||
|
}
|
||||||
|
ScrollDelta::Pixels(pix) => pix,
|
||||||
|
};
|
||||||
|
|
||||||
|
editor.scroll = (editor.scroll + change).clamp(
|
||||||
|
&point(bounds.size.width, bounds.size.height).negate(),
|
||||||
|
&Point::default(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let prev_ruler = editor.ruler;
|
||||||
|
let next_ruler = (editor.scroll.y.0 / bounds.size.height.0 * 100.).abs().floor() as u8;
|
||||||
|
|
||||||
|
if prev_ruler != next_ruler {
|
||||||
|
editor.ruler = next_ruler;
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
log::trace!(
|
||||||
|
"[{prev_editor_scroll:#?} -> {:#?}] [{prev_ruler}% -> {next_ruler}%] {scroll:#?}",
|
||||||
|
editor.scroll
|
||||||
|
);
|
||||||
|
|
||||||
|
cx.stop_propagation();
|
||||||
|
|
||||||
|
if !change.is_zero() {
|
||||||
|
cx.refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.with_text_style(
|
cx.with_text_style(
|
||||||
|
|
|
@ -3,5 +3,5 @@ pub enum Mode {
|
||||||
#[default]
|
#[default]
|
||||||
Normal,
|
Normal,
|
||||||
Insert,
|
Insert,
|
||||||
Visual
|
Visual,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue