Skip to content

Commit ea55858

Browse files
committed
feat(view): render soft-wrap indicators in the gutter
Moves the soft-wrap indicator into the gutter to keep the text flush and take an advantage of otherwise empty space. Fixes: #14802
1 parent 68c7e87 commit ea55858

File tree

5 files changed

+12
-29
lines changed

5 files changed

+12
-29
lines changed

helix-core/src/doc_formatter.rs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ pub struct TextFormat {
148148
pub tab_width: u16,
149149
pub max_wrap: u16,
150150
pub max_indent_retain: u16,
151-
pub wrap_indicator: Box<str>,
152151
pub wrap_indicator_highlight: Option<Highlight>,
153152
pub viewport_width: u16,
154153
pub soft_wrap_at_text_width: bool,
@@ -162,7 +161,6 @@ impl Default for TextFormat {
162161
tab_width: 4,
163162
max_wrap: 3,
164163
max_indent_retain: 4,
165-
wrap_indicator: Box::from(" "),
166164
viewport_width: 17,
167165
wrap_indicator_highlight: None,
168166
soft_wrap_at_text_width: false,
@@ -311,25 +309,8 @@ impl<'t> DocumentFormatter<'t> {
311309
.virtual_lines_at(self.char_pos, self.visual_pos, self.line_pos);
312310
self.visual_pos.col = indent_carry_over as usize;
313311
self.visual_pos.row += 1 + virtual_lines;
314-
let mut i = 0;
315312
let mut word_width = 0;
316-
let wrap_indicator = UnicodeSegmentation::graphemes(&*self.text_fmt.wrap_indicator, true)
317-
.map(|g| {
318-
i += 1;
319-
let grapheme = GraphemeWithSource::new(
320-
g.into(),
321-
self.visual_pos.col + word_width,
322-
self.text_fmt.tab_width,
323-
GraphemeSource::VirtualText {
324-
highlight: self.text_fmt.wrap_indicator_highlight,
325-
},
326-
);
327-
word_width += grapheme.width();
328-
grapheme
329-
});
330-
self.word_buf.splice(0..0, wrap_indicator);
331-
332-
for grapheme in &mut self.word_buf[i..] {
313+
for grapheme in &mut self.word_buf {
333314
let visual_x = self.visual_pos.col + word_width;
334315
grapheme
335316
.grapheme

helix-core/src/doc_formatter/test.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ impl TextFormat {
88
tab_width: 2,
99
max_wrap: 3,
1010
max_indent_retain: 4,
11-
wrap_indicator: ".".into(),
1211
wrap_indicator_highlight: None,
1312
// use a prime number to allow lining up too often with repeat
1413
viewport_width: 17,

helix-view/src/annotations/diagnostics.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ impl InlineDiagnosticsConfig {
9898
tab_width: 4,
9999
max_wrap: self.max_wrap.min(width / 4),
100100
max_indent_retain: 0,
101-
wrap_indicator: "".into(),
102101
wrap_indicator_highlight: None,
103102
viewport_width: width,
104103
soft_wrap_at_text_width: true,

helix-view/src/document.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2258,10 +2258,6 @@ impl Document {
22582258
.and_then(|soft_wrap| soft_wrap.max_indent_retain)
22592259
.or(editor_soft_wrap.max_indent_retain)
22602260
.unwrap_or(40);
2261-
let wrap_indicator = language_soft_wrap
2262-
.and_then(|soft_wrap| soft_wrap.wrap_indicator.clone())
2263-
.or_else(|| config.soft_wrap.wrap_indicator.clone())
2264-
.unwrap_or_else(|| "↪ ".into());
22652261
let tab_width = self.tab_width() as u16;
22662262
TextFormat {
22672263
soft_wrap: enable_soft_wrap && viewport_width > 10,
@@ -2271,7 +2267,6 @@ impl Document {
22712267
// avoid spinning forever when the window manager
22722268
// sets the size to something tiny
22732269
viewport_width,
2274-
wrap_indicator: wrap_indicator.into_boxed_str(),
22752270
wrap_indicator_highlight: theme
22762271
.and_then(|theme| theme.find_highlight("ui.virtual.wrap")),
22772272
soft_wrap_at_text_width,

helix-view/src/gutter.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,15 @@ pub fn line_numbers<'doc>(
163163
.char_to_line(doc.selection(view.id).primary().cursor(text));
164164

165165
let line_number = editor.config().line_number;
166+
let wrap_indicator = editor
167+
.config()
168+
.soft_wrap
169+
.wrap_indicator
170+
.as_ref()
171+
.map_or_else(
172+
|| "↪".into(),
173+
|indicator| indicator.clone().chars().take(width).collect::<String>(),
174+
);
166175
let mode = editor.mode;
167176

168177
Box::new(
@@ -193,10 +202,10 @@ pub fn line_numbers<'doc>(
193202
if first_visual_line {
194203
write!(out, "{:>1$}", display_num, width).unwrap();
195204
} else {
196-
write!(out, "{:>1$}", " ", width).unwrap();
205+
write!(out, "{:>1$}", wrap_indicator, width).unwrap();
197206
}
198207

199-
first_visual_line.then_some(style)
208+
Some(style)
200209
}
201210
},
202211
)

0 commit comments

Comments
 (0)