From 11a1fa6a17f1ff1ff33cd4b35dd385598b67ce86 Mon Sep 17 00:00:00 2001 From: mars Date: Wed, 12 Apr 2023 12:39:22 -0400 Subject: [PATCH 1/8] Add syntect and parking_lot deps --- Cargo.lock | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 6 ++ 2 files changed, 207 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b37b28..2ee1316 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "arg" version = "0.4.1" @@ -18,7 +24,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "849efc162c06e51ce911bf4fe702f62a08f3b6ebbbfc5178e86c6bae449c2c60" dependencies = [ "quote", - "syn", + "syn 1.0.109", "tabwriter", ] @@ -28,6 +34,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bindgen" version = "0.63.0" @@ -46,7 +61,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn", + "syn 1.0.109", "which", ] @@ -64,11 +79,19 @@ dependencies = [ "crossterm", "libc", "once_cell", + "parking_lot", "ropey", + "syntect", "toml", "yacexits", ] +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "cexpr" version = "0.6.0" @@ -95,6 +118,15 @@ dependencies = [ "libloading", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossterm" version = "0.26.1" @@ -126,6 +158,22 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "glob" version = "0.3.1" @@ -148,6 +196,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + [[package]] name = "lazy_static" version = "1.4.0" @@ -207,6 +261,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.6" @@ -235,6 +298,28 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[package]] +name = "onig" +version = "6.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f" +dependencies = [ + "bitflags", + "libc", + "once_cell", + "onig_sys", +] + +[[package]] +name = "onig_sys" +version = "69.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -264,6 +349,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + [[package]] name = "proc-macro2" version = "1.0.56" @@ -322,6 +413,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -334,6 +440,28 @@ version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +[[package]] +name = "serde_derive" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.14", +] + +[[package]] +name = "serde_json" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_spanned" version = "0.6.1" @@ -402,6 +530,38 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf316d5356ed6847742d036f8a39c3b8435cac10bd528a4bd461928a6ab34d5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syntect" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c454c27d9d7d9a84c7803aaa3c50cd088d2906fe3c6e42da3209aa623576a8" +dependencies = [ + "bincode", + "bitflags", + "flate2", + "fnv", + "lazy_static", + "once_cell", + "onig", + "regex-syntax", + "serde", + "serde_derive", + "serde_json", + "thiserror", + "walkdir", +] + [[package]] name = "tabwriter" version = "1.2.1" @@ -411,6 +571,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.14", +] + [[package]] name = "toml" version = "0.7.3" @@ -457,6 +637,16 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -490,6 +680,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index aca0966..ebd31f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,12 @@ arg = "0.4.1" crossterm = "0.26" libc = "0.2.141" once_cell = "1.17" +parking_lot = "0.12" ropey = "1.6" toml = "0.7" yacexits = "0.1.5" + +[dependencies.syntect] +version = "5" +default-features = false +features = ["default-syntaxes", "parsing", "regex-onig"] From ce13258ca719f45c8e7f536a75caf62259b353a3 Mon Sep 17 00:00:00 2001 From: mars Date: Wed, 12 Apr 2023 12:40:06 -0400 Subject: [PATCH 2/8] Make Style::print_styled() generic over Display --- src/theme.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/theme.rs b/src/theme.rs index 5235321..5ff0210 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -17,8 +17,8 @@ * along with this program. If not, see https://www.gnu.org/licenses/. */ -use std::collections::HashMap; use std::io::Write; +use std::{collections::HashMap, fmt::Display}; use crossterm::{style::Color, ExecutableCommand}; use once_cell::sync::Lazy; @@ -124,7 +124,7 @@ impl Style { pub fn print_styled( &self, out: &mut (impl ExecutableCommand + Write), - content: &str, + content: impl Display, ) -> crossterm::Result<()> { use crossterm::style::{ResetColor, SetBackgroundColor, SetForegroundColor}; From 86bbfcda60572af99a2e7e5089032af2d12a533b Mon Sep 17 00:00:00 2001 From: mars Date: Wed, 12 Apr 2023 12:40:16 -0400 Subject: [PATCH 3/8] Add Style::apply() --- src/theme.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/theme.rs b/src/theme.rs index 5ff0210..ae65b4c 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -142,6 +142,17 @@ impl Style { Ok(()) } + + /// Applies another [Style] on top of this one. + pub fn apply(&mut self, other: &Style) { + if other.fg.is_some() { + self.fg = other.fg; + } + + if other.bg.is_some() { + self.bg = other.bg; + } + } } #[derive(Clone, Debug, Default)] From 78b24c4203933817d5f80bc970d9b87418beb3a3 Mon Sep 17 00:00:00 2001 From: mars Date: Wed, 12 Apr 2023 12:40:39 -0400 Subject: [PATCH 4/8] Support 0-length scopes --- src/theme.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/theme.rs b/src/theme.rs index ae65b4c..dec9bb8 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -197,7 +197,7 @@ impl Theme { let mut longest_len = 0; for (target, style) in self.styles.iter() { - if target.len() > longest_len && scope.starts_with(target) { + if target.len() >= longest_len && scope.starts_with(target) { longest = *style; longest_len = target.len(); } From 71377441222b4339fc2cb8c34fe6ac12827db64f Mon Sep 17 00:00:00 2001 From: mars Date: Wed, 12 Apr 2023 12:41:08 -0400 Subject: [PATCH 5/8] Merge palette table with default palette --- src/theme.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/theme.rs b/src/theme.rs index dec9bb8..2f31278 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -254,15 +254,13 @@ impl TryFrom for Palette { value ))?; - let default = Self::default(); - let mut palette = HashMap::with_capacity(values.len()); - + let mut default = Self::default(); for (name, value) in values { let color = default.parse_color(value)?; - palette.insert(name.to_string(), color); + default.palette.insert(name.to_string(), color); } - Ok(Self { palette }) + Ok(default) } } From 51622bf6fda5caa323c5f73e4904d7fca50c1b79 Mon Sep 17 00:00:00 2001 From: mars Date: Wed, 12 Apr 2023 12:41:22 -0400 Subject: [PATCH 6/8] Ignore style modifiers and underline for now --- src/theme.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/theme.rs b/src/theme.rs index 2f31278..72c6768 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -301,6 +301,8 @@ impl Palette { match name.as_str() { "fg" => style.fg = Some(self.parse_color(&value)?), "bg" => style.bg = Some(self.parse_color(&value)?), + "modifiers" => {} // ignore for now + "underline" => {} // ignore for now _ => return Err(format!("Theme: invalid style attribute: {}", name)), } } From 3d03c90c7b6aecfe482a94320d7f3f87ef0cab21 Mon Sep 17 00:00:00 2001 From: mars Date: Wed, 12 Apr 2023 12:52:46 -0400 Subject: [PATCH 7/8] WIP syntax highlighting --- src/buffer.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++++--- src/main.rs | 19 +++++---- 2 files changed, 110 insertions(+), 13 deletions(-) diff --git a/src/buffer.rs b/src/buffer.rs index 37d6d30..47957b3 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -18,23 +18,45 @@ */ use std::io::Write; +use std::ops::Range; +use std::sync::Arc; use crossterm::{cursor, ExecutableCommand}; +use parking_lot::Mutex; use ropey::Rope; +use syntect::easy::ScopeRangeIterator; +use syntect::parsing::{ParseState, Scope, ScopeStack, SyntaxSet}; -use crate::theme::StyleStore; +use crate::theme::{Style, StyleStore}; use crate::{Cursor, Direction}; #[derive(Clone, Debug)] pub struct Buffer { + styles: Arc>, text: Rope, + syntax_set: Arc, + parser: ParseState, + styled: Vec)>>, } impl Buffer { - pub fn from_str(text: &str) -> Self { - Self { + pub fn from_str(styles: Arc>, text: &str) -> Self { + let syntax_set = SyntaxSet::load_defaults_nonewlines(); + // TODO load non-Rust syntax highlighting + let syntax_ref = syntax_set.find_syntax_by_extension("rs").unwrap(); + let parser = ParseState::new(syntax_ref); + + let mut buf = Self { + styles, text: Rope::from_str(text), - } + syntax_set: Arc::new(SyntaxSet::load_defaults_newlines()), + parser, + styled: Vec::new(), + }; + + buf.parse(); + + buf } pub fn draw( @@ -63,11 +85,24 @@ impl Buffer { linenr_style.print_styled(out, &linenr)?; let lhs = scroll.column; - let width = line.len_chars().saturating_sub(1); // lop off whitespace + let width = line.len_chars(); if lhs < width { let window = text_width.min(width - lhs); let rhs = lhs + window; - write!(out, "{}", line.slice(lhs..rhs))?; + let styled = &self.styled[row]; + for (style, range) in styled.iter() { + let range = range.start.max(lhs)..range.end.min(rhs); + if range.start < range.end { + // this range is in view so display + let content = line.slice(range.clone()); + style.print_styled(out, content)?; + } + + if range.end >= rhs { + // past the end of the window so we're done + break; + } + } } out.execute(cursor::MoveToNextLine(1))?; @@ -79,11 +114,55 @@ impl Buffer { pub fn remove(&mut self, cursor: Cursor) { let index = self.cursor_to_char(cursor); self.text.remove(index..=index); + self.parse(); } pub fn insert_char(&mut self, cursor: Cursor, c: char) { let index = self.cursor_to_char(cursor); self.text.insert_char(index, c); + self.parse(); + } + + /// Parses the whole file from scratch. + fn parse(&mut self) { + use std::fmt::Write; + let mut styles = self.styles.lock(); + self.styled.clear(); + let mut parser = self.parser.clone(); + let mut line_buf = String::new(); + let mut stack = ScopeStack::new(); + for line in self.text.lines() { + // display line to a pre-allocated buffer for fast parsing + line_buf.clear(); + write!(line_buf, "{}", line).unwrap(); + let end = line_buf.trim_end().len(); + line_buf.truncate(end); + + // parse the line into a sequence of stack operations + let stack_ops = parser.parse_line(&line_buf, &self.syntax_set).unwrap(); + + // execute the operations on the stack + let mut line = Vec::new(); + let range_iter = ScopeRangeIterator::new(&stack_ops, &line_buf); + for (range, op) in range_iter { + stack.apply(&op).unwrap(); + + if range.start == range.end { + continue; + } + + let mut style = Style::default(); + for scope in stack.scopes.clone() { + // TODO docs say that build_string "shouldn't be done frequently" + let scope = scope.build_string(); + style.apply(&styles.get_scope(&scope)); + } + + line.push((style, range)); + } + + self.styled.push(line); + } } pub fn clamped_cursor(&self, cursor: Cursor) -> Cursor { @@ -136,3 +215,16 @@ impl Buffer { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn style_scopes() { + let text = include_str!("buffer.rs"); + let mut buffer = Buffer::from_str(Default::default(), text); + buffer.parse(); + println!("{:#?}", buffer.styled); + } +} diff --git a/src/main.rs b/src/main.rs index 7ce333c..b92ec14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,6 +22,7 @@ use std::{ fs::File, io::{stdout, Read, Stdout, Write}, os::fd::FromRawFd, + sync::Arc, }; use crossterm::{ @@ -29,6 +30,7 @@ use crossterm::{ event::{read, Event, KeyCode, KeyEvent}, terminal, ExecutableCommand, Result, }; +use parking_lot::Mutex; use yacexits::{exit, EX_DATAERR, EX_UNAVAILABLE}; mod buffer; @@ -94,7 +96,7 @@ pub enum Direction { } struct State { - pub style_store: StyleStore, + pub styles: Arc>, pub buffer: Buffer, pub cursor: Cursor, pub scroll: Cursor, @@ -105,11 +107,13 @@ struct State { impl State { pub fn from_str(text: &str) -> Result { + let styles = Arc::new(Mutex::new(StyleStore::default())); + let buffer = Buffer::from_str(styles.clone(), text); let (cols, rows) = terminal::size()?; Ok(Self { - style_store: StyleStore::default(), - buffer: Buffer::from_str(text), + styles, + buffer, cursor: Cursor::default(), scroll: Cursor::default(), size: (cols as usize, rows as usize), @@ -123,6 +127,7 @@ impl State { let (cols, rows) = terminal::size()?; out.execute(terminal::BeginSynchronizedUpdate)?; out.execute(terminal::Clear(terminal::ClearType::All))?; + let mut styles = self.styles.lock(); // draw status line let mut set_cursor_pos = None; @@ -138,7 +143,7 @@ impl State { show_status_bar = true; } Mode::Normal(NormalState { error: Some(error) }) => { - let error_style = self.style_store.get_scope("error"); + let error_style = styles.get_scope("error"); out.execute(cursor::MoveTo(0, rows - 1))?; error_style.print_styled(out, error)?; show_status_bar = true; @@ -148,9 +153,9 @@ impl State { // draw buffer let buffer_rows = if show_status_bar { rows - 1 } else { rows }; - let lr_width = - self.buffer - .draw(&mut self.style_store, cols, buffer_rows, self.scroll, out)?; + let lr_width = self + .buffer + .draw(&mut styles, cols, buffer_rows, self.scroll, out)?; // draw cursor let cursor_pos = set_cursor_pos.unwrap_or_else(|| { From 539360114a351ad4e03c037ecb74f7a85e1b966a Mon Sep 17 00:00:00 2001 From: mars Date: Wed, 12 Apr 2023 12:53:11 -0400 Subject: [PATCH 8/8] WIP Rose Pine default theme --- default_theme.toml | 92 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/default_theme.toml b/default_theme.toml index be3ce26..6100e3c 100644 --- a/default_theme.toml +++ b/default_theme.toml @@ -1,3 +1,93 @@ "ui.linenr" = "gray" -"error" = "red" +"error" = "love" + +"attribute" = "iris" + +"type" = "foam" +# "type.builtin" = "" + +"constructor" = "foam" + + +"comment" = { fg = "muted", modifiers = ["italic"]} +"constant" = "foam" +"constant.builtin" = "rose" +"constant.character" = "gold" +"constant.character.escape" = "pine" +"constant.numeric" = "gold" +"entity.name" = "rose" +"invalid" = "love" +"keyword" = "pine" +"keyword.operator" = "subtle" +"label" = "foam" +"operator" = "subtle" +"punctuation" = "subtle" +"string" = "gold" +# "string.regexp" = "" +# "string.special" = "" +# "string.special.path" = "" +# "string.special.url" = "" +# "string.special.symbol" = "" +"variable" = "text" +"variable.builtin" = "love" +"variable.parameter" = "iris" + +"markup.heading.marker" = "muted" +"markup.heading" = { fg = "iris", modifiers = ["bold"] } +"markup.heading.1" = { fg = "iris", modifiers = ["bold"] } +"markup.heading.2" = { fg = "foam", modifiers = ["bold"] } +"markup.heading.3" = { fg = "rose", modifiers = ["bold"] } +"markup.heading.4" = { fg = "gold", modifiers = ["bold"] } +"markup.heading.5" = { fg = "pine", modifiers = ["bold"] } +"markup.heading.6" = { fg = "foam", modifiers = ["bold"] } +# "markup.heading.completion" = "" +# "markup.heading.hover" = "" +"markup.list" = "muted" +# "markup.list.unnumbered" = "" +# "markup.list.numbered" = "" +"markup.bold" = { modifiers = ["bold"] } +"markup.italic" = { modifiers = ["italic"] } +"markup.strikethrough" = { modifiers = ["crossed_out"] } +"markup.link" = "iris" +"markup.link.url" = { fg = "iris", underline = { color = "iris", style = "line" } } +"markup.link.label" = "subtle" +"markup.link.text" = "text" +"markup.quote" = "subtle" +"markup.raw" = "subtle" +# "markup.raw.inline" = {} +# "markup.raw.inline.completion" = {} +# "markup.raw.inline.hover" = {} +# "markup.raw.block" = {} +# "markup.normal" = "" +# "markup.normal.completion" = "" +# "markup.normal.hover" = "" + +"diff" = "overlay" +"diff.plus" = "foam" +"diff.minus" = "love" +"diff.delta" = "highlight_high" +# "diff.delta.moved" = "" + +[palette] +base = "#191724" +surface = "#1f1d2e" +overlay = "#26233a" +muted = "#6e6a86" +subtle = "#908caa" +text = "#e0def4" +love = "#eb6f92" +love_10 = "#311f30" +gold = "#f6c177" +gold_10 = "#30282c" +rose = "#ebbcba" +rose_10 = "#2f2834" +pine = "#31748f" +pine_10 = "#1a2030" +foam = "#9ccfd8" +foam_10 = "#252937" +iris = "#c4a7e7" +iris_10 = "#2b2539" +highlight_low = "#21202e" +highlight_med = "#403d52" +highlight_high = "#524f67" \ No newline at end of file