diff --git a/src/window.cc b/src/window.cc index 4a889c00..09b7be7e 100644 --- a/src/window.cc +++ b/src/window.cc @@ -8,7 +8,8 @@ namespace Kakoune Window::Window(const std::shared_ptr buffer) : m_buffer(buffer), m_position(0, 0), - m_cursor(0, 0) + m_cursor(0, 0), + m_dimensions(0, 0) { } @@ -16,7 +17,7 @@ void Window::erase() { if (m_selections.empty()) { - BufferIterator cursor = m_buffer->iterator_at(m_cursor); + BufferIterator cursor = iterator_at(m_cursor); m_buffer->erase(cursor, cursor+1); } @@ -47,7 +48,7 @@ void Window::insert(const String& string) { if (m_selections.empty()) { - m_buffer->insert(m_buffer->iterator_at(m_cursor), string); + m_buffer->insert(iterator_at(m_cursor), string); move_cursor(measure_string(string)); } @@ -73,6 +74,28 @@ void Window::append(const String& string) } } +LineAndColumn Window::window_to_buffer(const LineAndColumn& window_pos) const +{ + return LineAndColumn(m_position.line + window_pos.line, + m_position.column + window_pos.column); +} + +LineAndColumn Window::buffer_to_window(const LineAndColumn& buffer_pos) const +{ + return LineAndColumn(buffer_pos.line - m_position.line, + buffer_pos.column - m_position.column); +} + +BufferIterator Window::iterator_at(const LineAndColumn& window_pos) const +{ + return m_buffer->iterator_at(window_to_buffer(window_pos)); +} + +LineAndColumn Window::line_and_column_at(const BufferIterator& iterator) const +{ + return buffer_to_window(m_buffer->line_and_column_at(iterator)); +} + void Window::empty_selections() { m_selections.clear(); @@ -83,7 +106,7 @@ void Window::select(bool append, const Selector& selector) if (not append or m_selections.empty()) { empty_selections(); - m_selections.push_back(selector(m_buffer->iterator_at(m_cursor))); + m_selections.push_back(selector(iterator_at(m_cursor))); } else { @@ -92,13 +115,19 @@ void Window::select(bool append, const Selector& selector) sel->end = selector(sel->end).end; } } - m_cursor = m_buffer->line_and_column_at(m_selections.back().end); + m_cursor = line_and_column_at(m_selections.back().end); + scroll_to_keep_cursor_visible_ifn(); } void Window::move_cursor(const LineAndColumn& offset) { - m_cursor = m_buffer->clamp(LineAndColumn(m_cursor.line + offset.line, - m_cursor.column + offset.column)); + LineAndColumn target_position = + window_to_buffer(LineAndColumn(m_cursor.line + offset.line, + m_cursor.column + offset.column)); + + m_cursor = buffer_to_window(m_buffer->clamp(target_position)); + + scroll_to_keep_cursor_visible_ifn(); } void Window::update_display_buffer() @@ -109,7 +138,7 @@ void Window::update_display_buffer() std::sort(sorted_selections.begin(), sorted_selections.end(), [](const Selection& lhs, const Selection& rhs) { return lhs.begin < rhs.begin; }); - BufferIterator current_position = m_buffer->begin(); + BufferIterator current_position = m_buffer->iterator_at(m_position); for (Selection& sel : sorted_selections) { @@ -136,4 +165,9 @@ void Window::update_display_buffer() } } +void Window::set_dimensions(const LineAndColumn& dimensions) +{ + m_dimensions = dimensions; +} + } diff --git a/src/window.hh b/src/window.hh index 6df0cd70..6fe86cef 100644 --- a/src/window.hh +++ b/src/window.hh @@ -35,18 +35,27 @@ public: const LineAndColumn& position() const { return m_position; } const LineAndColumn& cursor_position() const { return m_cursor; } + const std::shared_ptr& buffer() const { return m_buffer; } + LineAndColumn window_to_buffer(const LineAndColumn& window_pos) const; + LineAndColumn buffer_to_window(const LineAndColumn& buffer_pos) const; + + BufferIterator iterator_at(const LineAndColumn& window_pos) const; + LineAndColumn line_and_column_at(const BufferIterator& iterator) const; void move_cursor(const LineAndColumn& offset); const SelectionList& selections() const { return m_selections; } - void empty_selections(); - void select(bool append, const Selector& selector); + void empty_selections(); + void select(bool append, const Selector& selector); + + void set_dimensions(const LineAndColumn& dimensions); const DisplayBuffer& display_buffer() const { return m_display_buffer; } void update_display_buffer(); + private: std::shared_ptr m_buffer;