diff --git a/book/src/configuration.md b/book/src/configuration.md index 439c80f1c..913897d62 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -145,7 +145,7 @@ Options for rendering whitespace with visible characters. Use `:set whitespace.r | Key | Description | Default | |-----|-------------|---------| | `render` | Whether to render whitespace. May either be `"all"` or `"none"`, or a table with sub-keys `space`, `tab`, and `newline`. | `"none"` | -| `characters` | Literal characters to use when rendering whitespace. Sub-keys may be any of `tab`, `space` or `newline` | See example below | +| `characters` | Literal characters to use when rendering whitespace. Sub-keys may be any of `tab`, `space`, `nbsp` or `newline` | See example below | Example @@ -160,6 +160,7 @@ newline = "none" [editor.whitespace.characters] space = "·" +nbsp = "⍽" tab = "→" newline = "⏎" ``` diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 5ceff39e5..52e581632 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -370,6 +370,7 @@ impl EditorView { " ".repeat(tab_width) }; let space = whitespace.characters.space.to_string(); + let nbsp = whitespace.characters.nbsp.to_string(); let newline = if whitespace.render.newline() == WhitespaceRenderValue::All { whitespace.characters.newline.to_string() } else { @@ -406,6 +407,14 @@ impl EditorView { " " }; + let nbsp = if whitespace.render.nbsp() == WhitespaceRenderValue::All + && text.len_chars() < end + { +   + } else { + " " + }; + use helix_core::graphemes::{grapheme_width, RopeGraphemes}; for grapheme in RopeGraphemes::new(text) { @@ -445,6 +454,9 @@ impl EditorView { } else if grapheme == " " { is_whitespace = true; (space, 1) + } else if grapheme == "\u{00A0}" { + is_whitespace = true; + (nbsp, 1) } else { is_whitespace = false; // Cow will prevent allocations if span contained in a single slice diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 38826f4bf..0de1732c3 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -288,6 +288,7 @@ pub enum WhitespaceRender { Specific { default: Option, space: Option, + nbsp: Option, tab: Option, newline: Option, }, @@ -311,6 +312,14 @@ impl WhitespaceRender { } } } + pub fn nbsp(&self) -> WhitespaceRenderValue { + match *self { + Self::Basic(val) => val, + Self::Specific { default, nbsp, .. } => { + nbsp.or(default).unwrap_or(WhitespaceRenderValue::None) + } + } + } pub fn tab(&self) -> WhitespaceRenderValue { match *self { Self::Basic(val) => val, @@ -333,6 +342,7 @@ impl WhitespaceRender { #[serde(default)] pub struct WhitespaceCharacters { pub space: char, + pub nbsp: char, pub tab: char, pub newline: char, } @@ -341,6 +351,7 @@ impl Default for WhitespaceCharacters { fn default() -> Self { Self { space: '·', // U+00B7 + nbsp: '⍽', // U+237D tab: '→', // U+2192 newline: '⏎', // U+23CE }