Merge branch 'master'

pull/9723/head
mo8it 7 months ago
commit 2c7d62547e

@ -255,8 +255,8 @@ 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`, `nbsp`, `tab`, and `newline` | `"none"` |
| `characters` | Literal characters to use when rendering whitespace. Sub-keys may be any of `tab`, `space`, `nbsp`, `newline` or `tabpad` | See example below |
| `render` | Whether to render whitespace. May either be `"all"` or `"none"`, or a table with sub-keys `space`, `nbsp`, `nnbsp`, `tab`, and `newline` | `"none"` |
| `characters` | Literal characters to use when rendering whitespace. Sub-keys may be any of `tab`, `space`, `nbsp`, `nnbsp`, `newline` or `tabpad` | See example below |
Example
@ -267,11 +267,14 @@ render = "all"
[editor.whitespace.render]
space = "all"
tab = "all"
nbsp = "none"
nnbsp = "none"
newline = "none"
[editor.whitespace.characters]
space = "·"
nbsp = "⍽"
nnbsp = "␣"
tab = "→"
newline = "⏎"
tabpad = "·" # Tabs will look like "→···" (depending on tab width)

@ -128,6 +128,7 @@
| ocaml | ✓ | | ✓ | `ocamllsp` |
| ocaml-interface | ✓ | | | `ocamllsp` |
| odin | ✓ | | ✓ | `ols` |
| ohm | ✓ | ✓ | ✓ | |
| opencl | ✓ | ✓ | ✓ | `clangd` |
| openscad | ✓ | | | `openscad-lsp` |
| org | ✓ | | | |

@ -341,6 +341,7 @@ pub struct TextRenderer<'a> {
pub indent_guide_style: Style,
pub newline: String,
pub nbsp: String,
pub nnbsp: String,
pub space: String,
pub tab: String,
pub virtual_tab: String,
@ -395,6 +396,11 @@ impl<'a> TextRenderer<'a> {
} else {
" ".to_owned()
};
let nnbsp = if ws_render.nnbsp() == WhitespaceRenderValue::All {
ws_chars.nnbsp.into()
} else {
" ".to_owned()
};
let text_style = theme.get("ui.text");
@ -405,6 +411,7 @@ impl<'a> TextRenderer<'a> {
indent_guide_char: editor_config.indent_guides.character.into(),
newline,
nbsp,
nnbsp,
space,
tab,
virtual_tab,
@ -448,6 +455,7 @@ impl<'a> TextRenderer<'a> {
let width = grapheme.width();
let space = if is_virtual { " " } else { &self.space };
let nbsp = if is_virtual { " " } else { &self.nbsp };
let nnbsp = if is_virtual { " " } else { &self.nnbsp };
let tab = if is_virtual {
&self.virtual_tab
} else {
@ -461,6 +469,7 @@ impl<'a> TextRenderer<'a> {
// TODO special rendering for other whitespaces?
Grapheme::Other { ref g } if g == " " => space,
Grapheme::Other { ref g } if g == "\u{00A0}" => nbsp,
Grapheme::Other { ref g } if g == "\u{202F}" => nnbsp,
Grapheme::Other { ref g } => g,
Grapheme::Newline => &self.newline,
};

@ -4,6 +4,7 @@ use helix_core::unicode::width::UnicodeWidthStr;
use unicode_segmentation::UnicodeSegmentation;
const NBSP: &str = "\u{00a0}";
const NNBSP: &str = "\u{202f}";
/// A state machine to pack styled symbols into lines.
/// Cannot implement it as Iterator since it yields slices of the internal buffer (need streaming
@ -58,7 +59,8 @@ impl<'a, 'b> LineComposer<'a> for WordWrapper<'a, 'b> {
let mut symbols_exhausted = true;
for StyledGrapheme { symbol, style } in &mut self.symbols {
symbols_exhausted = false;
let symbol_whitespace = symbol.chars().all(&char::is_whitespace) && symbol != NBSP;
let symbol_whitespace =
symbol.chars().all(&char::is_whitespace) && symbol != NBSP && symbol != NNBSP;
// Ignore characters wider that the total max width.
if symbol.width() as u16 > self.max_line_width
@ -496,6 +498,20 @@ mod test {
assert_eq!(word_wrapper_space, vec!["AAAAAAAAAAAAAAA AAAA", "AAA",]);
}
#[test]
fn line_composer_word_wrapper_nnbsp() {
let width = 20;
let text = "AAAAAAAAAAAAAAA AAAA\u{202f}AAA";
let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: true }, text, width);
assert_eq!(word_wrapper, vec!["AAAAAAAAAAAAAAA", "AAAA\u{202f}AAA",]);
// Ensure that if the character was a regular space, it would be wrapped differently.
let text_space = text.replace('\u{202f}', " ");
let (word_wrapper_space, _) =
run_composer(Composer::WordWrapper { trim: true }, &text_space, width);
assert_eq!(word_wrapper_space, vec!["AAAAAAAAAAAAAAA AAAA", "AAA",]);
}
#[test]
fn line_composer_word_wrapper_preserve_indentation() {
let width = 20;

@ -722,6 +722,7 @@ pub enum WhitespaceRender {
default: Option<WhitespaceRenderValue>,
space: Option<WhitespaceRenderValue>,
nbsp: Option<WhitespaceRenderValue>,
nnbsp: Option<WhitespaceRenderValue>,
tab: Option<WhitespaceRenderValue>,
newline: Option<WhitespaceRenderValue>,
},
@ -753,6 +754,14 @@ impl WhitespaceRender {
}
}
}
pub fn nnbsp(&self) -> WhitespaceRenderValue {
match *self {
Self::Basic(val) => val,
Self::Specific { default, nnbsp, .. } => {
nnbsp.or(default).unwrap_or(WhitespaceRenderValue::None)
}
}
}
pub fn tab(&self) -> WhitespaceRenderValue {
match *self {
Self::Basic(val) => val,
@ -776,6 +785,7 @@ impl WhitespaceRender {
pub struct WhitespaceCharacters {
pub space: char,
pub nbsp: char,
pub nnbsp: char,
pub tab: char,
pub tabpad: char,
pub newline: char,
@ -786,6 +796,7 @@ impl Default for WhitespaceCharacters {
Self {
space: '·', // U+00B7
nbsp: '', // U+237D
nnbsp: '', // U+2423
tab: '', // U+2192
newline: '', // U+23CE
tabpad: ' ',

@ -3408,3 +3408,25 @@ formatter = { command = "prettier", args = ['--parser', 'glimmer'] }
[[grammar]]
name = "glimmer"
source = { git = "https://github.com/ember-tooling/tree-sitter-glimmer", rev = "5dc6d1040e8ff8978ff3680e818d85447bbc10aa" }
[[language]]
name = "ohm"
scope = "source.ohm"
injection-regex = "ohm"
file-types = ["ohm"]
comment-token = "//"
block-comment-tokens = [
{ start = "/*", end = "*/" },
{ start = "/**", end = "*/" },
]
indent = { tab-width = 2, unit = " " }
[language.auto-pairs]
'"' = '"'
'{' = '}'
'(' = ')'
'<' = '>'
[[grammar]]
name = "ohm"
source = { git = "https://github.com/novusnota/tree-sitter-ohm", rev = "80f14f0e477ddacc1e137d5ed8e830329e3fb7a3" }

@ -0,0 +1,122 @@
; See: https://docs.helix-editor.com/master/themes.html#syntax-highlighting
; attribute
; ---------
(case_name) @attribute
; comment.line
; ------------
[
(singleline_comment)
(rule_descr)
] @comment.line
; comment.block
; -------------
(multiline_comment) @comment.block
; function.method
; ---------------
(rule
name: (identifier) @function.method)
; function.builtin
; ----------------
; Lexical
((identifier) @function.builtin
(#any-of? @function.builtin
"any"
"alnum"
"end"
"digit" "hexDigit"
"letter"
"space"
"lower" "upper" "caseInsensitive"
"listOf" "nonemptyListOf" "emptyListOf"
"applySyntactic")
(#is-not? local))
; Syntactic
((identifier) @function.builtin
(#any-of? @function.builtin "ListOf" "NonemptyListOf" "EmptyListOf")
(#is-not? local))
; function.method (continuing)
; ---------------
(term
base: (identifier) @function.method)
; string.special
; --------------
(escape_char) @constant.character.escape
; string
; ------
[
(terminal_string)
(one_char_terminal)
] @string
; type
; ----
(super_grammar
name: (identifier) @type)
(grammar
name: (identifier) @type)
; operator
; --------
[
; "=" ":=" "+="
(define) (override) (extend)
; "&" "~"
(lookahead) (negative_lookahead)
; "#"
(lexification)
; "*" "+" "?"
(zero_or_more) (one_or_more) (zero_or_one)
; "..."
(super_splice)
"<:" ".." "|"
] @operator
; punctuation.bracket
; -------------------
[
"<"
">"
"{"
"}"
] @punctuation.bracket
(alt
"(" @punctuation.bracket
")" @punctuation.bracket)
; punctuation.delimiter
; ---------------------
"," @punctuation.delimiter
; variable.parameter
; ------------------
(formals
(identifier) @variable.parameter)

@ -0,0 +1,37 @@
; See: https://docs.helix-editor.com/guides/indent.html
; indent
; ------
[
; <..., ...>
(formals)
(params)
; (...| ...)
(alt)
] @indent
; outdent
; -------
[
"}"
")"
">"
] @outdent
; align
; -----
; | ... | ...
(rule_body
. (top_level_term) @anchor
(#set! "scope" "tail")) @align
; N/A or unused:
; --------------
; indent.always
; outdent.always
; extend
; extend.prevent-once

@ -0,0 +1,7 @@
; See: https://docs.helix-editor.com/guides/injection.html
((singleline_comment) @injection.content
(#set! injection.language "comment"))
((multiline_comment) @injection.content
(#set! injection.language "comment"))

@ -0,0 +1,40 @@
; See: https://docs.helix-editor.com/guides/textobject.html
; function.inside & around
; ------------------------
(rule
body: (_) @function.inside) @function.around
; class.inside & around
; ---------------------
(grammar
body: (_) @class.inside) @class.around
; parameter.inside & around
; -------------------------
(formals
((_) @parameter.inside . ","? @parameter.around) @parameter.around)
(rule_body
((_) @parameter.inside . "|"? @parameter.around) @parameter.around)
(params
((_) @parameter.inside . ","? @parameter.around) @parameter.around)
(alt
((_) @parameter.inside . "|"? @parameter.around) @parameter.around)
; comment.inside
; --------------
(multiline_comment)+ @comment.inside
(singleline_comment)+ @comment.inside
; comment.around
; --------------
(multiline_comment)+ @comment.around
(singleline_comment)+ @comment.around

@ -89,6 +89,7 @@
"ui.virtual.ruler" = { bg = "surface0" }
"ui.virtual.indent-guide" = "surface0"
"ui.virtual.inlay-hint" = { fg = "overlay0", bg = "base" }
"ui.virtual.jump-label" = { fg = "rosewater", modifiers = ["bold"] }
"ui.selection" = { bg = "surface1" }

@ -90,6 +90,7 @@
"ui.virtual.ruler" = { bg = "borders" }
"ui.virtual.indent-guide" = { fg = "dark_gray4" }
"ui.virtual.inlay-hint" = { fg = "dark_gray5"}
"ui.virtual.jump-label" = { fg = "dark_gray", modifiers = ["bold"] }
"warning" = { fg = "gold2" }
"error" = { fg = "red" }

@ -27,8 +27,8 @@ namespace = "orange"
"ui.gutter" = "gray"
"ui.gutter.selected" = "light-gray"
"ui.selection" = { bg = "selection" }
"ui.virtual.indent-guide" = { fg = "gray"}
"ui.virtual.whitespace" = { fg = "light-gray"}
"ui.virtual.indent-guide" = { fg = "gray" }
"ui.virtual.whitespace" = { fg = "light-gray" }
"ui.statusline" = { bg = "dark-bg", fg = "light-gray" }
"ui.popup" = { bg = "dark-bg", fg = "orange" }
"ui.help" = { bg = "dark-bg", fg = "orange" }
@ -37,13 +37,14 @@ namespace = "orange"
"ui.window" = "selection"
"ui.bufferline" = { bg = "dark-bg", fg = "light-gray" }
"ui.bufferline.active" = { bg = "dark-bg", fg = "orange" }
"ui.virtual.jump-label" = { fg = "pink", modifiers = ["bold"] }
# Diagnostics
"diagnostic" = { underline = { style = "curl" } }
"diagnostic.hint" = { underline = { color = "green", style = "curl" } }
"diagnostic.info" = { underline = { color = "blue", style = "curl" } }
"diagnostics.error" = { underline = { color = "red", style = "curl"} }
"diagnostics.warning" = { underline = { color = "orange", style = "curl"} }
"diagnostics.error" = { underline = { color = "red", style = "curl" } }
"diagnostics.warning" = { underline = { color = "orange", style = "curl" } }
warning = { fg = "orange", modifiers = ["bold"] }
error = { fg = "red", modifiers = ["bold"] }

@ -56,6 +56,7 @@
"ui.virtual.whitespace" = { fg = "light-gray" }
"ui.virtual.ruler" = { bg = "gray" }
"ui.virtual.inlay-hint" = { fg = "light-gray" }
"ui.virtual.jump-label" = { fg = "light-gray", modifiers = ["bold"] }
"ui.cursor" = { fg = "white", modifiers = ["reversed"] }
"ui.cursor.primary" = { fg = "white", modifiers = ["reversed"] }

@ -37,6 +37,7 @@
"ui.text.focus" = { bg = "overlay" }
"ui.text.info" = { fg = "subtle" }
"ui.virtual.jump-label" = { fg = "love", modifiers = ["bold"] }
"ui.virtual.ruler" = { bg = "overlay" }
"ui.virtual.whitespace" = { fg = "highlight_high" }
"ui.virtual.indent-guide" = { fg = "muted" }

Loading…
Cancel
Save