diff --git a/README.md b/README.md index 6661221..13d5567 100644 --- a/README.md +++ b/README.md @@ -234,6 +234,7 @@ require('nuwiki').setup({ exclude_files = {}, -- glob patterns -- Checkbox progression characters: " .oOX" by default. listsyms = ' .oOX', + listsym_rejected = '-', -- glyph for a cancelled checkbox [-] listsyms_propagate = true, }, }, @@ -327,6 +328,7 @@ Each is a boolean. All default to `true` except `mouse`. | `diary_sort` | string | `'desc'` | `'desc'` \| `'asc'` | | `diary_header` | string | `'Diary'` | any heading text | | `listsyms` | string | `' .oOX'` | checkbox progression chars | +| `listsym_rejected` | string | `'-'` | glyph for a cancelled checkbox (`[-]`); first char used | | `listsyms_propagate` | bool | `true` | `true` \| `false` | | `list_margin` | int | `-1` | `-1` (auto) or `≥ 0` | | `links_space_char` | string | `' '` | char that replaces spaces in synthesised link paths | diff --git a/crates/nuwiki-core/src/listsyms.rs b/crates/nuwiki-core/src/listsyms.rs index 51e4218..0186480 100644 --- a/crates/nuwiki-core/src/listsyms.rs +++ b/crates/nuwiki-core/src/listsyms.rs @@ -10,32 +10,47 @@ use crate::ast::CheckboxState; +/// Default rejected/cancelled marker (vimwiki's `listsym_rejected`). const REJECTED: char = '-'; /// An ordered checkbox progress palette. Always holds at least two glyphs. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListSyms { progression: Vec, + rejected: char, } impl Default for ListSyms { fn default() -> Self { Self { progression: " .oOX".chars().collect(), + rejected: REJECTED, } } } impl ListSyms { - /// Build a palette from a glyph string. Falls back to the default when - /// fewer than two glyphs are supplied (a one-symbol palette can't express - /// both "empty" and "done"). + /// Build a palette from a glyph string, with the default rejected marker. + /// Falls back to the default when fewer than two glyphs are supplied (a + /// one-symbol palette can't express both "empty" and "done"). pub fn new(s: &str) -> Self { + Self::new_with_rejected(s, REJECTED) + } + + /// Like [`new`](Self::new) but with a custom rejected/cancelled glyph + /// (vimwiki's `listsym_rejected`). + pub fn new_with_rejected(s: &str, rejected: char) -> Self { let progression: Vec = s.chars().collect(); if progression.len() < 2 { - Self::default() + Self { + rejected, + ..Self::default() + } } else { - Self { progression } + Self { + progression, + rejected, + } } } @@ -56,7 +71,7 @@ impl ListSyms { } pub fn rejected_glyph(&self) -> char { - REJECTED + self.rejected } pub fn glyph_at(&self, index: usize) -> char { @@ -76,7 +91,7 @@ impl ListSyms { /// Normalised five-bucket [`CheckboxState`] for a glyph, or `None` when the /// glyph is not part of this palette (and is not the rejected marker). pub fn state_of(&self, c: char) -> Option { - if c == REJECTED { + if c == self.rejected { return Some(CheckboxState::Rejected); } let index = self.index_of(c)?; @@ -96,7 +111,7 @@ impl ListSyms { /// `ceil` rule, matching the stock five-symbol behaviour. pub fn glyph_for_rate(&self, rate: i32) -> char { if rate < 0 { - return REJECTED; + return self.rejected; } if rate <= 0 { return self.empty_glyph(); @@ -157,6 +172,19 @@ mod tests { assert_eq!(ListSyms::new("x"), ListSyms::default()); } + #[test] + fn custom_rejected_glyph_is_honoured() { + // `listsym_rejected = '✗'`: that glyph lexes/snaps as Rejected and the + // default `-` no longer does. + let s = ListSyms::new_with_rejected(" .oOX", '✗'); + assert_eq!(s.rejected_glyph(), '✗'); + assert_eq!(s.state_of('✗'), Some(CheckboxState::Rejected)); + assert_eq!(s.glyph_for_rate(-1), '✗'); + assert_eq!(s.state_of('-'), None); // no longer the rejected marker + // A short palette still keeps the custom rejected glyph. + assert_eq!(ListSyms::new_with_rejected("x", '✗').rejected_glyph(), '✗'); + } + #[test] fn custom_palette_buckets_to_nearest_state() { // 3 glyphs → rates 0 / 50 / 100. diff --git a/crates/nuwiki-lsp/src/commands.rs b/crates/nuwiki-lsp/src/commands.rs index 7db8e97..6eb5ace 100644 --- a/crates/nuwiki-lsp/src/commands.rs +++ b/crates/nuwiki-lsp/src/commands.rs @@ -250,7 +250,7 @@ fn list_checkbox( let wiki = backend.wiki_for_uri(&p.uri); let syms = wiki .as_ref() - .map(|w| nuwiki_core::listsyms::ListSyms::new(&w.config.listsyms)) + .map(|w| w.config.list_syms()) .unwrap_or_default(); let propagate = wiki.map(|w| w.config.listsyms_propagate).unwrap_or(true); Ok(ops::checkbox_edit( @@ -1184,10 +1184,8 @@ fn export_all(backend: &Backend, args: Vec, force: bool) -> Result