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",
|
"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]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.22.1"
|
version = "0.22.1"
|
||||||
|
@ -1278,7 +1287,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"funnylog-macros",
|
"funnylog-macros",
|
||||||
"log",
|
"log",
|
||||||
"owo-colors",
|
"owo-colors 4.0.0",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1684,6 +1693,17 @@ dependencies = [
|
||||||
"once_cell",
|
"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]]
|
[[package]]
|
||||||
name = "is-wsl"
|
name = "is-wsl"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -1694,6 +1714,12 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_ci"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "isahc"
|
name = "isahc"
|
||||||
version = "1.7.2"
|
version = "1.7.2"
|
||||||
|
@ -1980,8 +2006,17 @@ version = "5.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e"
|
checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
"backtrace-ext",
|
||||||
|
"is-terminal",
|
||||||
"miette-derive",
|
"miette-derive",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"owo-colors 3.5.0",
|
||||||
|
"supports-color",
|
||||||
|
"supports-hyperlinks",
|
||||||
|
"supports-unicode",
|
||||||
|
"terminal_size",
|
||||||
|
"textwrap",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
@ -2032,6 +2067,7 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"linkme",
|
"linkme",
|
||||||
"log",
|
"log",
|
||||||
|
"miette",
|
||||||
"ming_macros",
|
"ming_macros",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"oo7",
|
"oo7",
|
||||||
|
@ -2168,7 +2204,9 @@ dependencies = [
|
||||||
"careless",
|
"careless",
|
||||||
"funnylog",
|
"funnylog",
|
||||||
"inkjet",
|
"inkjet",
|
||||||
|
"kdl",
|
||||||
"log",
|
"log",
|
||||||
|
"miette",
|
||||||
"ming",
|
"ming",
|
||||||
"serde",
|
"serde",
|
||||||
"widestring",
|
"widestring",
|
||||||
|
@ -2440,6 +2478,12 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "owo-colors"
|
||||||
|
version = "3.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "owo-colors"
|
name = "owo-colors"
|
||||||
version = "4.0.0"
|
version = "4.0.0"
|
||||||
|
@ -3105,14 +3149,6 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_kdl"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"kdl",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_repr"
|
name = "serde_repr"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
|
@ -3220,6 +3256,12 @@ version = "1.13.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smawk"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay-client-toolkit"
|
name = "smithay-client-toolkit"
|
||||||
version = "0.18.1"
|
version = "0.18.1"
|
||||||
|
@ -3329,6 +3371,34 @@ version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
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]]
|
[[package]]
|
||||||
name = "svg_fmt"
|
name = "svg_fmt"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
@ -3427,6 +3497,27 @@ dependencies = [
|
||||||
"winapi-util",
|
"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]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.60"
|
version = "1.0.60"
|
||||||
|
|
|
@ -12,6 +12,8 @@ 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 }
|
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 }
|
||||||
|
miette = { workspace = true, features = ["fancy"] }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
|
@ -30,7 +32,6 @@ license = "GPL-3.0"
|
||||||
collections.path = "crates/collections"
|
collections.path = "crates/collections"
|
||||||
ming.path = "crates/ming"
|
ming.path = "crates/ming"
|
||||||
ming_macros.path = "crates/ming_macros"
|
ming_macros.path = "crates/ming_macros"
|
||||||
serde_kdl.path = "crates/serde_kdl"
|
|
||||||
refineable.path = "crates/refineable"
|
refineable.path = "crates/refineable"
|
||||||
util.path = "crates/util"
|
util.path = "crates/util"
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ tempfile = "3.9"
|
||||||
unicase = "2.6"
|
unicase = "2.6"
|
||||||
derive_more = "0.99.17"
|
derive_more = "0.99.17"
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
miette = "5.7.0"
|
||||||
ctor = "0.2.6"
|
ctor = "0.2.6"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
itertools = "0.12"
|
itertools = "0.12"
|
||||||
|
|
|
@ -10,6 +10,9 @@ The following list of features and tasks required to have them is highly opinion
|
||||||
|
|
||||||
- [ ] Barebones editor
|
- [ ] Barebones editor
|
||||||
* [x] Make it compile
|
* [x] Make it compile
|
||||||
|
* [x] Treesitter
|
||||||
|
* [x] Scrolling
|
||||||
|
* [ ] Cursor
|
||||||
- [ ] Vim-like keybindings and motions
|
- [ ] Vim-like keybindings and motions
|
||||||
- [ ] A Telescope-ey file finder
|
- [ ] A Telescope-ey file finder
|
||||||
- [ ] Something like [harpoon](https://github.com/theprimeagen/harpoon) and maybe a topbar with marks
|
- [ ] Something like [harpoon](https://github.com/theprimeagen/harpoon) and maybe a topbar with marks
|
||||||
|
|
|
@ -62,6 +62,7 @@ util.workspace = true
|
||||||
uuid.workspace = true
|
uuid.workspace = true
|
||||||
waker-fn = "1.1.0"
|
waker-fn = "1.1.0"
|
||||||
smol = "2.0.0"
|
smol = "2.0.0"
|
||||||
|
miette.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
backtrace = "0.3"
|
backtrace = "0.3"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::bail;
|
use miette::{bail, IntoDiagnostic};
|
||||||
use serde::de::{self, Deserialize, Deserializer, Visitor};
|
use serde::de::{self, Deserialize, Deserializer, Visitor};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ impl From<Hsla> for Rgba {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&'_ str> for Rgba {
|
impl TryFrom<&'_ str> for Rgba {
|
||||||
type Error = anyhow::Error;
|
type Error = miette::Error;
|
||||||
|
|
||||||
fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
|
fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
|
||||||
const RGB: usize = "rgb".len();
|
const RGB: usize = "rgb".len();
|
||||||
|
@ -148,11 +148,11 @@ impl TryFrom<&'_ str> for Rgba {
|
||||||
|
|
||||||
let (r, g, b, a) = match hex.len() {
|
let (r, g, b, a) = match hex.len() {
|
||||||
RGB | RGBA => {
|
RGB | RGBA => {
|
||||||
let r = u8::from_str_radix(&hex[0..1], 16)?;
|
let r = u8::from_str_radix(&hex[0..1], 16).into_diagnostic()?;
|
||||||
let g = u8::from_str_radix(&hex[1..2], 16)?;
|
let g = u8::from_str_radix(&hex[1..2], 16).into_diagnostic()?;
|
||||||
let b = u8::from_str_radix(&hex[2..3], 16)?;
|
let b = u8::from_str_radix(&hex[2..3], 16).into_diagnostic()?;
|
||||||
let a = if hex.len() == RGBA {
|
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 {
|
} else {
|
||||||
0xf
|
0xf
|
||||||
};
|
};
|
||||||
|
@ -166,11 +166,11 @@ impl TryFrom<&'_ str> for Rgba {
|
||||||
(duplicate(r), duplicate(g), duplicate(b), duplicate(a))
|
(duplicate(r), duplicate(g), duplicate(b), duplicate(a))
|
||||||
}
|
}
|
||||||
RRGGBB | RRGGBBAA => {
|
RRGGBB | RRGGBBAA => {
|
||||||
let r = u8::from_str_radix(&hex[0..2], 16)?;
|
let r = u8::from_str_radix(&hex[0..2], 16).into_diagnostic()?;
|
||||||
let g = u8::from_str_radix(&hex[2..4], 16)?;
|
let g = u8::from_str_radix(&hex[2..4], 16).into_diagnostic()?;
|
||||||
let b = u8::from_str_radix(&hex[4..6], 16)?;
|
let b = u8::from_str_radix(&hex[4..6], 16).into_diagnostic()?;
|
||||||
let a = if hex.len() == RRGGBBAA {
|
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 {
|
} else {
|
||||||
0xff
|
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") {
|
} else if cfg!(target_os = "linux") {
|
||||||
dirs::config_dir()
|
dirs::config_dir()
|
||||||
.expect("failed to determine XDG_CONFIG_HOME directory")
|
.expect("failed to determine XDG_CONFIG_HOME directory")
|
||||||
.join("zed")
|
.join("nite")
|
||||||
} else {
|
} else {
|
||||||
HOME.join(".config").join("zed")
|
HOME.join(".config").join("nite")
|
||||||
};
|
};
|
||||||
pub static ref CONVERSATIONS_DIR: PathBuf = if cfg!(target_os = "macos") {
|
pub static ref CONVERSATIONS_DIR: PathBuf = if cfg!(target_os = "macos") {
|
||||||
CONFIG_DIR.join("conversations")
|
CONFIG_DIR.join("conversations")
|
||||||
|
@ -36,7 +36,7 @@ lazy_static::lazy_static! {
|
||||||
} else if cfg!(target_os = "linux") {
|
} else if cfg!(target_os = "linux") {
|
||||||
dirs::data_local_dir()
|
dirs::data_local_dir()
|
||||||
.expect("failed to determine XDG_DATA_DIR directory")
|
.expect("failed to determine XDG_DATA_DIR directory")
|
||||||
.join("zed")
|
.join("nite")
|
||||||
} else if cfg!(target_os = "windows") {
|
} else if cfg!(target_os = "windows") {
|
||||||
dirs::data_local_dir()
|
dirs::data_local_dir()
|
||||||
.expect("failed to determine LocalAppData directory")
|
.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 LAST_USERNAME: PathBuf = CONFIG_DIR.join("last-username.txt");
|
||||||
pub static ref LOG: PathBuf = LOGS_DIR.join("Zed.log");
|
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 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_SETTINGS_RELATIVE_PATH: &'static Path = Path::new(".nite/settings.json");
|
||||||
pub static ref LOCAL_TASKS_RELATIVE_PATH: &'static Path = Path::new(".zed/tasks.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 LOCAL_VSCODE_TASKS_RELATIVE_PATH: &'static Path = Path::new(".vscode/tasks.json");
|
||||||
pub static ref TEMP_DIR: PathBuf = if cfg!(target_os = "windows") {
|
pub static ref TEMP_DIR: PathBuf = if cfg!(target_os = "windows") {
|
||||||
dirs::cache_dir()
|
dirs::cache_dir()
|
||||||
|
@ -77,9 +77,9 @@ lazy_static::lazy_static! {
|
||||||
} else if cfg!(target_os = "linux") {
|
} else if cfg!(target_os = "linux") {
|
||||||
dirs::cache_dir()
|
dirs::cache_dir()
|
||||||
.expect("failed to determine XDG_CACHE_HOME directory")
|
.expect("failed to determine XDG_CACHE_HOME directory")
|
||||||
.join("zed")
|
.join("nite")
|
||||||
} else {
|
} else {
|
||||||
HOME.join(".cache").join("zed")
|
HOME.join(".cache").join("nite")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,7 +612,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn project_search() {
|
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();
|
let path_matcher = PathMatcher::new("**/node_modules/**").unwrap();
|
||||||
assert!(
|
assert!(
|
||||||
path_matcher.is_match(path),
|
path_matcher.is_match(path),
|
||||||
|
|
110
src/editor.rs
110
src/editor.rs
|
@ -1,6 +1,8 @@
|
||||||
use std::{collections::HashMap, path::PathBuf};
|
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::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -11,16 +13,51 @@ pub struct EditorSettings {
|
||||||
style: EditorStyle,
|
style: EditorStyle,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct Highlight {
|
pub struct Highlight {
|
||||||
pub color: Option<Rgba>,
|
pub color: Option<Rgba>,
|
||||||
#[serde(default)]
|
|
||||||
pub style: Option<FontStyle>,
|
pub style: Option<FontStyle>,
|
||||||
#[serde(default)]
|
|
||||||
pub weight: Option<FontWeight>,
|
pub weight: Option<FontWeight>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Highlight {
|
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) {
|
pub fn apply_to_run(&self, run: &mut TextRun) {
|
||||||
if let Some(color) = self.color {
|
if let Some(color) = self.color {
|
||||||
run.color = color.into();
|
run.color = color.into();
|
||||||
|
@ -36,24 +73,67 @@ impl Highlight {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Theme {
|
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 highlights: HashMap<String, Highlight>,
|
pub highlight_indices: Vec<Highlight>,
|
||||||
#[serde(skip)]
|
}
|
||||||
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 {
|
impl Theme {
|
||||||
pub fn load(text: &str) -> Result<Self, kaydle::serde::de::Error> {
|
pub fn load(text: &str) -> miette::Result<Self> {
|
||||||
kaydle::serde::from_str(text).map(|mut me: Self| {
|
let kdl = text.parse()?;
|
||||||
me.highlight_indices = inkjet::constants::HIGHLIGHT_NAMES.iter().flat_map(|hl| {
|
|
||||||
me.highlights.get(*hl).cloned()
|
|
||||||
}).collect();
|
|
||||||
|
|
||||||
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,
|
settings,
|
||||||
logger,
|
logger,
|
||||||
cursor: Point::default(),
|
cursor: Point::default(),
|
||||||
scroll: Point::default()
|
scroll: Point::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::fmt::write;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub struct EditorElement {
|
pub struct EditorElement {
|
||||||
|
@ -22,7 +24,9 @@ impl IntoElement for EditorElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EditorLayout {}
|
pub struct EditorLayout {
|
||||||
|
hb: Hitbox,
|
||||||
|
}
|
||||||
pub struct EditorRequestLayout {
|
pub struct EditorRequestLayout {
|
||||||
styled: Vec<(LayoutId, StyledText, Bounds<Pixels>)>,
|
styled: Vec<(LayoutId, StyledText, Bounds<Pixels>)>,
|
||||||
}
|
}
|
||||||
|
@ -45,6 +49,7 @@ impl Element for EditorElement {
|
||||||
&TextStyle {
|
&TextStyle {
|
||||||
font_size: self.style.font_size,
|
font_size: self.style.font_size,
|
||||||
font_family: self.style.font_family.clone(),
|
font_family: self.style.font_family.clone(),
|
||||||
|
color: editor.settings.read(cx).style.theme.text_color.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
&self.style.theme,
|
&self.style.theme,
|
||||||
|
@ -89,10 +94,22 @@ impl Element for EditorElement {
|
||||||
request_layout
|
request_layout
|
||||||
.styled
|
.styled
|
||||||
.iter_mut()
|
.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(
|
fn paint(
|
||||||
|
@ -114,15 +131,56 @@ impl Element for EditorElement {
|
||||||
|
|
||||||
let view = self.editor.clone();
|
let view = self.editor.clone();
|
||||||
let font_size = self.style.font_size.to_pixels(px(4.));
|
let font_size = self.style.font_size.to_pixels(px(4.));
|
||||||
cx.on_mouse_event(move |scroll: &ScrollWheelEvent, _dispatch, cx| {
|
let hb = prepaint.hb.clone();
|
||||||
log::trace!("{scroll:#?}");
|
|
||||||
view.update(cx, |editor, cx| match scroll.delta {
|
let styled_bounds = request_layout
|
||||||
ScrollDelta::Lines(lines) => {
|
.styled
|
||||||
|
.iter()
|
||||||
}
|
.map(|(_, _, b)| *b)
|
||||||
ScrollDelta::Pixels(pix) => {
|
.collect::<Vec<_>>();
|
||||||
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)
|
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()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
|cx| {
|
|cx| {
|
||||||
cx.with_element_offset(self.editor.read(cx).scroll, |cx| {
|
request_layout
|
||||||
request_layout
|
.styled
|
||||||
.styled
|
.iter_mut()
|
||||||
.iter_mut()
|
.for_each(|(_id, styled, bounds)| {
|
||||||
.for_each(|(_id, styled, bounds)| {
|
styled.paint(None, *bounds, &mut (), &mut (), cx)
|
||||||
styled.paint(None, *bounds, &mut (), &mut (), cx)
|
});
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -3,11 +3,22 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use funnylog::{filter::LevelFilter, span, Drain, Level};
|
use funnylog::{filter::LevelFilter, span, Drain, Level};
|
||||||
use ming::{*, prelude::*};
|
use miette::{Diagnostic, Report, WrapErr};
|
||||||
|
use ming::{prelude::*, *, Context};
|
||||||
|
|
||||||
mod buffer;
|
mod buffer;
|
||||||
mod editor;
|
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 {
|
struct Nite {
|
||||||
editor: View<editor::Editor>,
|
editor: View<editor::Editor>,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
|
@ -37,6 +48,7 @@ impl Render for Nite {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
miette::set_panic_hook();
|
||||||
let drain = Arc::new(
|
let drain = Arc::new(
|
||||||
funnylog::terminal::TerminalConfig::default()
|
funnylog::terminal::TerminalConfig::default()
|
||||||
.to_stderr()
|
.to_stderr()
|
||||||
|
|
|
@ -1,24 +1,50 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
name "Catppuccin Mocha"
|
name "Catppuccin Mocha"
|
||||||
background_color "#1e1e2e"
|
background_color "#1e1e2e"
|
||||||
text_color "#cdd6f4"
|
text_color "#cdd6f4"
|
||||||
highlights {
|
highlights {
|
||||||
attribute "#f9e2af"
|
attribute "#f9e2af"
|
||||||
boolean "#fab387"
|
boolean "#fab387"
|
||||||
comment "#7f849c"
|
comment "#7f849c" font_style="italic"
|
||||||
comment.doc "#7f849c"
|
comment.doc "#7f849c" font_style="italic"
|
||||||
constant "#fab387"
|
constant "#fab387"
|
||||||
constructor "#89b4fa"
|
constructor "#89b4fa"
|
||||||
embedded "#eba0ac"
|
embedded "#eba0ac"
|
||||||
emphasis "#f38ba8"
|
emphasis "#f38ba8" font_style="italic"
|
||||||
emphasis.strong "#f38ba8" font_weight=700
|
emphasis.strong "#f38ba8" font_weight=700
|
||||||
enum "#94e2d5" font_weight=700
|
enum "#94e2d5" font_weight=700
|
||||||
function "#89b4fa"
|
function "#89b4fa" font_style="italic"
|
||||||
hint "#94e2d5"
|
hint "#94e2d5" font_style="italic"
|
||||||
keyword "#cba6f7"
|
keyword "#cba6f7"
|
||||||
link_text "#89b4fa"
|
link_text "#89b4fa"
|
||||||
link_uri "#89b4fa"
|
link_uri "#89b4fa"
|
||||||
number "#fab387"
|
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
|
- accent
|
||||||
filename: "{{flavor.identifier}}-{{accent}}{{variant}}.kdl"
|
filename: "{{flavor.identifier}}-{{accent}}{{variant}}.kdl"
|
||||||
---
|
---
|
||||||
|
|
||||||
{%set c = flavor.colors-%}
|
{%set c = flavor.colors-%}
|
||||||
{%set accent = c[accent]-%}
|
{%set accent = c[accent]-%}
|
||||||
|
|
||||||
{%if variant == "-no-italics"%}
|
{%if variant == "-no-italics"%}
|
||||||
{%set italic = "font_style=italic"-%}
|
|
||||||
{%else%}
|
|
||||||
{%set italic = ""-%}
|
{%set italic = ""-%}
|
||||||
|
{%else%}
|
||||||
|
{%set italic = 'font_style="italic"'-%}
|
||||||
{%endif%}
|
{%endif%}
|
||||||
|
|
||||||
name "Catppuccin {{flavor.name}} {%- if variant == "-no-italics" %} (no italics) {%- endif -%}"
|
name "Catppuccin {{flavor.name}} {%- if variant == "-no-italics" %} (no italics) {%- endif -%}"
|
||||||
background_color "#{{c.base.hex}}"
|
background_color "#{{c.base.hex}}"
|
||||||
text_color "#{{c.text.hex}}"
|
text_color "#{{c.text.hex}}"
|
||||||
|
@ -37,4 +34,31 @@ highlights {
|
||||||
link_text "#{{c.blue.hex}}"
|
link_text "#{{c.blue.hex}}"
|
||||||
link_uri "#{{c.blue.hex}}"
|
link_uri "#{{c.blue.hex}}"
|
||||||
number "#{{c.peach.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