mirror of
https://github.com/helix-editor/helix.git
synced 2025-10-06 00:13:28 +02:00
Compare commits
11 Commits
bump_imara
...
expand-std
Author | SHA1 | Date | |
---|---|---|---|
|
6d8e874da1 | ||
|
ab9e36069b | ||
|
c68016081a | ||
|
ab97585b69 | ||
|
9dbfb9b4eb | ||
|
091f19f67c | ||
|
ae3eac8aeb | ||
|
fbe9785613 | ||
|
7092e30f8d | ||
|
705d467932 | ||
|
05a4d05646 |
49
Cargo.lock
generated
49
Cargo.lock
generated
@@ -150,9 +150,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.25"
|
||||
version = "1.2.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951"
|
||||
checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
@@ -1376,9 +1376,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.3"
|
||||
version = "0.15.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
|
||||
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
@@ -1455,7 +1455,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"foldhash",
|
||||
"futures-executor",
|
||||
"hashbrown 0.15.3",
|
||||
"hashbrown 0.15.4",
|
||||
"log",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
@@ -1845,7 +1845,7 @@ version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17d34b7d42178945f775e84bc4c36dde7c1c6cdfea656d3354d009056f2bb3d2"
|
||||
dependencies = [
|
||||
"hashbrown 0.15.3",
|
||||
"hashbrown 0.15.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1855,7 +1855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.15.3",
|
||||
"hashbrown 0.15.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2437,9 +2437,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.8"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
|
||||
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -2539,9 +2539,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.0"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "smartstring"
|
||||
@@ -2759,9 +2759,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.22"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae"
|
||||
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
@@ -2771,18 +2771,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.9"
|
||||
version = "0.6.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3"
|
||||
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.26"
|
||||
version = "0.22.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e"
|
||||
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
@@ -2794,9 +2794,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_write"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076"
|
||||
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||
|
||||
[[package]]
|
||||
name = "tree-house"
|
||||
@@ -2805,7 +2805,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "679e3296e503901cd9f6e116be5a43a9270222215bf6c78b4b1f4af5c3dcc62d"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"hashbrown 0.15.3",
|
||||
"hashbrown 0.15.4",
|
||||
"kstring",
|
||||
"once_cell",
|
||||
"regex",
|
||||
@@ -3006,11 +3006,10 @@ checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "7.0.3"
|
||||
version = "8.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d643ce3fd3e5b54854602a080f34fb10ab75e0b813ee32d00ca2b44fa74762"
|
||||
checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d"
|
||||
dependencies = [
|
||||
"either",
|
||||
"env_home",
|
||||
"rustix 1.0.7",
|
||||
"winsafe",
|
||||
@@ -3146,9 +3145,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.7"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cb8234a863ea0e8cd7284fcdd4f145233eb00fee02bbdd9861aec44e6477bc5"
|
||||
checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@@ -150,7 +150,7 @@
|
||||
| mermaid | ✓ | | | |
|
||||
| meson | ✓ | | ✓ | `mesonlsp` |
|
||||
| mint | | | | `mint` |
|
||||
| mojo | ✓ | ✓ | ✓ | `magic` |
|
||||
| mojo | ✓ | ✓ | ✓ | `pixi` |
|
||||
| move | ✓ | | | |
|
||||
| msbuild | ✓ | | ✓ | |
|
||||
| nasm | ✓ | ✓ | | `asm-lsp` |
|
||||
@@ -238,7 +238,7 @@
|
||||
| thrift | ✓ | | | |
|
||||
| tlaplus | ✓ | | | |
|
||||
| todotxt | ✓ | | | |
|
||||
| toml | ✓ | ✓ | | `taplo` |
|
||||
| toml | ✓ | ✓ | | `taplo`, `tombi` |
|
||||
| tsq | ✓ | | | `ts_query_ls` |
|
||||
| tsx | ✓ | ✓ | ✓ | `typescript-language-server` |
|
||||
| twig | ✓ | | | |
|
||||
|
@@ -171,8 +171,9 @@ We use a similar set of scopes as
|
||||
|
||||
- `comment` - Code comments
|
||||
- `line` - Single line comments (`//`)
|
||||
- `documentation` - Line documentation comments (e.g. `///` in Rust)
|
||||
- `block` - Block comments (e.g. (`/* */`)
|
||||
- `documentation` - Documentation comments (e.g. `///` in Rust)
|
||||
- `documentation` - Block documentation comments (e.g. `/** */` in Rust)
|
||||
|
||||
- `variable` - Variables
|
||||
- `builtin` - Reserved language variables (`self`, `this`, `super`, etc.)
|
||||
|
@@ -176,6 +176,29 @@ impl Client {
|
||||
self.did_change_workspace(vec![workspace_for_uri(root_uri)], Vec::new())
|
||||
}
|
||||
|
||||
/// Merge FormattingOptions with 'config.format' and return it
|
||||
fn get_merged_formatting_options(
|
||||
&self,
|
||||
options: lsp::FormattingOptions,
|
||||
) -> lsp::FormattingOptions {
|
||||
let config_format = self
|
||||
.config
|
||||
.as_ref()
|
||||
.and_then(|cfg| cfg.get("format"))
|
||||
.and_then(|fmt| HashMap::<String, lsp::FormattingProperty>::deserialize(fmt).ok());
|
||||
|
||||
if let Some(mut properties) = config_format {
|
||||
// passed in options take precedence over 'config.format'
|
||||
properties.extend(options.properties);
|
||||
lsp::FormattingOptions {
|
||||
properties,
|
||||
..options
|
||||
}
|
||||
} else {
|
||||
options
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity, clippy::too_many_arguments)]
|
||||
pub fn start(
|
||||
cmd: &str,
|
||||
@@ -1168,23 +1191,7 @@ impl Client {
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
// merge FormattingOptions with 'config.format'
|
||||
let config_format = self
|
||||
.config
|
||||
.as_ref()
|
||||
.and_then(|cfg| cfg.get("format"))
|
||||
.and_then(|fmt| HashMap::<String, lsp::FormattingProperty>::deserialize(fmt).ok());
|
||||
|
||||
let options = if let Some(mut properties) = config_format {
|
||||
// passed in options take precedence over 'config.format'
|
||||
properties.extend(options.properties);
|
||||
lsp::FormattingOptions {
|
||||
properties,
|
||||
..options
|
||||
}
|
||||
} else {
|
||||
options
|
||||
};
|
||||
let options = self.get_merged_formatting_options(options);
|
||||
|
||||
let params = lsp::DocumentFormattingParams {
|
||||
text_document,
|
||||
@@ -1210,6 +1217,8 @@ impl Client {
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let options = self.get_merged_formatting_options(options);
|
||||
|
||||
let params = lsp::DocumentRangeFormattingParams {
|
||||
text_document,
|
||||
range,
|
||||
|
@@ -15,7 +15,7 @@ homepage.workspace = true
|
||||
dunce = "1.0"
|
||||
etcetera = "0.10"
|
||||
ropey.workspace = true
|
||||
which = "7.0"
|
||||
which = "8.0"
|
||||
regex-cursor = "0.1.5"
|
||||
bitflags.workspace = true
|
||||
once_cell = "1.21"
|
||||
|
@@ -135,7 +135,9 @@ pub trait RopeSliceExt<'a>: Sized {
|
||||
/// let graphemes: Vec<_> = text.graphemes().collect();
|
||||
/// assert_eq!(graphemes.as_slice(), &["😶🌫️", "🏴☠️", "🖼️"]);
|
||||
/// ```
|
||||
fn graphemes(self) -> RopeGraphemes<'a>;
|
||||
fn graphemes(self) -> RopeGraphemes<'a> {
|
||||
self.graphemes_at(0)
|
||||
}
|
||||
/// Returns an iterator over the grapheme clusters in the slice, reversed.
|
||||
///
|
||||
/// The returned iterator starts at the end of the slice and ends at the beginning of the
|
||||
@@ -150,7 +152,111 @@ pub trait RopeSliceExt<'a>: Sized {
|
||||
/// let graphemes: Vec<_> = text.graphemes_rev().collect();
|
||||
/// assert_eq!(graphemes.as_slice(), &["🖼️", "🏴☠️", "😶🌫️"]);
|
||||
/// ```
|
||||
fn graphemes_rev(self) -> RevRopeGraphemes<'a>;
|
||||
fn graphemes_rev(self) -> RopeGraphemes<'a>;
|
||||
/// Returns an iterator over the grapheme clusters in the slice at the given byte index.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use ropey::Rope;
|
||||
/// # use helix_stdx::rope::RopeSliceExt;
|
||||
/// let text = Rope::from_str("😶🌫️🏴☠️🖼️");
|
||||
/// // 14 is the byte index of the pirate flag's starting cluster boundary.
|
||||
/// let graphemes: Vec<_> = text.slice(..).graphemes_at(14).collect();
|
||||
/// assert_eq!(graphemes.as_slice(), &["🏴☠️", "🖼️"]);
|
||||
/// // 27 is the byte index of the pirate flag's ending cluster boundary.
|
||||
/// let graphemes: Vec<_> = text.slice(..).graphemes_at(27).reversed().collect();
|
||||
/// assert_eq!(graphemes.as_slice(), &["🏴☠️", "😶🌫️"]);
|
||||
/// ```
|
||||
fn graphemes_at(self, byte_idx: usize) -> RopeGraphemes<'a>;
|
||||
/// Returns an iterator over the grapheme clusters in a rope and the byte index where each
|
||||
/// grapheme cluster starts.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use ropey::Rope;
|
||||
/// # use helix_stdx::rope::RopeSliceExt;
|
||||
/// let text = Rope::from_str("😶🌫️🏴☠️🖼️");
|
||||
/// let slice = text.slice(..);
|
||||
/// let graphemes: Vec<_> = slice.grapheme_indices_at(0).collect();
|
||||
/// assert_eq!(
|
||||
/// graphemes.as_slice(),
|
||||
/// &[(0, "😶🌫️".into()), (14, "🏴☠️".into()), (27, "🖼️".into())]
|
||||
/// );
|
||||
/// let graphemes: Vec<_> = slice.grapheme_indices_at(slice.len_bytes()).reversed().collect();
|
||||
/// assert_eq!(
|
||||
/// graphemes.as_slice(),
|
||||
/// &[(27, "🖼️".into()), (14, "🏴☠️".into()), (0, "😶🌫️".into())]
|
||||
/// );
|
||||
/// ```
|
||||
fn grapheme_indices_at(self, byte_idx: usize) -> RopeGraphemeIndices<'a>;
|
||||
/// Finds the byte index of the next grapheme boundary after `byte_idx`.
|
||||
///
|
||||
/// If the byte index lies on the last grapheme cluster in the slice then this function
|
||||
/// returns `RopeSlice::len_bytes`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use ropey::Rope;
|
||||
/// # use helix_stdx::rope::RopeSliceExt;
|
||||
/// let text = Rope::from_str("😶🌫️🏴☠️🖼️");
|
||||
/// let slice = text.slice(..);
|
||||
/// let mut byte_idx = 0;
|
||||
/// assert_eq!(slice.graphemes_at(byte_idx).next(), Some("😶🌫️".into()));
|
||||
/// byte_idx = slice.next_grapheme_boundary(byte_idx);
|
||||
/// assert_eq!(slice.graphemes_at(byte_idx).next(), Some("🏴☠️".into()));
|
||||
/// byte_idx = slice.next_grapheme_boundary(byte_idx);
|
||||
/// assert_eq!(slice.graphemes_at(byte_idx).next(), Some("🖼️".into()));
|
||||
/// byte_idx = slice.next_grapheme_boundary(byte_idx);
|
||||
/// assert_eq!(slice.graphemes_at(byte_idx).next(), None);
|
||||
/// assert_eq!(byte_idx, slice.len_bytes());
|
||||
/// ```
|
||||
fn next_grapheme_boundary(self, byte_idx: usize) -> usize {
|
||||
self.nth_next_grapheme_boundary(byte_idx, 1)
|
||||
}
|
||||
/// Finds the byte index of the `n`th grapheme cluster after the given `byte_idx`.
|
||||
///
|
||||
/// If there are more than `n` grapheme clusters after `byte_idx` in the rope then this
|
||||
/// function returns `RopeSlice::len_bytes`.
|
||||
///
|
||||
/// This is functionally equivalent to calling `next_grapheme_boundary` `n` times but is more
|
||||
/// efficient.
|
||||
fn nth_next_grapheme_boundary(self, byte_idx: usize, n: usize) -> usize;
|
||||
/// Finds the byte index of the previous grapheme boundary before `byte_idx`.
|
||||
///
|
||||
/// If the byte index lies on the first grapheme cluster in the slice then this function
|
||||
/// returns zero.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use ropey::Rope;
|
||||
/// # use helix_stdx::rope::RopeSliceExt;
|
||||
/// let text = Rope::from_str("😶🌫️🏴☠️🖼️");
|
||||
/// let slice = text.slice(..);
|
||||
/// let mut byte_idx = text.len_bytes();
|
||||
/// assert_eq!(slice.graphemes_at(byte_idx).prev(), Some("🖼️".into()));
|
||||
/// byte_idx = slice.prev_grapheme_boundary(byte_idx);
|
||||
/// assert_eq!(slice.graphemes_at(byte_idx).prev(), Some("🏴☠️".into()));
|
||||
/// byte_idx = slice.prev_grapheme_boundary(byte_idx);
|
||||
/// assert_eq!(slice.graphemes_at(byte_idx).prev(), Some("😶🌫️".into()));
|
||||
/// byte_idx = slice.prev_grapheme_boundary(byte_idx);
|
||||
/// assert_eq!(slice.graphemes_at(byte_idx).prev(), None);
|
||||
/// assert_eq!(byte_idx, 0);
|
||||
/// ```
|
||||
fn prev_grapheme_boundary(self, byte_idx: usize) -> usize {
|
||||
self.nth_prev_grapheme_boundary(byte_idx, 1)
|
||||
}
|
||||
/// Finds the byte index of the `n`th grapheme cluster before the given `byte_idx`.
|
||||
///
|
||||
/// If there are fewer than `n` grapheme clusters before `byte_idx` in the rope then this
|
||||
/// function returns zero.
|
||||
///
|
||||
/// This is functionally equivalent to calling `prev_grapheme_boundary` `n` times but is more
|
||||
/// efficient.
|
||||
fn nth_prev_grapheme_boundary(self, byte_idx: usize, n: usize) -> usize;
|
||||
}
|
||||
|
||||
impl<'a> RopeSliceExt<'a> for RopeSlice<'a> {
|
||||
@@ -335,31 +441,106 @@ impl<'a> RopeSliceExt<'a> for RopeSlice<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn graphemes(self) -> RopeGraphemes<'a> {
|
||||
let mut chunks = self.chunks();
|
||||
let first_chunk = chunks.next().unwrap_or("");
|
||||
fn graphemes_rev(self) -> RopeGraphemes<'a> {
|
||||
self.graphemes_at(self.len_bytes()).reversed()
|
||||
}
|
||||
|
||||
fn graphemes_at(self, byte_idx: usize) -> RopeGraphemes<'a> {
|
||||
let (mut chunks, chunk_byte_idx, _, _) = self.chunks_at_byte(byte_idx);
|
||||
let current_chunk = chunks.next().unwrap_or("");
|
||||
|
||||
RopeGraphemes {
|
||||
text: self,
|
||||
chunks,
|
||||
cur_chunk: first_chunk,
|
||||
cur_chunk_start: 0,
|
||||
cursor: GraphemeCursor::new(0, self.len_bytes(), true),
|
||||
current_chunk,
|
||||
chunk_byte_idx,
|
||||
cursor: GraphemeCursor::new(byte_idx, self.len_bytes(), true),
|
||||
is_reversed: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn graphemes_rev(self) -> RevRopeGraphemes<'a> {
|
||||
let (mut chunks, mut cur_chunk_start, _, _) = self.chunks_at_byte(self.len_bytes());
|
||||
chunks.reverse();
|
||||
let first_chunk = chunks.next().unwrap_or("");
|
||||
cur_chunk_start -= first_chunk.len();
|
||||
RevRopeGraphemes {
|
||||
text: self,
|
||||
chunks,
|
||||
cur_chunk: first_chunk,
|
||||
cur_chunk_start,
|
||||
cursor: GraphemeCursor::new(self.len_bytes(), self.len_bytes(), true),
|
||||
fn grapheme_indices_at(self, byte_idx: usize) -> RopeGraphemeIndices<'a> {
|
||||
RopeGraphemeIndices {
|
||||
front_offset: byte_idx,
|
||||
iter: self.graphemes_at(byte_idx),
|
||||
is_reversed: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn nth_next_grapheme_boundary(self, mut byte_idx: usize, n: usize) -> usize {
|
||||
// Bounds check
|
||||
debug_assert!(byte_idx <= self.len_bytes());
|
||||
|
||||
byte_idx = self.floor_char_boundary(byte_idx);
|
||||
|
||||
// Get the chunk with our byte index in it.
|
||||
let (mut chunk, mut chunk_byte_idx, _, _) = self.chunk_at_byte(byte_idx);
|
||||
|
||||
// Set up the grapheme cursor.
|
||||
let mut gc = GraphemeCursor::new(byte_idx, self.len_bytes(), true);
|
||||
|
||||
// Find the nth next grapheme cluster boundary.
|
||||
for _ in 0..n {
|
||||
loop {
|
||||
match gc.next_boundary(chunk, chunk_byte_idx) {
|
||||
Ok(None) => return self.len_bytes(),
|
||||
Ok(Some(n)) => {
|
||||
byte_idx = n;
|
||||
break;
|
||||
}
|
||||
Err(GraphemeIncomplete::NextChunk) => {
|
||||
chunk_byte_idx += chunk.len();
|
||||
let (a, _, _, _) = self.chunk_at_byte(chunk_byte_idx);
|
||||
chunk = a;
|
||||
}
|
||||
Err(GraphemeIncomplete::PreContext(n)) => {
|
||||
let ctx_chunk = self.chunk_at_byte(n - 1).0;
|
||||
gc.provide_context(ctx_chunk, n - ctx_chunk.len());
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte_idx
|
||||
}
|
||||
|
||||
fn nth_prev_grapheme_boundary(self, mut byte_idx: usize, n: usize) -> usize {
|
||||
// Bounds check
|
||||
debug_assert!(byte_idx <= self.len_bytes());
|
||||
|
||||
byte_idx = self.ceil_char_boundary(byte_idx);
|
||||
|
||||
// Get the chunk with our byte index in it.
|
||||
let (mut chunk, mut chunk_byte_idx, _, _) = self.chunk_at_byte(byte_idx);
|
||||
|
||||
// Set up the grapheme cursor.
|
||||
let mut gc = GraphemeCursor::new(byte_idx, self.len_bytes(), true);
|
||||
|
||||
for _ in 0..n {
|
||||
loop {
|
||||
match gc.prev_boundary(chunk, chunk_byte_idx) {
|
||||
Ok(None) => return 0,
|
||||
Ok(Some(n)) => {
|
||||
byte_idx = n;
|
||||
break;
|
||||
}
|
||||
Err(GraphemeIncomplete::PrevChunk) => {
|
||||
let (a, b, _, _) = self.chunk_at_byte(chunk_byte_idx - 1);
|
||||
chunk = a;
|
||||
chunk_byte_idx = b;
|
||||
}
|
||||
Err(GraphemeIncomplete::PreContext(n)) => {
|
||||
let ctx_chunk = self.chunk_at_byte(n - 1).0;
|
||||
gc.provide_context(ctx_chunk, n - ctx_chunk.len());
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte_idx
|
||||
}
|
||||
}
|
||||
|
||||
// copied from std
|
||||
@@ -370,13 +551,18 @@ const fn is_utf8_char_boundary(b: u8) -> bool {
|
||||
}
|
||||
|
||||
/// An iterator over the graphemes of a `RopeSlice`.
|
||||
///
|
||||
/// This iterator is cursor-like: rather than implementing DoubleEndedIterator it can be reversed
|
||||
/// like a cursor.
|
||||
#[derive(Clone)]
|
||||
pub struct RopeGraphemes<'a> {
|
||||
text: RopeSlice<'a>,
|
||||
chunks: Chunks<'a>,
|
||||
cur_chunk: &'a str,
|
||||
cur_chunk_start: usize,
|
||||
current_chunk: &'a str,
|
||||
/// Byte index of the start of the current chunk.
|
||||
chunk_byte_idx: usize,
|
||||
cursor: GraphemeCursor,
|
||||
is_reversed: bool,
|
||||
}
|
||||
|
||||
impl fmt::Debug for RopeGraphemes<'_> {
|
||||
@@ -384,112 +570,178 @@ impl fmt::Debug for RopeGraphemes<'_> {
|
||||
f.debug_struct("RopeGraphemes")
|
||||
.field("text", &self.text)
|
||||
.field("chunks", &self.chunks)
|
||||
.field("cur_chunk", &self.cur_chunk)
|
||||
.field("cur_chunk_start", &self.cur_chunk_start)
|
||||
.field("current_chunk", &self.current_chunk)
|
||||
.field("chunk_byte_idx", &self.chunk_byte_idx)
|
||||
// .field("cursor", &self.cursor)
|
||||
.field("is_reversed", &self.is_reversed)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RopeGraphemes<'a> {
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn next(&mut self) -> Option<RopeSlice<'a>> {
|
||||
if self.is_reversed {
|
||||
self.prev_impl()
|
||||
} else {
|
||||
self.next_impl()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prev(&mut self) -> Option<RopeSlice<'a>> {
|
||||
if self.is_reversed {
|
||||
self.next_impl()
|
||||
} else {
|
||||
self.prev_impl()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reverse(&mut self) {
|
||||
self.is_reversed = !self.is_reversed;
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn reversed(mut self) -> Self {
|
||||
self.reverse();
|
||||
self
|
||||
}
|
||||
|
||||
fn next_impl(&mut self) -> Option<RopeSlice<'a>> {
|
||||
let a = self.cursor.cur_cursor();
|
||||
let b;
|
||||
loop {
|
||||
match self
|
||||
.cursor
|
||||
.next_boundary(self.current_chunk, self.chunk_byte_idx)
|
||||
{
|
||||
Ok(None) => return None,
|
||||
Ok(Some(n)) => {
|
||||
b = n;
|
||||
break;
|
||||
}
|
||||
Err(GraphemeIncomplete::NextChunk) => {
|
||||
self.chunk_byte_idx += self.current_chunk.len();
|
||||
self.current_chunk = self.chunks.next().unwrap_or("");
|
||||
}
|
||||
Err(GraphemeIncomplete::PreContext(idx)) => {
|
||||
let (chunk, byte_idx, _, _) = self.text.chunk_at_byte(idx.saturating_sub(1));
|
||||
self.cursor.provide_context(chunk, byte_idx);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
if a < self.chunk_byte_idx {
|
||||
Some(self.text.byte_slice(a..b))
|
||||
} else {
|
||||
let a2 = a - self.chunk_byte_idx;
|
||||
let b2 = b - self.chunk_byte_idx;
|
||||
Some((&self.current_chunk[a2..b2]).into())
|
||||
}
|
||||
}
|
||||
|
||||
fn prev_impl(&mut self) -> Option<RopeSlice<'a>> {
|
||||
let a = self.cursor.cur_cursor();
|
||||
let b;
|
||||
loop {
|
||||
match self
|
||||
.cursor
|
||||
.prev_boundary(self.current_chunk, self.chunk_byte_idx)
|
||||
{
|
||||
Ok(None) => return None,
|
||||
Ok(Some(n)) => {
|
||||
b = n;
|
||||
break;
|
||||
}
|
||||
Err(GraphemeIncomplete::PrevChunk) => {
|
||||
self.current_chunk = self.chunks.prev().unwrap_or("");
|
||||
self.chunk_byte_idx -= self.current_chunk.len();
|
||||
}
|
||||
Err(GraphemeIncomplete::PreContext(idx)) => {
|
||||
let (chunk, byte_idx, _, _) = self.text.chunk_at_byte(idx.saturating_sub(1));
|
||||
self.cursor.provide_context(chunk, byte_idx);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
if a >= self.chunk_byte_idx + self.current_chunk.len() {
|
||||
Some(self.text.byte_slice(b..a))
|
||||
} else {
|
||||
let a2 = a - self.chunk_byte_idx;
|
||||
let b2 = b - self.chunk_byte_idx;
|
||||
Some((&self.current_chunk[b2..a2]).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for RopeGraphemes<'a> {
|
||||
type Item = RopeSlice<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let a = self.cursor.cur_cursor();
|
||||
let b;
|
||||
loop {
|
||||
match self
|
||||
.cursor
|
||||
.next_boundary(self.cur_chunk, self.cur_chunk_start)
|
||||
{
|
||||
Ok(None) => {
|
||||
return None;
|
||||
}
|
||||
Ok(Some(n)) => {
|
||||
b = n;
|
||||
break;
|
||||
}
|
||||
Err(GraphemeIncomplete::NextChunk) => {
|
||||
self.cur_chunk_start += self.cur_chunk.len();
|
||||
self.cur_chunk = self.chunks.next().unwrap_or("");
|
||||
}
|
||||
Err(GraphemeIncomplete::PreContext(idx)) => {
|
||||
let (chunk, byte_idx, _, _) = self.text.chunk_at_byte(idx.saturating_sub(1));
|
||||
self.cursor.provide_context(chunk, byte_idx);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
RopeGraphemes::next(self)
|
||||
}
|
||||
}
|
||||
|
||||
if a < self.cur_chunk_start {
|
||||
Some(self.text.byte_slice(a..b))
|
||||
/// An iterator over the grapheme clusters in a rope and the byte indices where each grapheme
|
||||
/// cluster starts.
|
||||
///
|
||||
/// This iterator wraps `RopeGraphemes` and is also cursor-like. Use `reverse` or `reversed` to
|
||||
/// toggle the direction of the iterator.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RopeGraphemeIndices<'a> {
|
||||
front_offset: usize,
|
||||
iter: RopeGraphemes<'a>,
|
||||
is_reversed: bool,
|
||||
}
|
||||
|
||||
impl<'a> RopeGraphemeIndices<'a> {
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn next(&mut self) -> Option<(usize, RopeSlice<'a>)> {
|
||||
if self.is_reversed {
|
||||
self.prev_impl()
|
||||
} else {
|
||||
let a2 = a - self.cur_chunk_start;
|
||||
let b2 = b - self.cur_chunk_start;
|
||||
Some((&self.cur_chunk[a2..b2]).into())
|
||||
self.next_impl()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over the graphemes of a `RopeSlice` in reverse.
|
||||
#[derive(Clone)]
|
||||
pub struct RevRopeGraphemes<'a> {
|
||||
text: RopeSlice<'a>,
|
||||
chunks: Chunks<'a>,
|
||||
cur_chunk: &'a str,
|
||||
cur_chunk_start: usize,
|
||||
cursor: GraphemeCursor,
|
||||
}
|
||||
pub fn prev(&mut self) -> Option<(usize, RopeSlice<'a>)> {
|
||||
if self.is_reversed {
|
||||
self.next_impl()
|
||||
} else {
|
||||
self.prev_impl()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for RevRopeGraphemes<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("RevRopeGraphemes")
|
||||
.field("text", &self.text)
|
||||
.field("chunks", &self.chunks)
|
||||
.field("cur_chunk", &self.cur_chunk)
|
||||
.field("cur_chunk_start", &self.cur_chunk_start)
|
||||
// .field("cursor", &self.cursor)
|
||||
.finish()
|
||||
pub fn reverse(&mut self) {
|
||||
self.is_reversed = !self.is_reversed;
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn reversed(mut self) -> Self {
|
||||
self.reverse();
|
||||
self
|
||||
}
|
||||
|
||||
fn next_impl(&mut self) -> Option<(usize, RopeSlice<'a>)> {
|
||||
let slice = self.iter.next()?;
|
||||
let idx = self.front_offset;
|
||||
self.front_offset += slice.len_bytes();
|
||||
Some((idx, slice))
|
||||
}
|
||||
|
||||
fn prev_impl(&mut self) -> Option<(usize, RopeSlice<'a>)> {
|
||||
let slice = self.iter.prev()?;
|
||||
self.front_offset -= slice.len_bytes();
|
||||
Some((self.front_offset, slice))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for RevRopeGraphemes<'a> {
|
||||
type Item = RopeSlice<'a>;
|
||||
impl<'a> Iterator for RopeGraphemeIndices<'a> {
|
||||
type Item = (usize, RopeSlice<'a>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let a = self.cursor.cur_cursor();
|
||||
let b;
|
||||
loop {
|
||||
match self
|
||||
.cursor
|
||||
.prev_boundary(self.cur_chunk, self.cur_chunk_start)
|
||||
{
|
||||
Ok(None) => {
|
||||
return None;
|
||||
}
|
||||
Ok(Some(n)) => {
|
||||
b = n;
|
||||
break;
|
||||
}
|
||||
Err(GraphemeIncomplete::PrevChunk) => {
|
||||
self.cur_chunk = self.chunks.next().unwrap_or("");
|
||||
self.cur_chunk_start -= self.cur_chunk.len();
|
||||
}
|
||||
Err(GraphemeIncomplete::PreContext(idx)) => {
|
||||
let (chunk, byte_idx, _, _) = self.text.chunk_at_byte(idx.saturating_sub(1));
|
||||
self.cursor.provide_context(chunk, byte_idx);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
if a >= self.cur_chunk_start + self.cur_chunk.len() {
|
||||
Some(self.text.byte_slice(b..a))
|
||||
} else {
|
||||
let a2 = a - self.cur_chunk_start;
|
||||
let b2 = b - self.cur_chunk_start;
|
||||
Some((&self.cur_chunk[b2..a2]).into())
|
||||
}
|
||||
RopeGraphemeIndices::next(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -71,7 +71,7 @@ marksman = { command = "marksman", args = ["server"] }
|
||||
metals = { command = "metals", config = { "isHttpEnabled" = true, metals = { inlayHints = { typeParameters = {enable = true} , hintsInPatternMatch = {enable = true} } } } }
|
||||
mesonlsp = { command = "mesonlsp", args = ["--lsp"] }
|
||||
mint = { command = "mint", args = ["tool", "ls"] }
|
||||
mojo-lsp = { command = "magic", args = ["run", "mojo-lsp-server"] }
|
||||
mojo-lsp-server = { command = "pixi", args = ["run", "mojo-lsp-server"] }
|
||||
nil = { command = "nil" }
|
||||
nimlangserver = { command = "nimlangserver" }
|
||||
nimlsp = { command = "nimlsp" }
|
||||
@@ -120,6 +120,7 @@ taplo = { command = "taplo", args = ["lsp", "stdio"] }
|
||||
templ = { command = "templ", args = ["lsp"] }
|
||||
terraform-ls = { command = "terraform-ls", args = ["serve"] }
|
||||
texlab = { command = "texlab" }
|
||||
tombi = { command = "tombi", args = ["lsp"] }
|
||||
ty = { command = "ty", args = ["server"] }
|
||||
typespec = { command = "tsp-server", args = ["--stdio"] }
|
||||
vala-language-server = { command = "vala-language-server" }
|
||||
@@ -345,7 +346,7 @@ scope = "source.toml"
|
||||
injection-regex = "toml"
|
||||
file-types = ["toml", { glob = "pdm.lock" }, { glob = "poetry.lock" }, { glob = "Cargo.lock" }, { glob = "uv.lock" }]
|
||||
comment-token = "#"
|
||||
language-servers = [ "taplo" ]
|
||||
language-servers = [ "taplo", "tombi" ]
|
||||
indent = { tab-width = 2, unit = " " }
|
||||
|
||||
[[grammar]]
|
||||
@@ -452,14 +453,14 @@ indent = { tab-width = 2, unit = " " }
|
||||
[[language]]
|
||||
name = "mojo"
|
||||
scope = "source.mojo"
|
||||
roots = ["__init__.mojo"]
|
||||
roots = ["pixi.toml", "pixi.lock"]
|
||||
injection-regex = "mojo"
|
||||
file-types = ["mojo", "🔥"]
|
||||
language-servers = [ "mojo-lsp" ]
|
||||
language-servers = [ "mojo-lsp-server" ]
|
||||
comment-token = "#"
|
||||
indent = { tab-width = 4, unit = " " }
|
||||
auto-format = true
|
||||
formatter = { command = "magic", args = ["run", "mojo" , "format", "-q", "-"]}
|
||||
formatter = { command = "pixi", args = ["run", "mojo" , "format", "-q", "-"]}
|
||||
|
||||
[[grammar]]
|
||||
name = "mojo"
|
||||
|
@@ -106,12 +106,28 @@
|
||||
(string_literal)
|
||||
(raw_string_literal)
|
||||
] @string
|
||||
(outer_doc_comment_marker "/" @comment)
|
||||
(inner_doc_comment_marker "!" @comment)
|
||||
[
|
||||
(line_comment)
|
||||
(block_comment)
|
||||
] @comment
|
||||
|
||||
; -------
|
||||
; Comments
|
||||
; -------
|
||||
|
||||
(line_comment) @comment.line
|
||||
(block_comment) @comment.block
|
||||
|
||||
; Doc Comments
|
||||
(line_comment
|
||||
(outer_doc_comment_marker "/" @comment.line.documentation)
|
||||
(doc_comment)) @comment.line.documentation
|
||||
(line_comment
|
||||
(inner_doc_comment_marker "!" @comment.line.documentation)
|
||||
(doc_comment)) @comment.line.documentation
|
||||
|
||||
(block_comment
|
||||
(outer_doc_comment_marker) @comment.block.documentation
|
||||
(doc_comment) "*/" @comment.block.documentation) @comment.block.documentation
|
||||
(block_comment
|
||||
(inner_doc_comment_marker) @comment.block.documentation
|
||||
(doc_comment) "*/" @comment.block.documentation) @comment.block.documentation
|
||||
|
||||
; ---
|
||||
; Extraneous
|
||||
|
@@ -35,6 +35,7 @@
|
||||
|
||||
"comment" = { fg = "g_6", modifiers = ["italic"] }
|
||||
"comment.block.documentation" = { fg = "g_5", modifiers = ["italic"] }
|
||||
"comment.line.documentation" = { fg = "g_5", modifiers = ["italic"] }
|
||||
|
||||
"variable" = "g_3"
|
||||
"variable.parameter" = { fg = "g_2", modifiers = ["italic"] }
|
||||
|
@@ -56,6 +56,7 @@ diagnostic = "cool-sky"
|
||||
|
||||
"comment" = "purple-gray"
|
||||
"comment.line" = "purple-gray"
|
||||
"comment.line.documentation" = "purple-gray"
|
||||
"comment.block" = "dead-green"
|
||||
"comment.block.documentation" = "dead-green"
|
||||
|
||||
|
@@ -22,6 +22,7 @@
|
||||
|
||||
"comment" = { fg = "gray40", modifiers = ["italic"] }
|
||||
"comment.block.documentation" = { fg = "gray40", modifiers = ["italic"] }
|
||||
"comment.line.documentation" = { fg = "gray40", modifiers = ["italic"] }
|
||||
|
||||
"variable" = "gray70"
|
||||
"variable.builtin" = { fg = "cyan30", modifiers = ["bold"] }
|
||||
|
@@ -9,6 +9,7 @@
|
||||
'comment' = { fg = 'gray', modifiers = ['italic'] }
|
||||
'comment.block' = { fg = 'green', modifiers = ['italic'] }
|
||||
'comment.block.documentation' = { fg = 'green', modifiers = ['italic'] }
|
||||
'comment.line.documentation' = { fg = 'green', modifiers = ['italic'] }
|
||||
'constant' = { fg = 'magenta' }
|
||||
'constant.numeric' = { fg = 'orange' }
|
||||
'constructor' = { fg = 'red' }
|
||||
|
@@ -9,6 +9,7 @@
|
||||
"comment.block" = { fg = "comment" }
|
||||
"comment.block.documentation" = { fg = "comment" }
|
||||
"comment.line" = { fg = "comment" }
|
||||
"comment.line.documentation" = { fg = "comment" }
|
||||
|
||||
"constant" = { fg = "purple" }
|
||||
"constant.builtin" = { fg = "purple" }
|
||||
|
@@ -6,6 +6,7 @@
|
||||
"comment.block" = "comments"
|
||||
"comment.block.documentation" = "comments"
|
||||
"comment.line" = "comments"
|
||||
"comment.line.documentation" = "comments"
|
||||
#"constant" = ""
|
||||
"constant.builtin" = { fg = "builtins", modifiers = ["italic"] }
|
||||
"constant.character" = "strings"
|
||||
|
@@ -4,6 +4,7 @@
|
||||
"attribute" = { fg = "blue_text", bg = "blue_bg" }
|
||||
"comment" = { fg = "base3", modifiers = ["italic"] }
|
||||
"comment.line" = {}
|
||||
"comment.line.documentation" = { fg = "base2" }
|
||||
"comment.block" = {}
|
||||
"comment.block.documentation" = { fg = "base2" }
|
||||
"constant" = { fg = "blue_text", bg = "blue_bg" }
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
"comment" = { fg = "comment" }
|
||||
"comment.block.documentation" = { bg = "comment_doc", modifiers = ["italic"] }
|
||||
"comment.line.documentation" = { bg = "comment_doc", modifiers = ["italic"] }
|
||||
|
||||
"constant" = { fg = "t11" }
|
||||
"function" = { fg = "t10" }
|
||||
|
@@ -5,6 +5,7 @@
|
||||
string = "green171"
|
||||
comment = "blue133"
|
||||
"comment.block.documentation" = "green130"
|
||||
"comment.line.documentation" = "green130"
|
||||
"variable.builtin" = "red207"
|
||||
"variable.other.member" = "red199"
|
||||
label = "red199"
|
||||
|
132
runtime/themes/lapis_aquamarine.toml
Normal file
132
runtime/themes/lapis_aquamarine.toml
Normal file
@@ -0,0 +1,132 @@
|
||||
# Author: spentbliss <zyhkekrz.hatbox475@passinbox.com>
|
||||
# License: MIT (originally by Alex Barnett)
|
||||
|
||||
"ui.background" = { fg = "fg", bg = "bg" } # file picker border color
|
||||
"ui.text" = "fg"
|
||||
"ui.text.focus" = { fg = "bg", bg = "fg" } # file picker selection
|
||||
"ui.cursor" = { bg = "blue", fg = "bg" }
|
||||
"ui.linenr" = "grey"
|
||||
"ui.statusline" = { fg = "fg" }
|
||||
"ui.selection" = "green"
|
||||
"ui.selection.primary" = { bg = "bg_highlight" }
|
||||
"ui.virtual.ruler" = { bg = "bg_highlight" }
|
||||
|
||||
# Syntax Highlighting for Markdown
|
||||
"markup.raw" = { fg = "purple", bg = "bg" }
|
||||
"markup.raw.inline" = {fg = "fg" }
|
||||
"markup.heading.1" = { fg = "#46D9FF", bg = "#11313B" } # cyan
|
||||
"markup.heading.2" = { fg = "#C678DD", bg = "#2D2233" } # magenta
|
||||
"markup.heading.3" = { fg = "#98BE65", bg = "#253027" } # green
|
||||
"markup.heading.4" = { fg = "#A8A1E1", bg = "#2A2738" } # purple
|
||||
"markup.heading.5" = { fg = "#ECBE7B", bg = "#3A3223" } # yellow
|
||||
"markup.heading.6" = { fg = "#46D9FF", bg = "#1E2A30" } # cyan again
|
||||
"markup.list" = { fg = "purple" }
|
||||
"markup.bold" = { fg = "fg", modifiers = ["bold"] }
|
||||
"markup.italic" = { fg = "fg" }
|
||||
"markup.strikethrough" = { fg = "red", modifiers = ["crossed_out"] }
|
||||
"markup.link" = { fg = "cyan" }
|
||||
"markup.quote" = { fg = "fg" }
|
||||
|
||||
# Syntax Highlighting for Code
|
||||
"comment" = { fg = "grey", modifiers = ["italic"] }
|
||||
"comment.line" = { fg = "grey", modifiers = ["italic"] }
|
||||
"comment.block" = { fg = "grey", modifiers = ["italic"] }
|
||||
"comment.documentation" = { fg = "blue", modifiers = ["italic"] }
|
||||
|
||||
"keyword" = "blue"
|
||||
"keyword.storage" = "blue" # let keyword in rust
|
||||
"keyword.storage.type" = "blue" # keywords describing how things are stored, class, var, let, etc
|
||||
"keyword.storage.modifier" = "fg" # mut keyword
|
||||
"keyword.control.import" = "blue" # use keyword in rust
|
||||
"keyword.control.export" = "blue"
|
||||
"keyword.control.conditional" = "blue" # if, else
|
||||
"keyword.directive" = "blue"
|
||||
"keyword.control.repeat" = "blue" # for, while, loop
|
||||
"keyword.operator" = "blue" # or, in keywords
|
||||
"keyword.function" = "blue" # function keyword color
|
||||
|
||||
"type" = "green"
|
||||
"type.builtin" = "green" # primitive types int, usize
|
||||
"type.parameter" = "green"
|
||||
"type.enum" = "cyan"
|
||||
|
||||
"function" = "purple" # color for function NAME not the keyword fn or func
|
||||
"function.builtin" = "purple"
|
||||
"function.method" = "blue"
|
||||
|
||||
"variable" = "fg"
|
||||
"variable.builtin" = "fg"
|
||||
"variable.parameter" = "cyan"
|
||||
|
||||
"string" = "green"
|
||||
"string.special" = "green"
|
||||
|
||||
"constant" = "cyan"
|
||||
"constant.builtin" = "blue" # true, false, nil
|
||||
"constant.numeric" = "cyan" # int & float
|
||||
"constant.character" = "yellow" # escape character
|
||||
|
||||
"operator" = "fg"
|
||||
|
||||
# html tags
|
||||
"tag" = { fg = "purple", modifiers = ["bold"] }
|
||||
"attribute" = "blue"
|
||||
|
||||
"namespace" = "fg"
|
||||
"macro" = "orange"
|
||||
"label" = "red"
|
||||
|
||||
# Interface specific
|
||||
"ui.cursorline.primary" = { bg = "bg_highlight" }
|
||||
"ui.cursorline.secondary" = { bg = "bg_alt" }
|
||||
"ui.cursorcolumn.primary" = { bg = "bg_highlight" }
|
||||
"ui.cursorcolumn.secondary" = { bg = "bg_alt" }
|
||||
"ui.statusline.normal" = { fg = "bg", bg = "cyan" }
|
||||
"ui.statusline.insert" = { fg = "bg", bg = "green" }
|
||||
"ui.statusline.select" = { fg = "bg", bg = "purple" }
|
||||
|
||||
# Diagnostic styles
|
||||
"warning" = { fg = "yellow", modifiers = ["bold"] }
|
||||
"error" = { fg = "red", modifiers = ["bold"] }
|
||||
"info" = { fg = "cyan", modifiers = ["bold"] }
|
||||
"hint" = { fg = "blue", modifiers = ["bold"] }
|
||||
"diagnostic.error" = { fg = "grey" }
|
||||
"diagnostic.warning" = { fg = "grey" }
|
||||
"diagnostic.info" = { fg = "grey" }
|
||||
"diagnostic.hint" = { fg = "grey" }
|
||||
|
||||
# Git changes indicator
|
||||
"diff.plus" = "green"
|
||||
"diff.plus.gutter" = "green"
|
||||
"diff.minus" = "red"
|
||||
"diff.minus.gutter" = "red"
|
||||
"diff.delta" = "fg"
|
||||
"diff.delta.gutter" = "fg"
|
||||
"diff.delta.moved" = "orange"
|
||||
"diff.delta.conflict" = "purple"
|
||||
|
||||
# Popups and Menus
|
||||
"ui.popup" = { fg = "fg", bg = "bg" }
|
||||
"ui.popup.info" = { fg = "fg", bg = "bg" }
|
||||
"ui.menu" = { fg = "fg", bg = "bg" }
|
||||
"ui.menu.selected" = { fg = "bg", bg = "fg" }
|
||||
|
||||
# Additional overrides
|
||||
"ui.virtual.whitespace" = "grey"
|
||||
"ui.virtual.indent-guide" = { fg = "indent_color", underline.style = "dotted" }
|
||||
|
||||
[palette]
|
||||
bg = "#1B1F27"
|
||||
fg = "#D6E2FF"
|
||||
grey = "#7183A9"
|
||||
blue = "#83ABFC"
|
||||
green = "#ABFC83"
|
||||
cyan = "#84FCD4"
|
||||
red = "#FC83AB"
|
||||
yellow = "#FCD583"
|
||||
pink = "#FC83D6"
|
||||
orange = "#FCAB83"
|
||||
purple = "#D483FC"
|
||||
bg_alt = "#14181D"
|
||||
bg_highlight = "#43537A"
|
||||
indent_color = "#2E3953"
|
23
runtime/themes/licenses/lapis_aquamarine.LICENSE
Normal file
23
runtime/themes/licenses/lapis_aquamarine.LICENSE
Normal file
@@ -0,0 +1,23 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Alex Barnett
|
||||
|
||||
This theme has been ported by spentbliss <zyhkekrz.hatbox475@passinbox.com>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@@ -4,6 +4,7 @@ inherits = "monokai"
|
||||
|
||||
"comment" = "comment"
|
||||
"comment.block.documentation" = { fg = "comment", modifiers = ["bold"] }
|
||||
"comment.line.documentation" = { fg = "comment", modifiers = ["bold"] }
|
||||
"constant.character.escape" = { fg = "light-blue", modifiers = ["italic"] }
|
||||
"function.macro" = { fg = "#c4be89", modifiers = ["italic"] }
|
||||
"keyword" = { fg = "keyword", modifiers = ["bold"] }
|
||||
|
@@ -51,6 +51,7 @@
|
||||
'string.special.url' = { fg = 'gold', modifiers = ['underlined'] }
|
||||
'comment' = { fg = 'slate', modifiers = ['italic'] }
|
||||
'comment.block.documentation' = { fg = 'slate' }
|
||||
'comment.line.documentation' = { fg = 'slate' }
|
||||
'variable' = { fg = 'green' }
|
||||
'variable.builtin' = { fg = 'green', modifiers = ['italic'] }
|
||||
'label' = { fg = 'foreground' }
|
||||
|
@@ -106,7 +106,8 @@
|
||||
"string.special.url" = { fg = "cyan", modifiers = ["bold"] } # String containing a web URL.
|
||||
|
||||
"comment" = { fg = "comment" } # This is a comment.
|
||||
"comment.block.documentation" = { fg = "comment", modifiers = ["bold"] } # Doc comments, e.g '///' in rust.
|
||||
"comment.block.documentation" = { fg = "comment", modifiers = ["bold"] } # Block doc comments, e.g '/** */' in rust.
|
||||
"comment.line.documentation" = { fg = "comment", modifiers = ["bold"] } # Line doc comments, e.g '///' in rust.
|
||||
|
||||
"variable" = { fg = "white" } # Variable names.
|
||||
"variable.builtin" = { fg = "red" } # Language reserved variables: `this`, `self`, `super`, etc.
|
||||
|
@@ -100,8 +100,9 @@
|
||||
|
||||
'comment' = { fg = "gray", modifiers = ["italic"] } # This is a comment.
|
||||
'comment.line' = { } # Line comments, like this.
|
||||
'comment.line.documentation' = { } # Doc comments, e.g '///' in rust.
|
||||
'comment.block' = { } # Block comments, like /* this */ in some languages.
|
||||
'comment.block.documentation' = { } # Doc comments, e.g '///' in rust.
|
||||
'comment.block.documentation' = { } # Doc comments, e.g '/** */' in rust.
|
||||
|
||||
'variable' = { fg = "light-orange" } # Variable names.
|
||||
# 'variable.builtin' = { } # Language reserved variables: `this`, `self`, `super`, etc.
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
"attribute" = { fg = "#7060eb", modifiers = ["bold"] }
|
||||
"comment" = { fg = "base03", modifiers = ["italic"] }
|
||||
"comment.line.documentation" = { fg = "base06", modifiers = ["italic"] }
|
||||
"comment.block.documentation" = { fg = "base06", modifiers = ["italic"] }
|
||||
"constant" = "base09"
|
||||
"constant.character.escape" = "base0C"
|
||||
|
@@ -33,6 +33,7 @@
|
||||
|
||||
"comment" = { fg = "grey", modifiers = ["italic"] }
|
||||
"comment.line" = { fg = "grey", modifiers = ["italic"] }
|
||||
"comment.line.documentation" = { fg = "grey", modifiers = ["italic"] }
|
||||
"comment.block" = { fg = "grey", modifiers = ["italic"] }
|
||||
"comment.block.documentation" = { fg = "grey", modifiers = ["italic"] }
|
||||
|
||||
|
@@ -76,6 +76,7 @@
|
||||
|
||||
"comment" = { fg = "regular5", modifiers = ["italic"] }
|
||||
"comment.line" = { fg = "regular5", modifiers = ["italic"] }
|
||||
"comment.line.documentation" = { fg = "regular5", modifiers = ["bold"] }
|
||||
"comment.block" = { fg = "regular5", modifiers = ["italic"] }
|
||||
"comment.block.documentation" = { fg = "regular5", modifiers = ["bold"] }
|
||||
|
||||
|
@@ -11,6 +11,7 @@
|
||||
"ui.text.focus" = { fg = "black", bg = "white" }
|
||||
"comment" = "light-green"
|
||||
"comment.line" = "light-green"
|
||||
"comment.line.documentation" = "light-green"
|
||||
"comment.block" = "red"
|
||||
"comment.block.documentation" = "red"
|
||||
"ui.statusline" = { fg = "black", bg = "light-cyan" }
|
||||
|
@@ -71,6 +71,7 @@ namespace = { fg = 'orangeL' }
|
||||
'string.special.symbol' = { fg = 'orangeW' }
|
||||
'comment' = { fg = 'greyC', modifiers = ['italic'] }
|
||||
'comment.line' = { fg = 'greyC', modifiers = ['italic'] }
|
||||
'comment.line.documentation' = { fg = 'greyC', modifiers = ['italic'] }
|
||||
'comment.block' = { fg = 'greyC', modifiers = ['italic'] }
|
||||
'comment.block.documentation' = { fg = 'greyC', modifiers = ['italic'] }
|
||||
'variable' = { fg = 'greyT' }
|
||||
|
@@ -94,6 +94,7 @@
|
||||
|
||||
"comment" = { fg = "muted", modifiers = ["italic"] }
|
||||
# "comment.line" = ""
|
||||
# "comment.line.documentation" = ""
|
||||
# "comment.block" = ""
|
||||
# "comment.block.documentation" = ""
|
||||
|
||||
|
@@ -23,6 +23,7 @@ string = "grass"
|
||||
|
||||
comment = { fg = "cmnt", modifiers = ["italic"] }
|
||||
"comment.block.documentation" = "grass"
|
||||
"comment.line.documentation" = "grass"
|
||||
|
||||
variable = "text"
|
||||
"variable.builtin" = { fg = "sky", modifiers = ["italic"] }
|
||||
|
@@ -3,6 +3,7 @@
|
||||
attribute = { fg = "cyan" }
|
||||
comment = { fg = "comment", modifiers = ["italic"] }
|
||||
"comment.block.documentation" = { fg = "yellow" }
|
||||
"comment.line.documentation" = { fg = "yellow" }
|
||||
constant = { fg = "orange" }
|
||||
"constant.builtin" = { fg = "aqua" }
|
||||
"constant.character" = { fg = "light-green" }
|
||||
|
@@ -11,6 +11,7 @@
|
||||
"comment" = { fg = "comment" }
|
||||
"ui.virtual.inlay-hint" = { fg = "#9f9f9f" }
|
||||
"comment.block.documentation" = { fg = "black", modifiers = ["bold"] }
|
||||
"comment.line.documentation" = { fg = "black", modifiers = ["bold"] }
|
||||
"ui.statusline" = { bg = "statusbg", fg = "#ccdc90" }
|
||||
"ui.statusline.inactive" = { fg = '#2e3330', bg = '#88b090' }
|
||||
"ui.cursor" = { fg = "#000d18", bg = "#8faf9f", modifiers = ["bold"] }
|
||||
@@ -62,4 +63,4 @@ todo = "#dfdfdf"
|
||||
errorfg = "#e37170"
|
||||
errorbg = "#3d3535"
|
||||
statusbg = "#313633"
|
||||
numeric = "#8cd0d3"
|
||||
numeric = "#8cd0d3"
|
||||
|
Reference in New Issue
Block a user