diff options
| author | Maxime Coste <mawww@kakoune.org> | 2017-11-03 19:30:31 +0800 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2017-11-03 19:30:31 +0800 |
| commit | 400ef6d48cd3e531251993d358b90d305b236e45 (patch) | |
| tree | 5d4af3f61a25b936f22d23dc7cae0716c4b6d407 /src | |
| parent | 9d6420caae76cbb73e7660e084cb3d1d9867fef3 (diff) | |
Wrap: rework logic to avoid infinite loop with multiple wrap highlighters
The display is still going to be wrong, as wrapping is going to take place
multiple times, but Kakoune should not freeze anymore.
Diffstat (limited to 'src')
| -rw-r--r-- | src/highlighters.cc | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/src/highlighters.cc b/src/highlighters.cc index ade701e7..8da4d6bd 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -758,10 +758,10 @@ struct WrapHighlighter : Highlighter setup.scroll_offset.column = 0; setup.full_lines = true; - const LineCount win_height = context.window().dimensions().line; LineCount win_line = 0; for (auto buf_line = setup.window_pos.line; - buf_line < setup.window_pos.line + setup.window_range.line; + buf_line < setup.window_pos.line + setup.window_range.line or + buf_line <= cursor.line; ++buf_line) { if (buf_line >= buffer.line_count()) @@ -774,36 +774,32 @@ struct WrapHighlighter : Highlighter const auto wrap_count = line_wrap_count(buf_line, indent); setup.window_range.line -= wrap_count; - if (win_line < setup.cursor_pos.line) - setup.cursor_pos.line += wrap_count; - // Place the cursor correctly after its line gets wrapped - else if (win_line == setup.cursor_pos.line) + if (buf_line == cursor.line) { BufferCoord coord{buf_line}; - while (true) + for (LineCount count = 0; true; ++count) { auto split_coord = next_split_coord(buffer, wrap_column - (coord.column == 0 ? 0_col : indent), tabstop, coord); if (split_coord.column > cursor.column) { - setup.cursor_pos.column = get_column(buffer, tabstop, cursor) - get_column(buffer, tabstop, coord); - if (coord.column != 0) - setup.cursor_pos.column += indent; - + setup.cursor_pos = DisplayCoord{ + win_line + count, + get_column(buffer, tabstop, cursor) - + get_column(buffer, tabstop, coord) + + (coord.column != 0 ? indent : 0_col) + }; break; } - ++setup.cursor_pos.line; coord = split_coord; } kak_assert(setup.cursor_pos.column >= 0 and setup.cursor_pos.column < setup.window_range.column); - if (setup.cursor_pos.line >= win_height) // In that case we will remove some lines from the top - setup.cursor_pos.line = win_height - 1; } win_line += wrap_count + 1; // scroll window to keep cursor visible, and update range as lines gets removed while (setup.window_pos.line < cursor.line and - setup.cursor_pos.line >= win_height - setup.scroll_offset.line) + cursor.line + setup.scroll_offset.line >= setup.window_pos.line + setup.window_range.line) { auto removed_lines = 1 + line_wrap_count(setup.window_pos.line++, indent); setup.cursor_pos.line -= removed_lines; @@ -826,14 +822,14 @@ struct WrapHighlighter : Highlighter auto column = get_column(buffer, tabstop, coord); auto col = get_byte_to_column( buffer, tabstop, {coord.line, column + wrap_column}); + StringView line = buffer[coord.line]; if (col == coord.column) // Can happen if we try to wrap on a tab char - col = buffer.char_next(coord).column; + col = line.byte_count_to(line.char_count_to(coord.column)+1); BufferCoord split_coord{coord.line, col}; if (m_word_wrap) { - StringView line = buffer[coord.line]; utf8::iterator<const char*> it{&line[col], line}; while (it != line.end() and it != line.begin() and is_word<WORD>(*it)) --it; |
