SCROLLING!!!!!!!!!!!
This commit is contained in:
parent
20889e9d1f
commit
ebe77bd035
13 changed files with 370 additions and 101 deletions
109
Cargo.lock
generated
109
Cargo.lock
generated
|
@ -306,6 +306,15 @@ dependencies = [
|
|||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace-ext"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
|
@ -1278,7 +1287,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"funnylog-macros",
|
||||
"log",
|
||||
"owo-colors",
|
||||
"owo-colors 4.0.0",
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
|
@ -1684,6 +1693,17 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-wsl"
|
||||
version = "0.4.0"
|
||||
|
@ -1694,6 +1714,12 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_ci"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
|
||||
|
||||
[[package]]
|
||||
name = "isahc"
|
||||
version = "1.7.2"
|
||||
|
@ -1980,8 +2006,17 @@ version = "5.10.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"backtrace-ext",
|
||||
"is-terminal",
|
||||
"miette-derive",
|
||||
"once_cell",
|
||||
"owo-colors 3.5.0",
|
||||
"supports-color",
|
||||
"supports-hyperlinks",
|
||||
"supports-unicode",
|
||||
"terminal_size",
|
||||
"textwrap",
|
||||
"thiserror",
|
||||
"unicode-width",
|
||||
]
|
||||
|
@ -2032,6 +2067,7 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"linkme",
|
||||
"log",
|
||||
"miette",
|
||||
"ming_macros",
|
||||
"num_cpus",
|
||||
"oo7",
|
||||
|
@ -2168,7 +2204,9 @@ dependencies = [
|
|||
"careless",
|
||||
"funnylog",
|
||||
"inkjet",
|
||||
"kdl",
|
||||
"log",
|
||||
"miette",
|
||||
"ming",
|
||||
"serde",
|
||||
"widestring",
|
||||
|
@ -2440,6 +2478,12 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "4.0.0"
|
||||
|
@ -3105,14 +3149,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_kdl"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"kdl",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.19"
|
||||
|
@ -3220,6 +3256,12 @@ version = "1.13.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "smawk"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
|
||||
|
||||
[[package]]
|
||||
name = "smithay-client-toolkit"
|
||||
version = "0.18.1"
|
||||
|
@ -3329,6 +3371,34 @@ version = "2.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||
|
||||
[[package]]
|
||||
name = "supports-color"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89"
|
||||
dependencies = [
|
||||
"is-terminal",
|
||||
"is_ci",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "supports-hyperlinks"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f84231692eb0d4d41e4cdd0cabfdd2e6cd9e255e65f80c9aa7c98dd502b4233d"
|
||||
dependencies = [
|
||||
"is-terminal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "supports-unicode"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f850c19edd184a205e883199a261ed44471c81e39bd95b1357f5febbef00e77a"
|
||||
dependencies = [
|
||||
"is-terminal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "svg_fmt"
|
||||
version = "0.4.2"
|
||||
|
@ -3427,6 +3497,27 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "terminal_size"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d"
|
||||
dependencies = [
|
||||
"smawk",
|
||||
"unicode-linebreak",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.60"
|
||||
|
|
|
@ -12,6 +12,8 @@ log.workspace = true
|
|||
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" }
|
||||
kdl = { version = "4.6.0", default-features = false }
|
||||
miette = { workspace = true, features = ["fancy"] }
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
|
@ -30,7 +32,6 @@ license = "GPL-3.0"
|
|||
collections.path = "crates/collections"
|
||||
ming.path = "crates/ming"
|
||||
ming_macros.path = "crates/ming_macros"
|
||||
serde_kdl.path = "crates/serde_kdl"
|
||||
refineable.path = "crates/refineable"
|
||||
util.path = "crates/util"
|
||||
|
||||
|
@ -48,6 +49,7 @@ tempfile = "3.9"
|
|||
unicase = "2.6"
|
||||
derive_more = "0.99.17"
|
||||
anyhow = "1"
|
||||
miette = "5.7.0"
|
||||
ctor = "0.2.6"
|
||||
log = "0.4"
|
||||
itertools = "0.12"
|
||||
|
|
|
@ -10,6 +10,9 @@ The following list of features and tasks required to have them is highly opinion
|
|||
|
||||
- [ ] Barebones editor
|
||||
* [x] Make it compile
|
||||
* [x] Treesitter
|
||||
* [x] Scrolling
|
||||
* [ ] Cursor
|
||||
- [ ] Vim-like keybindings and motions
|
||||
- [ ] A Telescope-ey file finder
|
||||
- [ ] Something like [harpoon](https://github.com/theprimeagen/harpoon) and maybe a topbar with marks
|
||||
|
|
|
@ -62,6 +62,7 @@ util.workspace = true
|
|||
uuid.workspace = true
|
||||
waker-fn = "1.1.0"
|
||||
smol = "2.0.0"
|
||||
miette.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
backtrace = "0.3"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::bail;
|
||||
use miette::{bail, IntoDiagnostic};
|
||||
use serde::de::{self, Deserialize, Deserializer, Visitor};
|
||||
use std::fmt;
|
||||
|
||||
|
@ -132,7 +132,7 @@ impl From<Hsla> for Rgba {
|
|||
}
|
||||
|
||||
impl TryFrom<&'_ str> for Rgba {
|
||||
type Error = anyhow::Error;
|
||||
type Error = miette::Error;
|
||||
|
||||
fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
|
||||
const RGB: usize = "rgb".len();
|
||||
|
@ -148,11 +148,11 @@ impl TryFrom<&'_ str> for Rgba {
|
|||
|
||||
let (r, g, b, a) = match hex.len() {
|
||||
RGB | RGBA => {
|
||||
let r = u8::from_str_radix(&hex[0..1], 16)?;
|
||||
let g = u8::from_str_radix(&hex[1..2], 16)?;
|
||||
let b = u8::from_str_radix(&hex[2..3], 16)?;
|
||||
let r = u8::from_str_radix(&hex[0..1], 16).into_diagnostic()?;
|
||||
let g = u8::from_str_radix(&hex[1..2], 16).into_diagnostic()?;
|
||||
let b = u8::from_str_radix(&hex[2..3], 16).into_diagnostic()?;
|
||||
let a = if hex.len() == RGBA {
|
||||
u8::from_str_radix(&hex[3..4], 16)?
|
||||
u8::from_str_radix(&hex[3..4], 16).into_diagnostic()?
|
||||
} else {
|
||||
0xf
|
||||
};
|
||||
|
@ -166,11 +166,11 @@ impl TryFrom<&'_ str> for Rgba {
|
|||
(duplicate(r), duplicate(g), duplicate(b), duplicate(a))
|
||||
}
|
||||
RRGGBB | RRGGBBAA => {
|
||||
let r = u8::from_str_radix(&hex[0..2], 16)?;
|
||||
let g = u8::from_str_radix(&hex[2..4], 16)?;
|
||||
let b = u8::from_str_radix(&hex[4..6], 16)?;
|
||||
let r = u8::from_str_radix(&hex[0..2], 16).into_diagnostic()?;
|
||||
let g = u8::from_str_radix(&hex[2..4], 16).into_diagnostic()?;
|
||||
let b = u8::from_str_radix(&hex[4..6], 16).into_diagnostic()?;
|
||||
let a = if hex.len() == RRGGBBAA {
|
||||
u8::from_str_radix(&hex[6..8], 16)?
|
||||
u8::from_str_radix(&hex[6..8], 16).into_diagnostic()?
|
||||
} else {
|
||||
0xff
|
||||
};
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
[package]
|
||||
name = "serde_kdl"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
kdl = "4.6.0"
|
||||
serde.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
|
@ -1,14 +0,0 @@
|
|||
pub fn add(left: usize, right: usize) -> usize {
|
||||
left + right
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
|
@ -15,9 +15,9 @@ lazy_static::lazy_static! {
|
|||
} else if cfg!(target_os = "linux") {
|
||||
dirs::config_dir()
|
||||
.expect("failed to determine XDG_CONFIG_HOME directory")
|
||||
.join("zed")
|
||||
.join("nite")
|
||||
} else {
|
||||
HOME.join(".config").join("zed")
|
||||
HOME.join(".config").join("nite")
|
||||
};
|
||||
pub static ref CONVERSATIONS_DIR: PathBuf = if cfg!(target_os = "macos") {
|
||||
CONFIG_DIR.join("conversations")
|
||||
|
@ -36,7 +36,7 @@ lazy_static::lazy_static! {
|
|||
} else if cfg!(target_os = "linux") {
|
||||
dirs::data_local_dir()
|
||||
.expect("failed to determine XDG_DATA_DIR directory")
|
||||
.join("zed")
|
||||
.join("nite")
|
||||
} else if cfg!(target_os = "windows") {
|
||||
dirs::data_local_dir()
|
||||
.expect("failed to determine LocalAppData directory")
|
||||
|
@ -67,8 +67,8 @@ lazy_static::lazy_static! {
|
|||
pub static ref LAST_USERNAME: PathBuf = CONFIG_DIR.join("last-username.txt");
|
||||
pub static ref LOG: PathBuf = LOGS_DIR.join("Zed.log");
|
||||
pub static ref OLD_LOG: PathBuf = LOGS_DIR.join("Zed.log.old");
|
||||
pub static ref LOCAL_SETTINGS_RELATIVE_PATH: &'static Path = Path::new(".zed/settings.json");
|
||||
pub static ref LOCAL_TASKS_RELATIVE_PATH: &'static Path = Path::new(".zed/tasks.json");
|
||||
pub static ref LOCAL_SETTINGS_RELATIVE_PATH: &'static Path = Path::new(".nite/settings.json");
|
||||
pub static ref LOCAL_TASKS_RELATIVE_PATH: &'static Path = Path::new(".nite/tasks.json");
|
||||
pub static ref LOCAL_VSCODE_TASKS_RELATIVE_PATH: &'static Path = Path::new(".vscode/tasks.json");
|
||||
pub static ref TEMP_DIR: PathBuf = if cfg!(target_os = "windows") {
|
||||
dirs::cache_dir()
|
||||
|
@ -77,9 +77,9 @@ lazy_static::lazy_static! {
|
|||
} else if cfg!(target_os = "linux") {
|
||||
dirs::cache_dir()
|
||||
.expect("failed to determine XDG_CACHE_HOME directory")
|
||||
.join("zed")
|
||||
.join("nite")
|
||||
} else {
|
||||
HOME.join(".cache").join("zed")
|
||||
HOME.join(".cache").join("nite")
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -612,7 +612,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn project_search() {
|
||||
let path = Path::new("/Users/someonetoignore/work/zed/zed.dev/node_modules");
|
||||
let path = Path::new("/Users/someonetoignore/work/nite/nite.dev/node_modules");
|
||||
let path_matcher = PathMatcher::new("**/node_modules/**").unwrap();
|
||||
assert!(
|
||||
path_matcher.is_match(path),
|
||||
|
|
110
src/editor.rs
110
src/editor.rs
|
@ -1,6 +1,8 @@
|
|||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use careless::{try_f64_to_f32, try_iter::TryIterator, TryOption};
|
||||
use kdl::*;
|
||||
use miette::{bail, IntoDiagnostic};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -11,16 +13,51 @@ pub struct EditorSettings {
|
|||
style: EditorStyle,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Highlight {
|
||||
pub color: Option<Rgba>,
|
||||
#[serde(default)]
|
||||
pub style: Option<FontStyle>,
|
||||
#[serde(default)]
|
||||
pub weight: Option<FontWeight>,
|
||||
}
|
||||
|
||||
impl Highlight {
|
||||
pub fn from_kdl_node(node: &KdlNode) -> miette::Result<Self> {
|
||||
Ok(Self {
|
||||
color: TryOption::from_opt(node.get(0).or_else(|| node.get("color")))
|
||||
.and_then_res(|entry| rgba_from_kdl(entry.value()))
|
||||
.into_result_opt()?,
|
||||
style: TryOption::<_, miette::Error>::from_opt(node.get("style"))
|
||||
.and_then_res(|entry| {
|
||||
entry
|
||||
.value()
|
||||
.as_string()
|
||||
.context("style value wasn't a string")
|
||||
})
|
||||
.and_then_res(|str| {
|
||||
Ok(if str.eq_ignore_ascii_case("normal") {
|
||||
FontStyle::Normal
|
||||
} else if str.eq_ignore_ascii_case("italic") {
|
||||
FontStyle::Italic
|
||||
} else if str.eq_ignore_ascii_case("oblique") {
|
||||
FontStyle::Oblique
|
||||
} else {
|
||||
bail!("invalid FontStyle value: {str}")
|
||||
})
|
||||
})
|
||||
.into_result_opt()?,
|
||||
weight: TryOption::from_opt(node.get("weight"))
|
||||
.map(|entry| entry.value())
|
||||
.and_then(|value| {
|
||||
TryOption::from_opt(value.as_f64()).and_then_res(|value| {
|
||||
try_f64_to_f32(value)
|
||||
.context("font weight value (f64) didn't fit into a f32")
|
||||
.map(FontWeight)
|
||||
})
|
||||
})
|
||||
.into_result_opt()?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn apply_to_run(&self, run: &mut TextRun) {
|
||||
if let Some(color) = self.color {
|
||||
run.color = color.into();
|
||||
|
@ -36,24 +73,67 @@ impl Highlight {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Theme {
|
||||
pub name: String,
|
||||
pub background_color: Rgba,
|
||||
pub text_color: Rgba,
|
||||
pub highlights: HashMap<String, Highlight>,
|
||||
#[serde(skip)]
|
||||
pub highlight_indices: Vec<Highlight>
|
||||
pub highlight_indices: Vec<Highlight>,
|
||||
}
|
||||
|
||||
fn rgba_from_kdl(value: &KdlValue) -> miette::Result<Rgba> {
|
||||
if let Some(i64) = value.as_i64() {
|
||||
Ok(rgba(
|
||||
i64.try_into()
|
||||
.into_diagnostic()
|
||||
.context("number too big to fit in a u32")?,
|
||||
))
|
||||
} else if let Some(str) = value.as_string() {
|
||||
Rgba::try_from(str)
|
||||
} else {
|
||||
bail!("invalid KdlValue for Rgba: {value}")
|
||||
}
|
||||
}
|
||||
|
||||
impl Theme {
|
||||
pub fn load(text: &str) -> Result<Self, kaydle::serde::de::Error> {
|
||||
kaydle::serde::from_str(text).map(|mut me: Self| {
|
||||
me.highlight_indices = inkjet::constants::HIGHLIGHT_NAMES.iter().flat_map(|hl| {
|
||||
me.highlights.get(*hl).cloned()
|
||||
}).collect();
|
||||
pub fn load(text: &str) -> miette::Result<Self> {
|
||||
let kdl = text.parse()?;
|
||||
|
||||
me
|
||||
Self::from_kdl_document(kdl)
|
||||
}
|
||||
|
||||
pub fn from_kdl_document(document: KdlDocument) -> miette::Result<Self> {
|
||||
let highlight_indices = match document.get("highlights").and_then(|node| node.children()) {
|
||||
Some(doc) => {
|
||||
let mut indices = vec![];
|
||||
|
||||
for name in inkjet::constants::HIGHLIGHT_NAMES {
|
||||
let Some(node) = doc.get(*name) else { continue };
|
||||
|
||||
indices.push(Highlight::from_kdl_node(node)?);
|
||||
}
|
||||
|
||||
indices
|
||||
}
|
||||
None => Default::default(),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
name: document
|
||||
.get_arg("name")
|
||||
.context("no name attr")?
|
||||
.as_string()
|
||||
.context("name wasn't a string")?
|
||||
.to_string(),
|
||||
background_color: document
|
||||
.get_arg("background_color")
|
||||
.context("no background_color attr")
|
||||
.and_then(rgba_from_kdl)?,
|
||||
text_color: document
|
||||
.get_arg("text_color")
|
||||
.context("no background_color attr")
|
||||
.and_then(rgba_from_kdl)?,
|
||||
highlight_indices,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +187,7 @@ impl Editor {
|
|||
settings,
|
||||
logger,
|
||||
cursor: Point::default(),
|
||||
scroll: Point::default()
|
||||
scroll: Point::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::fmt::write;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub struct EditorElement {
|
||||
|
@ -22,7 +24,9 @@ impl IntoElement for EditorElement {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct EditorLayout {}
|
||||
pub struct EditorLayout {
|
||||
hb: Hitbox,
|
||||
}
|
||||
pub struct EditorRequestLayout {
|
||||
styled: Vec<(LayoutId, StyledText, Bounds<Pixels>)>,
|
||||
}
|
||||
|
@ -45,6 +49,7 @@ impl Element for EditorElement {
|
|||
&TextStyle {
|
||||
font_size: self.style.font_size,
|
||||
font_family: self.style.font_family.clone(),
|
||||
color: editor.settings.read(cx).style.theme.text_color.into(),
|
||||
..Default::default()
|
||||
},
|
||||
&self.style.theme,
|
||||
|
@ -89,10 +94,22 @@ impl Element for EditorElement {
|
|||
request_layout
|
||||
.styled
|
||||
.iter_mut()
|
||||
.for_each(|(_id, styled, bounds)| styled.prepaint(None, *bounds, &mut (), cx));
|
||||
.for_each(|(id, styled, bounds)| {
|
||||
styled.prepaint(
|
||||
None,
|
||||
{
|
||||
*bounds = cx.layout_bounds(*id);
|
||||
*bounds
|
||||
},
|
||||
&mut (),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
});
|
||||
|
||||
EditorLayout {}
|
||||
EditorLayout {
|
||||
hb: cx.insert_hitbox(bounds, true),
|
||||
}
|
||||
}
|
||||
|
||||
fn paint(
|
||||
|
@ -114,15 +131,56 @@ impl Element for EditorElement {
|
|||
|
||||
let view = self.editor.clone();
|
||||
let font_size = self.style.font_size.to_pixels(px(4.));
|
||||
cx.on_mouse_event(move |scroll: &ScrollWheelEvent, _dispatch, cx| {
|
||||
log::trace!("{scroll:#?}");
|
||||
view.update(cx, |editor, cx| match scroll.delta {
|
||||
ScrollDelta::Lines(lines) => {
|
||||
let hb = prepaint.hb.clone();
|
||||
|
||||
}
|
||||
ScrollDelta::Pixels(pix) => {
|
||||
let px_y = (pix.y.ceil().0 / font_size.0) as i32;
|
||||
editor.cursor.y = editor.cursor.y.saturating_add_signed(px_y as isize)
|
||||
let styled_bounds = request_layout
|
||||
.styled
|
||||
.iter()
|
||||
.map(|(_, _, b)| *b)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
cx.on_mouse_event(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(),
|
||||
);
|
||||
|
||||
log::trace!(
|
||||
"[{prev_editor_scroll:#?} -> {:#?}] {scroll:#?}",
|
||||
editor.scroll
|
||||
);
|
||||
|
||||
cx.stop_propagation();
|
||||
|
||||
if !change.is_zero() {
|
||||
cx.refresh();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -133,14 +191,12 @@ impl Element for EditorElement {
|
|||
..Default::default()
|
||||
}),
|
||||
|cx| {
|
||||
cx.with_element_offset(self.editor.read(cx).scroll, |cx| {
|
||||
request_layout
|
||||
.styled
|
||||
.iter_mut()
|
||||
.for_each(|(_id, styled, bounds)| {
|
||||
styled.paint(None, *bounds, &mut (), &mut (), cx)
|
||||
});
|
||||
});
|
||||
request_layout
|
||||
.styled
|
||||
.iter_mut()
|
||||
.for_each(|(_id, styled, bounds)| {
|
||||
styled.paint(None, *bounds, &mut (), &mut (), cx)
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -3,11 +3,22 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use funnylog::{filter::LevelFilter, span, Drain, Level};
|
||||
use ming::{*, prelude::*};
|
||||
use miette::{Diagnostic, Report, WrapErr};
|
||||
use ming::{prelude::*, *, Context};
|
||||
|
||||
mod buffer;
|
||||
mod editor;
|
||||
|
||||
trait MietteContext<T> {
|
||||
fn context(self, msg: impl std::fmt::Display + std::fmt::Debug + Send + Sync + 'static) -> Result<T, Report>;
|
||||
}
|
||||
|
||||
impl<T> MietteContext<T> for Option<T> {
|
||||
fn context(self, msg: impl std::fmt::Display + std::fmt::Debug + Send + Sync + 'static) -> Result<T, Report> {
|
||||
self.ok_or_else(|| Report::msg(msg))
|
||||
}
|
||||
}
|
||||
|
||||
struct Nite {
|
||||
editor: View<editor::Editor>,
|
||||
logger: Logger,
|
||||
|
@ -37,6 +48,7 @@ impl Render for Nite {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
miette::set_panic_hook();
|
||||
let drain = Arc::new(
|
||||
funnylog::terminal::TerminalConfig::default()
|
||||
.to_stderr()
|
||||
|
|
|
@ -1,24 +1,50 @@
|
|||
|
||||
|
||||
|
||||
name "Catppuccin Mocha"
|
||||
background_color "#1e1e2e"
|
||||
text_color "#cdd6f4"
|
||||
highlights {
|
||||
attribute "#f9e2af"
|
||||
boolean "#fab387"
|
||||
comment "#7f849c"
|
||||
comment.doc "#7f849c"
|
||||
comment "#7f849c" font_style="italic"
|
||||
comment.doc "#7f849c" font_style="italic"
|
||||
constant "#fab387"
|
||||
constructor "#89b4fa"
|
||||
embedded "#eba0ac"
|
||||
emphasis "#f38ba8"
|
||||
emphasis "#f38ba8" font_style="italic"
|
||||
emphasis.strong "#f38ba8" font_weight=700
|
||||
enum "#94e2d5" font_weight=700
|
||||
function "#89b4fa"
|
||||
hint "#94e2d5"
|
||||
function "#89b4fa" font_style="italic"
|
||||
hint "#94e2d5" font_style="italic"
|
||||
keyword "#cba6f7"
|
||||
link_text "#89b4fa"
|
||||
link_uri "#89b4fa"
|
||||
number "#fab387"
|
||||
operator "#89dceb"
|
||||
predictive "#585b70"
|
||||
predoc "#f38ba8"
|
||||
primary "#eba0ac"
|
||||
property "#89b4fa"
|
||||
punctuation "#94e2d5"
|
||||
punctuation.bracket "#94e2d5"
|
||||
punctuation.delimiter "#9399b2"
|
||||
punctuation.list_marker "#94e2d5"
|
||||
punctuation.special "#94e2d5"
|
||||
punctuation.special.symbol "#f38ba8"
|
||||
string "#a6e3a1"
|
||||
string.escape "#f5c2e7"
|
||||
string.regex "#f5c2e7"
|
||||
string.special "#f5c2e7"
|
||||
string.special.symbol "#f2cdcd"
|
||||
tag "#89b4fa"
|
||||
text.literal "#a6e3a1"
|
||||
title "#cdd6f4"
|
||||
type "#f9e2af"
|
||||
type.interface "#f9e2af"
|
||||
type.super "#f9e2af"
|
||||
variable "#cdd6f4"
|
||||
variable.member "#cdd6f4"
|
||||
variable.parameter "#cdd6f4"
|
||||
variable.special "#dcb8d5" font_style="italic"
|
||||
variant "#f38ba8"
|
||||
}
|
|
@ -7,16 +7,13 @@ whiskers:
|
|||
- accent
|
||||
filename: "{{flavor.identifier}}-{{accent}}{{variant}}.kdl"
|
||||
---
|
||||
|
||||
{%set c = flavor.colors-%}
|
||||
{%set accent = c[accent]-%}
|
||||
|
||||
{%if variant == "-no-italics"%}
|
||||
{%set italic = "font_style=italic"-%}
|
||||
{%else%}
|
||||
{%set italic = ""-%}
|
||||
{%else%}
|
||||
{%set italic = 'font_style="italic"'-%}
|
||||
{%endif%}
|
||||
|
||||
name "Catppuccin {{flavor.name}} {%- if variant == "-no-italics" %} (no italics) {%- endif -%}"
|
||||
background_color "#{{c.base.hex}}"
|
||||
text_color "#{{c.text.hex}}"
|
||||
|
@ -37,4 +34,31 @@ highlights {
|
|||
link_text "#{{c.blue.hex}}"
|
||||
link_uri "#{{c.blue.hex}}"
|
||||
number "#{{c.peach.hex}}"
|
||||
operator "#{{c.sky.hex}}"
|
||||
predictive "#{{c.surface2.hex}}"
|
||||
predoc "#{{c.red.hex}}"
|
||||
primary "#{{c.maroon.hex}}"
|
||||
property "#{{c.blue.hex}}"
|
||||
punctuation "#{{c.teal.hex}}"
|
||||
punctuation.bracket "#{{c.teal.hex}}"
|
||||
punctuation.delimiter "#{{c.overlay2.hex}}"
|
||||
punctuation.list_marker "#{{c.teal.hex}}"
|
||||
punctuation.special "#{{c.teal.hex}}"
|
||||
punctuation.special.symbol "#{{c.red.hex}}"
|
||||
string "#{{c.green.hex}}"
|
||||
string.escape "#{{c.pink.hex}}"
|
||||
string.regex "#{{c.pink.hex}}"
|
||||
string.special "#{{c.pink.hex}}"
|
||||
string.special.symbol "#{{c.flamingo.hex}}"
|
||||
tag "#{{c.blue.hex}}"
|
||||
text.literal "#{{c.green.hex}}"
|
||||
title "#{{c.text.hex}}"
|
||||
type "#{{c.yellow.hex}}"
|
||||
type.interface "#{{c.yellow.hex}}"
|
||||
type.super "#{{c.yellow.hex}}"
|
||||
variable "#{{c.text.hex}}"
|
||||
variable.member "#{{c.text.hex}}"
|
||||
variable.parameter "#{{c.text.hex}}"
|
||||
variable.special "#{{ c.text | mix(color=c.red,amount=0.6) | get(key='hex') }}" {{italic}}
|
||||
variant "#{{c.red.hex}}"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue