Make scrolling around work more correctly with wrapping
This commit is contained in:
parent
bd3ba77e96
commit
39826afde5
|
@ -39,7 +39,8 @@ struct DisplaySetup
|
|||
DisplayCoord window_pos;
|
||||
// Range of lines and columns from the buffer that will get displayed
|
||||
DisplayCoord window_range;
|
||||
|
||||
// Offset of line and columns that must remain visible around cursor
|
||||
DisplayCoord scroll_offset;
|
||||
// Position of the cursor in the window
|
||||
DisplayCoord cursor_pos;
|
||||
};
|
||||
|
@ -50,7 +51,7 @@ struct Highlighter
|
|||
virtual void highlight(const Context& context, HighlightPass pass, DisplayBuffer& display_buffer, BufferRange range) = 0;
|
||||
|
||||
virtual void compute_display_setup(const Context& context, HighlightPass pass,
|
||||
DisplayCoord scroll_offset, DisplaySetup& setup) {}
|
||||
DisplaySetup& setup) {}
|
||||
|
||||
virtual bool has_children() const { return false; }
|
||||
virtual Highlighter& get_child(StringView path) { throw runtime_error("this highlighter do not hold children"); }
|
||||
|
|
|
@ -13,10 +13,10 @@ void HighlighterGroup::highlight(const Context& context, HighlightPass pass,
|
|||
}
|
||||
|
||||
void HighlighterGroup::compute_display_setup(const Context& context, HighlightPass pass,
|
||||
DisplayCoord scroll_offset, DisplaySetup& setup)
|
||||
DisplaySetup& setup)
|
||||
{
|
||||
for (auto& hl : m_highlighters)
|
||||
hl.value->compute_display_setup(context, pass, scroll_offset, setup);
|
||||
hl.value->compute_display_setup(context, pass, setup);
|
||||
}
|
||||
|
||||
void HighlighterGroup::add_child(HighlighterAndId&& hl)
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
void highlight(const Context& context, HighlightPass pass, DisplayBuffer& display_buffer, BufferRange range) override;
|
||||
|
||||
void compute_display_setup(const Context& context, HighlightPass pass,
|
||||
DisplayCoord scroll_offset, DisplaySetup& setup) override;
|
||||
DisplaySetup& setup) override;
|
||||
|
||||
bool has_children() const override { return true; }
|
||||
void add_child(HighlighterAndId&& hl) override;
|
||||
|
|
|
@ -719,12 +719,12 @@ struct WrapHighlighter : Highlighter
|
|||
}
|
||||
|
||||
void compute_display_setup(const Context& context, HighlightPass pass,
|
||||
DisplayCoord scroll_offset, DisplaySetup& setup) override
|
||||
DisplaySetup& setup) override
|
||||
{
|
||||
if (pass != HighlightPass::Wrap)
|
||||
return;
|
||||
|
||||
ColumnCount column = context.window().display_setup().window_range.column;
|
||||
ColumnCount column = setup.window_range.column;
|
||||
if (column < 0)
|
||||
return;
|
||||
|
||||
|
@ -752,9 +752,11 @@ struct WrapHighlighter : Highlighter
|
|||
setup.cursor_pos.line += (int)(cursor_buffer_column / column);
|
||||
auto new_cursor_buffer_column = (cursor_buffer_column % column);
|
||||
|
||||
if (new_cursor_buffer_column < setup.window_pos.column + scroll_offset.column)
|
||||
setup.window_pos.column = new_cursor_buffer_column - scroll_offset.column;
|
||||
if (new_cursor_buffer_column < setup.window_pos.column + setup.scroll_offset.column)
|
||||
setup.window_pos.column = new_cursor_buffer_column - setup.scroll_offset.column;
|
||||
setup.cursor_pos.column = new_cursor_buffer_column - setup.window_pos.column;
|
||||
|
||||
kak_assert(setup.cursor_pos.column >= 0 and setup.cursor_pos.column < setup.window_range.column);
|
||||
}
|
||||
|
||||
const auto wrap_count = line_wrap_count(buf_line);
|
||||
|
@ -775,8 +777,10 @@ struct WrapHighlighter : Highlighter
|
|||
setup.window_range.line += removed_lines - 1;
|
||||
}
|
||||
|
||||
if (setup.window_range.line < buf_line - setup.window_pos.line + 1)
|
||||
if (setup.window_range.line <= buf_line - setup.window_pos.line)
|
||||
setup.window_range.line = buf_line - setup.window_pos.line + 1;
|
||||
|
||||
kak_assert(setup.cursor_pos.line >= 0 and setup.cursor_pos.line < win_height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -941,18 +945,13 @@ struct LineNumbersHighlighter : Highlighter
|
|||
}
|
||||
|
||||
void compute_display_setup(const Context& context, HighlightPass pass,
|
||||
DisplayCoord scroll_offset, DisplaySetup& setup) override
|
||||
DisplaySetup& setup) override
|
||||
{
|
||||
if (pass != HighlightPass::Move)
|
||||
return;
|
||||
|
||||
ColumnCount width = compute_digit_count(context) + m_separator.column_length();
|
||||
setup.window_range.column -= width;
|
||||
|
||||
auto cursor_overflow = setup.cursor_pos.column + scroll_offset.column -
|
||||
setup.window_range.column + 1;
|
||||
if (cursor_overflow > 0)
|
||||
setup.window_pos.column += cursor_overflow;
|
||||
}
|
||||
|
||||
static HighlighterAndId create(HighlighterParameters params)
|
||||
|
@ -1171,7 +1170,7 @@ struct FlagLinesHighlighter : Highlighter
|
|||
}
|
||||
|
||||
void compute_display_setup(const Context& context, HighlightPass pass,
|
||||
DisplayCoord scroll_offset, DisplaySetup& setup) override
|
||||
DisplaySetup& setup) override
|
||||
{
|
||||
if (pass != HighlightPass::Move)
|
||||
return;
|
||||
|
@ -1185,11 +1184,6 @@ struct FlagLinesHighlighter : Highlighter
|
|||
width = std::max(parse_display_line(std::get<1>(line)).length(), width);
|
||||
|
||||
setup.window_range.column -= width;
|
||||
|
||||
auto cursor_overflow = setup.cursor_pos.column + scroll_offset.column -
|
||||
setup.window_range.column + 1;
|
||||
if (cursor_overflow > 0)
|
||||
setup.window_pos.column += cursor_overflow;
|
||||
}
|
||||
|
||||
static HighlighterAndId create(HighlighterParameters params)
|
||||
|
|
|
@ -122,8 +122,7 @@ const DisplayBuffer& Window::update_display_buffer(const Context& context)
|
|||
return m_display_buffer;
|
||||
|
||||
kak_assert(&buffer() == &context.buffer());
|
||||
m_display_setup = compute_display_setup(context);
|
||||
m_position = m_display_setup.window_pos;
|
||||
compute_display_setup(context);
|
||||
|
||||
for (LineCount line = 0; line < m_display_setup.window_range.line; ++line)
|
||||
{
|
||||
|
@ -174,18 +173,7 @@ void Window::set_dimensions(DisplayCoord dimensions)
|
|||
}
|
||||
}
|
||||
|
||||
template<typename Unit>
|
||||
static Unit adapt_view_pos(Unit pos, Unit offset,
|
||||
Unit view_pos, Unit view_size)
|
||||
{
|
||||
if (pos - offset < view_pos)
|
||||
return std::max(Unit{0}, pos - offset);
|
||||
else if (pos + offset >= view_pos + view_size)
|
||||
return std::max(Unit{0}, pos + offset - view_size + 1);
|
||||
return view_pos;
|
||||
}
|
||||
|
||||
DisplaySetup Window::compute_display_setup(const Context& context)
|
||||
void Window::compute_display_setup(const Context& context)
|
||||
{
|
||||
DisplayCoord offset = options()["scrolloff"].get<DisplayCoord>();
|
||||
offset.line = std::min(offset.line, (m_dimensions.line + 1) / 2);
|
||||
|
@ -193,25 +181,42 @@ DisplaySetup Window::compute_display_setup(const Context& context)
|
|||
|
||||
const auto& cursor = context.selections().main().cursor();
|
||||
|
||||
m_position.line = adapt_view_pos(cursor.line, offset.line,
|
||||
m_position.line, m_dimensions.line);
|
||||
// Ensure cursor line is visible
|
||||
if (cursor.line - offset.line < m_position.line)
|
||||
m_position.line = cursor.line - offset.line;
|
||||
if (cursor.line + offset.line >= m_position.line + m_dimensions.line)
|
||||
m_position.line = cursor.line + offset.line - m_dimensions.line + 1;
|
||||
|
||||
const int tabstop = context.options()["tabstop"].get<int>();
|
||||
auto cursor_col = get_column(buffer(), tabstop, cursor);
|
||||
m_position.column = adapt_view_pos(cursor_col, offset.column,
|
||||
m_position.column, m_dimensions.column);
|
||||
|
||||
DisplaySetup setup{
|
||||
m_display_setup = DisplaySetup{
|
||||
m_position,
|
||||
m_dimensions,
|
||||
offset,
|
||||
DisplayCoord{cursor.line - m_position.line, cursor_col - m_position.column}
|
||||
};
|
||||
for (auto pass : { HighlightPass::Move, HighlightPass::Wrap })
|
||||
m_highlighters.compute_display_setup(context, pass, offset, setup);
|
||||
m_highlighters.compute_display_setup(context, pass, m_display_setup);
|
||||
for (auto pass : { HighlightPass::Move, HighlightPass::Wrap })
|
||||
m_builtin_highlighters.compute_display_setup(context, pass, offset, setup);
|
||||
m_builtin_highlighters.compute_display_setup(context, pass, m_display_setup);
|
||||
|
||||
return setup;
|
||||
// now ensure the cursor column is visible
|
||||
{
|
||||
auto underflow = m_display_setup.cursor_pos.column - m_display_setup.scroll_offset.column;
|
||||
if (underflow < 0)
|
||||
{
|
||||
m_display_setup.window_pos.column += underflow;
|
||||
m_display_setup.cursor_pos.column -= underflow;
|
||||
}
|
||||
auto overflow = m_display_setup.cursor_pos.column + m_display_setup.scroll_offset.column - m_display_setup.window_range.column + 1;
|
||||
if (overflow > 0)
|
||||
{
|
||||
m_display_setup.window_pos.column += overflow;
|
||||
m_display_setup.cursor_pos.column -= overflow;
|
||||
}
|
||||
}
|
||||
m_position = m_display_setup.window_pos;
|
||||
}
|
||||
|
||||
namespace
|
||||
|
|
|
@ -53,7 +53,7 @@ private:
|
|||
Window(const Window&) = delete;
|
||||
|
||||
void on_option_changed(const Option& option) override;
|
||||
DisplaySetup compute_display_setup(const Context& context);
|
||||
void compute_display_setup(const Context& context);
|
||||
|
||||
void run_hook_in_own_context(StringView hook_name, StringView param,
|
||||
String client_name = "");
|
||||
|
@ -63,8 +63,8 @@ private:
|
|||
|
||||
DisplayCoord m_position;
|
||||
DisplayCoord m_dimensions;
|
||||
DisplayBuffer m_display_buffer;
|
||||
DisplaySetup m_display_setup;
|
||||
DisplayBuffer m_display_buffer;
|
||||
|
||||
HighlighterGroup m_highlighters;
|
||||
HighlighterGroup m_builtin_highlighters;
|
||||
|
|
Loading…
Reference in New Issue
Block a user