diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/client.cc | 3 | ||||
| -rw-r--r-- | src/context.hh | 2 | ||||
| -rw-r--r-- | src/highlighter.hh | 1 | ||||
| -rw-r--r-- | src/highlighters.cc | 6 | ||||
| -rw-r--r-- | src/input_handler.cc | 37 | ||||
| -rw-r--r-- | src/input_handler.hh | 8 | ||||
| -rw-r--r-- | src/normal.cc | 7 | ||||
| -rw-r--r-- | src/window.cc | 17 |
8 files changed, 53 insertions, 28 deletions
diff --git a/src/client.cc b/src/client.cc index 6996ee13..5d6cee62 100644 --- a/src/client.cc +++ b/src/client.cc @@ -109,7 +109,10 @@ bool Client::process_pending_inputs() else if (key == Key::FocusOut) context().hooks().run_hook(Hook::FocusOut, context().name(), context()); else + { + context().ensure_cursor_visible = true; m_input_handler.handle_key(key); + } context().hooks().run_hook(Hook::RawKey, to_string(key), context()); } diff --git a/src/context.hh b/src/context.hh index 69377148..f6f00b80 100644 --- a/src/context.hh +++ b/src/context.hh @@ -144,6 +144,8 @@ public: void repeat_last_select() { if (m_last_select) m_last_select(*this); } Buffer* last_buffer() const; + + bool ensure_cursor_visible = true; private: void begin_edition(); void end_edition(); diff --git a/src/highlighter.hh b/src/highlighter.hh index ad94f44d..925dcaa7 100644 --- a/src/highlighter.hh +++ b/src/highlighter.hh @@ -46,6 +46,7 @@ struct DisplaySetup DisplayCoord cursor_pos; // Offset of line and columns that must remain visible around cursor DisplayCoord scroll_offset; + bool ensure_cursor_visible; }; using HighlighterIdList = ConstArrayView<StringView>; diff --git a/src/highlighters.cc b/src/highlighters.cc index 6f6d6e30..954f1417 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -752,7 +752,8 @@ struct WrapHighlighter : Highlighter win_line += wrap_count + 1; // scroll window to keep cursor visible, and update range as lines gets removed - while (buf_line >= cursor.line and setup.first_line < cursor.line and + while (setup.ensure_cursor_visible and + buf_line >= cursor.line and setup.first_line < cursor.line and setup.cursor_pos.line + setup.scroll_offset.line >= win_height) { auto remove_count = 1 + line_wrap_count(setup.first_line, indent); @@ -1660,7 +1661,8 @@ private: setup.cursor_pos.column += cursor_move; } - if (last.line >= setup.first_line and + if (setup.ensure_cursor_visible and + last.line >= setup.first_line and range.first.line <= setup.first_line + setup.line_count and range.first.line != last.line) { diff --git a/src/input_handler.cc b/src/input_handler.cc index 66d30391..a5c88a21 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -180,7 +180,7 @@ struct MouseHandler } case Key::Modifiers::Scroll: - scroll_window(context, static_cast<int32_t>(key.key), (bool)m_dragging); + scroll_window(context, static_cast<int32_t>(key.key), m_dragging ? OnHiddenCursor::MoveCursor : OnHiddenCursor::PreserveSelections); return true; default: return false; @@ -1852,7 +1852,7 @@ void hide_auto_info_ifn(const Context& context, bool hide) context.client().info_hide(); } -void scroll_window(Context& context, LineCount offset, bool mouse_dragging) +void scroll_window(Context& context, LineCount offset, OnHiddenCursor on_hidden_cursor) { Window& window = context.window(); Buffer& buffer = context.buffer(); @@ -1861,6 +1861,9 @@ void scroll_window(Context& context, LineCount offset, bool mouse_dragging) DisplayCoord win_pos = window.position(); DisplayCoord win_dim = window.dimensions(); + if (on_hidden_cursor == OnHiddenCursor::PreserveSelections) + context.ensure_cursor_visible = false; + if ((offset < 0 and win_pos.line == 0) or (offset > 0 and win_pos.line == line_count - 1)) return; @@ -1870,25 +1873,27 @@ void scroll_window(Context& context, LineCount offset, bool mouse_dragging) win_pos.line = clamp(win_pos.line + offset, 0_line, line_count-1); - ScopedSelectionEdition selection_edition{context}; - SelectionList& selections = context.selections(); - Selection& main_selection = selections.main(); - const BufferCoord anchor = main_selection.anchor(); - const BufferCoordAndTarget cursor = main_selection.cursor(); + window.set_position(win_pos); + if (on_hidden_cursor != OnHiddenCursor::PreserveSelections) + { + ScopedSelectionEdition selection_edition{context}; + SelectionList& selections = context.selections(); + Selection& main_selection = selections.main(); + const BufferCoord anchor = main_selection.anchor(); + const BufferCoordAndTarget cursor = main_selection.cursor(); - auto cursor_off = mouse_dragging ? win_pos.line - window.position().line : 0; + auto cursor_off = win_pos.line - window.position().line; - auto line = clamp(cursor.line + cursor_off, win_pos.line + scrolloff.line, - win_pos.line + win_dim.line - 1 - scrolloff.line); + auto line = clamp(cursor.line + cursor_off, win_pos.line + scrolloff.line, + win_pos.line + win_dim.line - 1 - scrolloff.line); - const ColumnCount tabstop = context.options()["tabstop"].get<int>(); - auto new_cursor = buffer.offset_coord(cursor, line - cursor.line, tabstop); - BufferCoord new_anchor = (mouse_dragging or new_cursor == cursor) ? anchor : new_cursor; + const ColumnCount tabstop = context.options()["tabstop"].get<int>(); + auto new_cursor = buffer.offset_coord(cursor, line - cursor.line, tabstop); - window.set_position(win_pos); - main_selection = { new_anchor, new_cursor }; + main_selection = {on_hidden_cursor == OnHiddenCursor::MoveCursor ? anchor : new_cursor, new_cursor}; - selections.sort_and_merge_overlapping(); + selections.sort_and_merge_overlapping(); + } } } diff --git a/src/input_handler.hh b/src/input_handler.hh index 00d2d53a..afcc24d4 100644 --- a/src/input_handler.hh +++ b/src/input_handler.hh @@ -204,7 +204,13 @@ void on_next_key_with_autoinfo(const Context& context, StringView mode_name, }); } -void scroll_window(Context& context, LineCount offset, bool mouse_dragging = false); +enum class OnHiddenCursor { + PreserveSelections, + MoveCursor, + MoveCursorAndAnchor, +}; + +void scroll_window(Context& context, LineCount offset, OnHiddenCursor on_hidden_cursor); } diff --git a/src/normal.cc b/src/normal.cc index 79a434ac..81caeb2d 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -368,6 +368,7 @@ void view_commands(Context& context, NormalParams params) const int count = params.count; on_next_key_with_autoinfo(context, "view", KeymapMode::View, [count](Key key, Context& context) { + context.ensure_cursor_visible = false; if (key == Key::Escape) return; @@ -400,10 +401,10 @@ void view_commands(Context& context, NormalParams params) window.scroll(-std::max<ColumnCount>(1, count)); break; case 'j': - scroll_window(context, std::max<LineCount>(1, count)); + scroll_window(context, std::max<LineCount>(1, count), OnHiddenCursor::PreserveSelections); break; case 'k': - scroll_window(context, -std::max<LineCount>(1, count)); + scroll_window(context, -std::max<LineCount>(1, count), OnHiddenCursor::PreserveSelections); break; case 'l': window.scroll( std::max<ColumnCount>(1, count)); @@ -1408,7 +1409,7 @@ void scroll(Context& context, NormalParams params) const int count = params.count ? params.count : 1; const LineCount offset = (window.dimensions().line - 2) / (half ? 2 : 1) * count; - scroll_window(context, offset * direction); + scroll_window(context, offset * direction, OnHiddenCursor::MoveCursorAndAnchor); } template<Direction direction> diff --git a/src/window.cc b/src/window.cc index 757723d2..b660bbdb 100644 --- a/src/window.cc +++ b/src/window.cc @@ -202,11 +202,14 @@ DisplaySetup Window::compute_display_setup(const Context& context) const const int tabstop = context.options()["tabstop"].get<int>(); const auto& cursor = context.selections().main().cursor(); - // Ensure cursor line is visible - if (cursor.line - offset.line < win_pos.line) - win_pos.line = std::max(0_line, cursor.line - offset.line); - if (cursor.line + offset.line >= win_pos.line + m_dimensions.line) - win_pos.line = std::min(buffer().line_count()-1, cursor.line + offset.line - m_dimensions.line + 1); + bool ensure_cursor_visible = context.ensure_cursor_visible; + if (ensure_cursor_visible) + { + if (cursor.line - offset.line < win_pos.line) + win_pos.line = std::max(0_line, cursor.line - offset.line); + if (cursor.line + offset.line >= win_pos.line + m_dimensions.line) + win_pos.line = std::min(buffer().line_count()-1, cursor.line + offset.line - m_dimensions.line + 1); + } DisplaySetup setup{ win_pos.line, @@ -215,13 +218,15 @@ DisplaySetup Window::compute_display_setup(const Context& context) const 0_col, {cursor.line - win_pos.line, get_column(buffer(), tabstop, cursor) - win_pos.column}, - offset + offset, + ensure_cursor_visible }; for (auto pass : { HighlightPass::Move, HighlightPass::Wrap }) m_builtin_highlighters.compute_display_setup({context, setup, pass, {}}, setup); check_display_setup(setup, *this); // now ensure the cursor column is visible + if (ensure_cursor_visible) { auto underflow = std::max(-setup.first_column, setup.cursor_pos.column - setup.scroll_offset.column); |
