summaryrefslogtreecommitdiff
path: root/src/window.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2023-08-12 13:40:55 +1000
committerMaxime Coste <mawww@kakoune.org>2023-08-16 21:02:42 +1000
commit1e38045d702ec6eb2425016d9b02636270ab1b1e (patch)
tree0298a655119e5d87d9650d5aadc0f1fc76ffcbfd /src/window.cc
parent6942a4c0c9428a9e2ddb65de3969d2dcb5c5eb2f (diff)
Only make cursor visible after buffer or selection change
Kakoune now does not touch cursors when scrolling. It checks if either the buffer or selections has been modified since last redraw. Fixes #4124 Fixes #2844
Diffstat (limited to 'src/window.cc')
-rw-r--r--src/window.cc57
1 files changed, 30 insertions, 27 deletions
diff --git a/src/window.cc b/src/window.cc
index 2a0469cf..b5d1db40 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -85,37 +85,34 @@ static uint32_t compute_faces_hash(const FaceRegistry& faces)
Window::Setup Window::build_setup(const Context& context) const
{
- Vector<BufferRange, MemoryDomain::Display> selections;
- for (auto& sel : context.selections())
- selections.push_back({sel.cursor(), sel.anchor()});
-
- return { m_position, m_dimensions,
- context.buffer().timestamp(),
- compute_faces_hash(context.faces()),
- context.selections().main_index(),
- std::move(selections) };
+ return {m_position, m_dimensions,
+ context.buffer().timestamp(),
+ compute_faces_hash(context.faces()),
+ context.selections().main_index(),
+ context.selections() | gather<Vector<BasicSelection, MemoryDomain::Display>>()};
}
bool Window::needs_redraw(const Context& context) const
{
auto& selections = context.selections();
-
- if (m_position != m_last_setup.position or
+ return m_position != m_last_setup.position or
m_dimensions != m_last_setup.dimensions or
context.buffer().timestamp() != m_last_setup.timestamp or
selections.main_index() != m_last_setup.main_selection or
selections.size() != m_last_setup.selections.size() or
- compute_faces_hash(context.faces()) != m_last_setup.faces_hash)
- return true;
-
- for (int i = 0; i < selections.size(); ++i)
- {
- if (selections[i].cursor() != m_last_setup.selections[i].begin or
- selections[i].anchor() != m_last_setup.selections[i].end)
- return true;
- }
+ compute_faces_hash(context.faces()) != m_last_setup.faces_hash or
+ not std::equal(selections.begin(), selections.end(),
+ m_last_setup.selections.begin(), m_last_setup.selections.end());
+}
- return false;
+bool Window::should_make_cursor_visible(const Context& context) const
+{
+ auto& selections = context.selections();
+ return context.buffer().timestamp() != m_last_setup.timestamp or
+ selections.main_index() != m_last_setup.main_selection or
+ selections.size() != m_last_setup.selections.size() or
+ not std::equal(selections.begin(), selections.end(),
+ m_last_setup.selections.begin(), m_last_setup.selections.end());
}
const DisplayBuffer& Window::update_display_buffer(const Context& context)
@@ -215,11 +212,15 @@ 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 = should_make_cursor_visible(context);
+
+ 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,
@@ -228,13 +229,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);