Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix rendering of lines longer than 2^16 #4172

Merged
merged 4 commits into from
Oct 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 22 additions & 18 deletions helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use helix_view::{
keyboard::{KeyCode, KeyModifiers},
Document, Editor, Theme, View,
};
use std::{borrow::Cow, path::PathBuf};
use std::{borrow::Cow, cmp::min, path::PathBuf};

use tui::buffer::Buffer as Surface;

Expand Down Expand Up @@ -404,7 +404,7 @@ impl EditorView {
let characters = &whitespace.characters;

let mut spans = Vec::new();
let mut visual_x = 0u16;
let mut visual_x = 0usize;
let mut line = 0u16;
let tab_width = doc.tab_width();
let tab = if whitespace.render.tab() == WhitespaceRenderValue::All {
Expand Down Expand Up @@ -442,17 +442,21 @@ impl EditorView {
}

let starting_indent =
(offset.col / tab_width) as u16 + config.indent_guides.skip_levels;
// TODO: limit to a max indent level too. It doesn't cause visual artifacts but it would avoid some
// extra loops if the code is deeply nested.

for i in starting_indent..(indent_level / tab_width as u16) {
surface.set_string(
viewport.x + (i * tab_width as u16) - offset.col as u16,
viewport.y + line,
&indent_guide_char,
indent_guide_style,
);
(offset.col / tab_width) + config.indent_guides.skip_levels as usize;

// Don't draw indent guides outside of view
let end_indent = min(
indent_level,
// Add tab_width - 1 to round up, since the first visible
// indent might be a bit after offset.col
offset.col + viewport.width as usize + (tab_width - 1),
) / tab_width;

for i in starting_indent..end_indent {
let x = (viewport.x as usize + (i * tab_width) - offset.col) as u16;
let y = viewport.y + line;
debug_assert!(surface.in_bounds(x, y));
surface.set_string(x, y, &indent_guide_char, indent_guide_style);
}
};

Expand Down Expand Up @@ -494,14 +498,14 @@ impl EditorView {
use helix_core::graphemes::{grapheme_width, RopeGraphemes};

for grapheme in RopeGraphemes::new(text) {
let out_of_bounds = visual_x < offset.col as u16
|| visual_x >= viewport.width + offset.col as u16;
let out_of_bounds = offset.col > (visual_x as usize)
|| (visual_x as usize) >= viewport.width as usize + offset.col;

if LineEnding::from_rope_slice(&grapheme).is_some() {
if !out_of_bounds {
// we still want to render an empty cell with the style
surface.set_string(
viewport.x + visual_x - offset.col as u16,
(viewport.x as usize + visual_x - offset.col) as u16,
viewport.y + line,
&newline,
style.patch(whitespace_style),
Expand Down Expand Up @@ -549,7 +553,7 @@ impl EditorView {
if !out_of_bounds {
// if we're offscreen just keep going until we hit a new line
surface.set_string(
viewport.x + visual_x - offset.col as u16,
(viewport.x as usize + visual_x - offset.col) as u16,
viewport.y + line,
display_grapheme,
if is_whitespace {
Expand Down Expand Up @@ -582,7 +586,7 @@ impl EditorView {
last_line_indent_level = visual_x;
}

visual_x = visual_x.saturating_add(width as u16);
visual_x = visual_x.saturating_add(width);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ impl Default for WhitespaceCharacters {
pub struct IndentGuidesConfig {
pub render: bool,
pub character: char,
pub skip_levels: u16,
pub skip_levels: u8,
}

impl Default for IndentGuidesConfig {
Expand Down