diff --git a/src/buffer.cc b/src/buffer.cc index b9ef6a96..bca676a6 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -604,11 +604,6 @@ BufferCoord Buffer::advance(BufferCoord coord, ByteCount count) const return { LineCount{ (int)(it - m_lines.begin()) }, off - it->start }; } -BufferCoord Buffer::char_advance(BufferCoord coord, CharCount count) const -{ - return utf8::advance(iterator_at(coord), end(), count).coord(); -} - BufferCoord Buffer::next(BufferCoord coord) const { if (coord.column < m_lines[coord.line].length() - 1) @@ -675,11 +670,6 @@ ByteCount Buffer::distance(const BufferCoord& begin, const BufferCoord& end) con return offset(end) - offset(begin); } -CharCount Buffer::char_distance(const BufferCoord& begin, const BufferCoord& end) const -{ - return utf8::distance(iterator_at(begin), iterator_at(end)); -} - ByteCount Buffer::offset(const BufferCoord& c) const { if (c.line == line_count()) diff --git a/src/buffer.hh b/src/buffer.hh index 4775f44b..21ca016e 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -119,8 +119,6 @@ public: BufferCoord prev(BufferCoord coord) const; Codepoint char_at(const BufferCoord& c) const; - CharCount char_distance(const BufferCoord& begin, const BufferCoord& end) const; - BufferCoord char_advance(BufferCoord coord, CharCount count) const; BufferCoord char_next(BufferCoord coord) const; BufferCoord char_prev(BufferCoord coord) const; diff --git a/src/client_manager.cc b/src/client_manager.cc index c4dbda6f..6c3b49ce 100644 --- a/src/client_manager.cc +++ b/src/client_manager.cc @@ -187,7 +187,7 @@ static DisplayLine generate_status_line(Client& client) { auto& context = client.context(); auto pos = context.editor().main_selection().last(); - auto col = context.buffer().char_distance({pos.line, 0}, pos); + auto col = context.buffer()[pos.line].char_count_to(pos.column); std::ostringstream oss; oss << context.buffer().display_name() diff --git a/src/editor.cc b/src/editor.cc index fbd2ae58..ae100871 100644 --- a/src/editor.cc +++ b/src/editor.cc @@ -97,7 +97,7 @@ void Editor::insert(const String& str, InsertMode mode) { sel.first() = pos; sel.last() = str.empty() ? - pos : m_buffer->char_advance(pos, str.char_length() - 1); + pos : m_buffer->advance(pos, str.byte_count_to(str.char_length() - 1)); } avoid_eol(*m_buffer, sel); } @@ -120,7 +120,7 @@ void Editor::insert(const memoryview& strings, InsertMode mode) { sel.first() = pos; sel.last() = str.empty() ? - pos : m_buffer->char_advance(pos, str.char_length() - 1); + pos : m_buffer->advance(pos, str.byte_count_to(str.char_length() - 1)); } avoid_eol(*m_buffer, sel); } @@ -185,8 +185,10 @@ void Editor::move_selections(CharCount offset, SelectMode mode) for (auto& sel : m_selections) { auto last = sel.last(); - last = clamp(m_buffer->char_advance(last, offset), - last.line, m_buffer->char_prev(last.line+1)); + auto& line = buffer()[last.line]; + auto character = std::max(0_char, std::min(line.char_count_to(last.column) + offset, + line.char_length() - 2)); + last.column = line.byte_count_to(character); sel.first() = mode == SelectMode::Extend ? sel.first() : last; sel.last() = last; avoid_eol(*m_buffer, sel); @@ -199,12 +201,14 @@ void Editor::move_selections(LineCount offset, SelectMode mode) kak_assert(mode == SelectMode::Replace or mode == SelectMode::Extend); for (auto& sel : m_selections) { - CharCount column = m_buffer->char_distance(sel.last().line, sel.last()); + auto character = (*m_buffer)[sel.last().line].char_count_to(sel.last().column); auto line = clamp(sel.last().line + offset, 0_line, m_buffer->line_count()-1); - column = std::min(column, (*m_buffer)[line].char_length()-1); - BufferCoord last = m_buffer->char_advance(line, column); - sel.first() = mode == SelectMode::Extend ? sel.first() : last; - sel.last() = last; + auto& content = (*m_buffer)[line]; + + character = std::max(0_char, std::min(character, content.char_length() - 2)); + BufferCoord pos{line, content.byte_count_to(character)}; + sel.first() = mode == SelectMode::Extend ? sel.first() : pos; + sel.last() = pos; avoid_eol(*m_buffer, sel); } sort_and_merge_overlapping(m_selections, m_main_sel); diff --git a/src/normal.cc b/src/normal.cc index 31f3b582..652a193e 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -707,7 +707,7 @@ void align(Context& context) auto& selections = context.editor().selections(); auto& buffer = context.buffer(); auto get_column = [&buffer](const BufferCoord& coord) - { return buffer.char_distance({coord.line, 0}, coord); }; + { return buffer[coord.line].char_count_to(coord.column); }; CharCount max_col = 0; for (auto& sel : selections) diff --git a/src/window.cc b/src/window.cc index 24cffed6..41cfe0dc 100644 --- a/src/window.cc +++ b/src/window.cc @@ -69,9 +69,9 @@ void Window::update_display_buffer() LineCount buffer_line = m_position.line + line; if (buffer_line >= buffer().line_count()) break; - BufferCoord limit{buffer_line+1, 0}; - auto begin = std::min(buffer().char_advance(buffer_line, m_position.column), limit); - auto end = std::min(buffer().char_advance(begin, m_dimensions.column), limit); + const String& content = buffer()[buffer_line]; + BufferCoord begin{buffer_line, content.byte_count_to(m_position.column)}; + BufferCoord end{buffer_line, content.byte_count_to(m_position.column + m_dimensions.column)}; lines.push_back(DisplayLine(buffer_line)); lines.back().push_back(DisplayAtom(AtomContent(buffer(), begin, end))); @@ -112,6 +112,7 @@ void Window::scroll_to_keep_cursor_visible_ifn() { const auto& first = main_selection().first(); const auto& last = main_selection().last(); + const String& content = buffer()[last.line]; const LineCount offset = std::min(options()["scrolloff"].get(), (m_dimensions.line - 1) / 2); @@ -145,14 +146,14 @@ void Window::scroll_to_keep_cursor_visible_ifn() { column += atom.content.length(); - CharCount first_col = first.line == last.line ? - buffer().char_distance(last.line, first) : 0_char; + auto first_col = (first.line == last.line) ? content.char_count_to(first.column) : 0_char; + auto last_col = content.char_count_to(last.column); + if (first_col < m_position.column) m_position.column = first_col; else if (column >= m_position.column + m_dimensions.column) m_position.column = column - (m_dimensions.column - 1); - CharCount last_col = buffer().char_distance(last.line, last); if (last_col < m_position.column) m_position.column = last_col; else if (column >= m_position.column + m_dimensions.column)