diff --git a/Cargo.lock b/Cargo.lock index be24b23..82525bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index e065d7e..376f0c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/README.md b/README.md index e8f686d..8311e28 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/crates/ming/Cargo.toml b/crates/ming/Cargo.toml index 44d5b87..755116e 100644 --- a/crates/ming/Cargo.toml +++ b/crates/ming/Cargo.toml @@ -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" diff --git a/crates/ming/src/color.rs b/crates/ming/src/color.rs index 5767b5c..c1557d4 100644 --- a/crates/ming/src/color.rs +++ b/crates/ming/src/color.rs @@ -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 for Rgba { } impl TryFrom<&'_ str> for Rgba { - type Error = anyhow::Error; + type Error = miette::Error; fn try_from(value: &'_ str) -> Result { 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 }; diff --git a/crates/serde_kdl/Cargo.toml b/crates/serde_kdl/Cargo.toml deleted file mode 100644 index 0d78872..0000000 --- a/crates/serde_kdl/Cargo.toml +++ /dev/null @@ -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 diff --git a/crates/serde_kdl/src/lib.rs b/crates/serde_kdl/src/lib.rs deleted file mode 100644 index 7d12d9a..0000000 --- a/crates/serde_kdl/src/lib.rs +++ /dev/null @@ -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); - } -} diff --git a/crates/util/src/paths.rs b/crates/util/src/paths.rs index e43c60a..e5bbedd 100644 --- a/crates/util/src/paths.rs +++ b/crates/util/src/paths.rs @@ -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), diff --git a/src/editor.rs b/src/editor.rs index 6c4bf70..d5d14fe 100644 --- a/src/editor.rs +++ b/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, - #[serde(default)] pub style: Option, - #[serde(default)] pub weight: Option, } impl Highlight { + pub fn from_kdl_node(node: &KdlNode) -> miette::Result { + 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, - #[serde(skip)] - pub highlight_indices: Vec + pub highlight_indices: Vec, +} + +fn rgba_from_kdl(value: &KdlValue) -> miette::Result { + 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 { - 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 { + let kdl = text.parse()?; - me + Self::from_kdl_document(kdl) + } + + pub fn from_kdl_document(document: KdlDocument) -> miette::Result { + 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(), }) } } diff --git a/src/editor/element.rs b/src/editor/element.rs index decb5ce..8fa40d8 100644 --- a/src/editor/element.rs +++ b/src/editor/element.rs @@ -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)>, } @@ -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) => { - - } - 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 hb = prepaint.hb.clone(); + + let styled_bounds = request_layout + .styled + .iter() + .map(|(_, _, b)| *b) + .collect::>(); + + 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) + }); }, ); } diff --git a/src/main.rs b/src/main.rs index 957e844..d4a9d87 100644 --- a/src/main.rs +++ b/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 { + fn context(self, msg: impl std::fmt::Display + std::fmt::Debug + Send + Sync + 'static) -> Result; +} + +impl MietteContext for Option { + fn context(self, msg: impl std::fmt::Display + std::fmt::Debug + Send + Sync + 'static) -> Result { + self.ok_or_else(|| Report::msg(msg)) + } +} + struct Nite { editor: View, 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() diff --git a/themes/catppuccin/mocha-teal.kdl b/themes/catppuccin/mocha-teal.kdl index e67fdac..cbfd38a 100644 --- a/themes/catppuccin/mocha-teal.kdl +++ b/themes/catppuccin/mocha-teal.kdl @@ -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" } \ No newline at end of file diff --git a/themes/catppuccin/nite.tera b/themes/catppuccin/nite.tera index 237331a..98afae6 100644 --- a/themes/catppuccin/nite.tera +++ b/themes/catppuccin/nite.tera @@ -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}}" }