Skip to content

Commit 35f26da

Browse files
committed
Add rainbow indentation guides
ref: helix-editor#4493
1 parent 28328c0 commit 35f26da

File tree

4 files changed

+53
-15
lines changed

4 files changed

+53
-15
lines changed

book/src/configuration.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,12 @@ tabpad = "·" # Tabs will look like "→···" (depending on tab width)
261261

262262
Options for rendering vertical indent guides.
263263

264-
| Key | Description | Default |
265-
| --- | --- | --- |
266-
| `render` | Whether to render indent guides | `false` |
267-
| `character` | Literal character to use for rendering the indent guide | `` |
268-
| `skip-levels` | Number of indent levels to skip | `0` |
264+
| Key | Description | Default |
265+
| --- | --- | --- |
266+
| `render` | Whether to render indent indent-guides | `false` |
267+
| `character` | Literal character to use for rendering the indent guide | `` |
268+
| `skip-levels` | Number of indent levels to skip | `0` |
269+
| `rainbow-option` | Enum to set rainbow indentations. Options: `normal`, `dim` and `none`| `none` |
269270

270271
Example:
271272

@@ -274,6 +275,7 @@ Example:
274275
render = true
275276
character = "" # Some characters that work well: "▏", "┆", "┊", "⸽"
276277
skip-levels = 1
278+
rainbow-option = "normal"
277279
```
278280

279281
### `[editor.gutters]` Section

helix-term/src/ui/document.rs

+32-10
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use helix_core::syntax::Highlight;
77
use helix_core::syntax::HighlightEvent;
88
use helix_core::text_annotations::TextAnnotations;
99
use helix_core::{visual_offset_from_block, Position, RopeSlice};
10-
use helix_view::editor::{WhitespaceConfig, WhitespaceRenderValue};
10+
use helix_view::editor::{RainbowIndentOptions, WhitespaceConfig, WhitespaceRenderValue};
1111
use helix_view::graphics::Rect;
12-
use helix_view::theme::Style;
12+
use helix_view::theme::{Modifier, Style};
1313
use helix_view::view::ViewPosition;
1414
use helix_view::Document;
1515
use helix_view::Theme;
@@ -310,6 +310,8 @@ pub struct TextRenderer<'a> {
310310
pub whitespace_style: Style,
311311
pub indent_guide_char: String,
312312
pub indent_guide_style: Style,
313+
pub indent_guide_rainbow: RainbowIndentOptions,
314+
pub theme: &'a Theme,
313315
pub newline: String,
314316
pub nbsp: String,
315317
pub space: String,
@@ -326,7 +328,7 @@ impl<'a> TextRenderer<'a> {
326328
pub fn new(
327329
surface: &'a mut Surface,
328330
doc: &Document,
329-
theme: &Theme,
331+
theme: &'a Theme,
330332
col_offset: usize,
331333
viewport: Rect,
332334
) -> TextRenderer<'a> {
@@ -363,12 +365,19 @@ impl<'a> TextRenderer<'a> {
363365
};
364366

365367
let text_style = theme.get("ui.text");
368+
let basic_style = text_style.patch(
369+
theme
370+
.try_get("ui.virtual.indent-guide")
371+
.unwrap_or_else(|| theme.get("ui.virtual.whitespace")),
372+
);
366373

367374
let indent_width = doc.indent_style.indent_width(tab_width) as u16;
368375

369376
TextRenderer {
370377
surface,
371378
indent_guide_char: editor_config.indent_guides.character.into(),
379+
indent_guide_rainbow: editor_config.indent_guides.rainbow_option.clone(),
380+
theme,
372381
newline,
373382
nbsp,
374383
space,
@@ -379,11 +388,7 @@ impl<'a> TextRenderer<'a> {
379388
starting_indent: col_offset / indent_width as usize
380389
+ (col_offset % indent_width as usize != 0) as usize
381390
+ editor_config.indent_guides.skip_levels as usize,
382-
indent_guide_style: text_style.patch(
383-
theme
384-
.try_get("ui.virtual.indent-guide")
385-
.unwrap_or_else(|| theme.get("ui.virtual.whitespace")),
386-
),
391+
indent_guide_style: basic_style,
387392
text_style,
388393
draw_indent_guides: editor_config.indent_guides.render,
389394
viewport,
@@ -477,8 +482,25 @@ impl<'a> TextRenderer<'a> {
477482
as u16;
478483
let y = self.viewport.y + row;
479484
debug_assert!(self.surface.in_bounds(x, y));
480-
self.surface
481-
.set_string(x, y, &self.indent_guide_char, self.indent_guide_style);
485+
match self.indent_guide_rainbow {
486+
RainbowIndentOptions::None => {
487+
self.surface
488+
.set_string(x, y, &self.indent_guide_char, self.indent_guide_style)
489+
}
490+
RainbowIndentOptions::Dim => {
491+
let new_style = self
492+
.indent_guide_style
493+
.patch(self.theme.get_rainbow(i))
494+
.add_modifier(Modifier::DIM);
495+
self.surface
496+
.set_string(x, y, &self.indent_guide_char, new_style);
497+
}
498+
RainbowIndentOptions::Normal => {
499+
let new_style = self.indent_guide_style.patch(self.theme.get_rainbow(i));
500+
self.surface
501+
.set_string(x, y, &self.indent_guide_char, new_style);
502+
}
503+
};
482504
}
483505
}
484506
}

helix-view/src/editor.rs

+10
Original file line numberDiff line numberDiff line change
@@ -743,12 +743,21 @@ impl Default for WhitespaceCharacters {
743743
}
744744
}
745745

746+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
747+
#[serde(rename_all = "kebab-case")]
748+
pub enum RainbowIndentOptions {
749+
None,
750+
Dim,
751+
Normal,
752+
}
753+
746754
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
747755
#[serde(default, rename_all = "kebab-case")]
748756
pub struct IndentGuidesConfig {
749757
pub render: bool,
750758
pub character: char,
751759
pub skip_levels: u8,
760+
pub rainbow_option: RainbowIndentOptions,
752761
}
753762

754763
impl Default for IndentGuidesConfig {
@@ -757,6 +766,7 @@ impl Default for IndentGuidesConfig {
757766
skip_levels: 0,
758767
render: false,
759768
character: '│',
769+
rainbow_option: RainbowIndentOptions::None,
760770
}
761771
}
762772
}

helix-view/src/theme.rs

+4
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,10 @@ impl Theme {
378378
pub fn rainbow_length(&self) -> usize {
379379
self.rainbow_length
380380
}
381+
382+
pub fn get_rainbow(&self, index: usize) -> Style {
383+
self.highlights[index % self.rainbow_length]
384+
}
381385
}
382386

383387
fn default_rainbow() -> Vec<Style> {

0 commit comments

Comments
 (0)