diff --git a/src/buffer.cc b/src/buffer.cc index 31784e60..ae98755b 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -612,7 +612,7 @@ BufferCoord Buffer::advance(BufferCoord coord, ByteCount count) const BufferCoord Buffer::char_advance(BufferCoord coord, CharCount count) const { - return utf8::advance(iterator_at(coord), end(), count); + return utf8::advance(iterator_at(coord), end(), count).coord(); } BufferCoord Buffer::next(BufferCoord coord) const diff --git a/src/buffer.hh b/src/buffer.hh index b2d5c793..7aacb841 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -59,9 +59,6 @@ public: BufferIterator operator++ (int); BufferIterator operator-- (int); - BufferIterator& operator=(const BufferCoord& coord); - operator const BufferCoord&() const { return m_coord; } - const BufferCoord& coord() const { return m_coord; } private: @@ -127,6 +124,9 @@ public: BufferCoord char_next(BufferCoord coord) const; BufferCoord char_prev(BufferCoord coord) const; + BufferCoord back_coord() const { return { line_count() - 1, m_lines.back().length() - 1 }; } + BufferCoord end_coord() const { return { line_count() - 1, m_lines.back().length() }; } + bool is_valid(const BufferCoord& c) const; bool is_end(const BufferCoord& c) const; diff --git a/src/buffer_iterator.inl.hh b/src/buffer_iterator.inl.hh index 362ed82a..4e5540e7 100644 --- a/src/buffer_iterator.inl.hh +++ b/src/buffer_iterator.inl.hh @@ -109,12 +109,5 @@ inline BufferIterator BufferIterator::operator--(int) return save; } -inline BufferIterator& BufferIterator::operator=(const BufferCoord& coord) -{ - kak_assert(m_buffer and m_buffer->is_valid(coord)); - m_coord = coord; - return *this; -} - } #endif // buffer_iterator_inl_h_INCLUDED diff --git a/src/commands.cc b/src/commands.cc index a2eb08d3..b6c9a1c6 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -60,7 +60,7 @@ Buffer* open_fifo(const String& name , const String& filename, Context& context) constexpr size_t buffer_size = 1024 * 16; char data[buffer_size]; ssize_t count = read(watcher.fd(), data, buffer_size); - buffer->insert(buffer->end()-1, + buffer->insert(buffer->back_coord(), count > 0 ? String(data, data+count) : "*** kak: fifo closed ***\n"); ClientManager::instance().redraw_clients(); diff --git a/src/debug.cc b/src/debug.cc index b0d2c4a7..af935bb7 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -23,7 +23,7 @@ void write_debug(const String& str) { Buffer& debug_buffer = get_or_create_debug_buffer(); Editor editor(debug_buffer); - editor.select(debug_buffer.end()-1); + editor.select(debug_buffer.back_coord()); editor.insert(str + "\n"); } diff --git a/src/editor.cc b/src/editor.cc index d3fbbe8b..7e5c0389 100644 --- a/src/editor.cc +++ b/src/editor.cc @@ -16,7 +16,7 @@ Editor::Editor(Buffer& buffer) m_edition_level(0), m_selections(buffer) { - m_selections.push_back(Selection(buffer.begin(), buffer.begin())); + m_selections.push_back(Selection({}, {})); m_main_sel = 0; } @@ -370,18 +370,14 @@ public: auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin, [](const BufferCoord& c, const Selection& sel) { return c < sel.min(); }); - m_ranges.emplace(it, registry().iterator_at(begin), - utf8::previous(registry().iterator_at(end))); + m_ranges.emplace(it, begin, buffer.char_prev(end)); } void on_erase(const Buffer& buffer, const BufferCoord& begin, const BufferCoord& end) { m_ranges.update_erase(buffer, begin, end); - BufferIterator pos{registry(), begin}; - if (pos >= buffer.end()) - pos = utf8::previous(buffer.end()); - - auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin, + auto pos = std::min(begin, buffer.back_coord()); + auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), pos, [](const BufferCoord& c, const Selection& sel) { return c < sel.min(); }); m_ranges.emplace(it, pos, pos); @@ -488,7 +484,7 @@ IncrementalInserter::IncrementalInserter(Editor& editor, InsertMode mode) case InsertMode::OpenLineAbove: case InsertMode::InsertAtLineBegin: - first = buffer.iterator_at(sel.min().line); + first = sel.min().line; if (mode == InsertMode::OpenLineAbove) first = buffer.char_prev(first); else @@ -497,7 +493,7 @@ IncrementalInserter::IncrementalInserter(Editor& editor, InsertMode mode) while (*first_non_blank == ' ' or *first_non_blank == '\t') ++first_non_blank; if (*first_non_blank != '\n') - first = first_non_blank; + first = first_non_blank.coord(); } last = first; break; diff --git a/src/filters.cc b/src/filters.cc index 27447951..61d98bca 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -16,7 +16,7 @@ void preserve_indent(Buffer& buffer, Selection& selection, String& content) first_non_white != buffer.end()) ++first_non_white; - content += buffer.string(line_begin, first_non_white); + content += buffer.string(line_begin, first_non_white.coord()); } } @@ -31,7 +31,7 @@ void cleanup_whitespaces(Buffer& buffer, Selection& selection, String& content) --whitespace_start; ++whitespace_start; if (whitespace_start != position) - buffer.erase(whitespace_start, position); + buffer.erase(whitespace_start.coord(), position.coord()); } } @@ -84,7 +84,7 @@ struct RegexFilter auto& first = selection.first(); auto& last = selection.last(); - buffer.insert(position, suffix); + buffer.insert(last, suffix); if (first == last) first = buffer.advance(first, -suffix.length()); last = buffer.advance(last, -suffix.length()); diff --git a/src/input_handler.cc b/src/input_handler.cc index 956ca959..6dc74390 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -511,7 +511,7 @@ static BufferCompletion complete_word(const Buffer& buffer, if (not is_word(*begin)) ++begin; - String ex = R"(\<\Q)" + buffer.string(begin, end) + R"(\E\w+\>)"; + String ex = R"(\<\Q)" + String{begin, end} + R"(\E\w+\>)"; Regex re(ex.begin(), ex.end()); using RegexIt = boost::regex_iterator; @@ -521,7 +521,7 @@ static BufferCompletion complete_word(const Buffer& buffer, auto& match = (*it)[0]; if (match.first <= pos and pos < match.second) continue; - matches.insert(buffer.string(match.first, match.second)); + matches.insert(String{match.first, match.second}); } if (other_buffers) { @@ -532,7 +532,7 @@ static BufferCompletion complete_word(const Buffer& buffer, for (RegexIt it(buf->begin(), buf->end(), re), re_end; it != re_end; ++it) { auto& match = (*it)[0]; - matches.insert(buf->string(match.first, match.second)); + matches.insert(String{match.first, match.second}); } } } @@ -541,7 +541,7 @@ static BufferCompletion complete_word(const Buffer& buffer, make_move_iterator(matches.end()), inserter(result, result.begin())); std::sort(result.begin(), result.end()); - return { begin, end, std::move(result), buffer.timestamp() }; + return { begin.coord(), end.coord(), std::move(result), buffer.timestamp() }; } static BufferCompletion complete_opt(const Buffer& buffer, @@ -561,12 +561,11 @@ static BufferCompletion complete_opt(const Buffer& buffer, BufferCoord coord{ str_to_int(match[1].str()) - 1, str_to_int(match[2].str()) - 1 }; if (not buffer.is_valid(coord)) return {}; - auto beg = buffer.iterator_at(coord); - auto end = beg; + auto end = coord; if (match[3].matched) { ByteCount len = str_to_int(match[3].str()); - end = beg + len; + end = buffer.advance(coord, len); } size_t timestamp = (size_t)str_to_int(match[4].str()); @@ -576,8 +575,8 @@ static BufferCompletion complete_opt(const Buffer& buffer, if (timestamp == buffer.timestamp() and cursor_pos.line == coord.line and cursor_pos.column <= coord.column and - buffer.distance(beg, cursor_pos) < longest_completion) - return { beg, end, { opt.begin() + 1, opt.end() }, timestamp }; + buffer.distance(coord, cursor_pos) < longest_completion) + return { coord, end, { opt.begin() + 1, opt.end() }, timestamp }; } return {}; } @@ -614,8 +613,8 @@ public: if (offset >= beg_offset and offset + end_offset < buffer_len and std::equal(pos - beg_offset, pos, begin)) { - auto beg = pos - beg_offset; - buffer.erase(beg, pos + end_offset); + auto beg = buffer.advance(sel.last(), -beg_offset); + buffer.erase(beg, buffer.advance(sel.last(), end_offset)); buffer.insert(beg, candidate); } } diff --git a/src/normal.cc b/src/normal.cc index fc60a0f3..31f3b582 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -96,7 +96,7 @@ void goto_commands(Context& context) } case 'e': context.push_jump(); - editor.select(editor.buffer().end()-1, mode); + editor.select(editor.buffer().back_coord(), mode); break; case 't': if (context.has_window()) @@ -610,7 +610,7 @@ void scroll(Context& context) auto cursor_pos = utf8::advance(buffer.iterator_at(position.line), buffer.iterator_at(position.line+1), position.column); - window.select(cursor_pos); + window.select(cursor_pos.coord()); window.set_position(position); } diff --git a/src/selectors.cc b/src/selectors.cc index 59891df9..06eb6842 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -69,7 +69,7 @@ void skip_while_reverse(Iterator& it, const BeginIterator& begin, T condition) Range utf8_range(const Utf8Iterator& first, const Utf8Iterator& last) { - return {first.underlying_iterator(), last.underlying_iterator()}; + return {first.underlying_iterator().coord(), last.underlying_iterator().coord()}; } } @@ -448,8 +448,8 @@ Selection select_whole_sentence(const Buffer& buffer, const Selection& selection --last; } } - return (flags & ObjectFlags::ToEnd) ? Selection{first, last} - : Selection{last, first}; + return (flags & ObjectFlags::ToEnd) ? Selection{first.coord(), last.coord()} + : Selection{last.coord(), first.coord()}; } Selection select_whole_paragraph(const Buffer& buffer, const Selection& selection, ObjectFlags flags) @@ -490,8 +490,8 @@ Selection select_whole_paragraph(const Buffer& buffer, const Selection& selectio } --last; } - return (flags & ObjectFlags::ToEnd) ? Selection{first, last} - : Selection{last, first}; + return (flags & ObjectFlags::ToEnd) ? Selection{first.coord(), last.coord()} + : Selection{last.coord(), first.coord()}; } Selection select_whole_lines(const Buffer& buffer, const Selection& selection) @@ -511,7 +511,7 @@ Selection select_whole_lines(const Buffer& buffer, const Selection& selection) if (to_line_end == buffer.end()) --to_line_end; - return Selection(first, last); + return Selection(first.coord(), last.coord()); } Selection trim_partial_lines(const Buffer& buffer, const Selection& selection) @@ -527,12 +527,12 @@ Selection trim_partial_lines(const Buffer& buffer, const Selection& selection) while (*(to_line_end+1) != '\n' and to_line_end != to_line_start) --to_line_end; - return Selection(first, last); + return Selection(first.coord(), last.coord()); } Selection select_whole_buffer(const Buffer& buffer, const Selection&) { - return Selection(buffer.begin(), utf8::previous(buffer.end())); + return Selection({0,0}, buffer.back_coord()); } using MatchResults = boost::match_results; @@ -591,7 +591,7 @@ Selection select_next_match(const Buffer& buffer, const Selection& selection, co end = utf8::previous(end); if (not forward) std::swap(begin, end); - return Selection{begin, end, std::move(captures)}; + return Selection{begin.coord(), end.coord(), std::move(captures)}; } template Selection select_next_match(const Buffer&, const Selection&, const Regex&); template Selection select_next_match(const Buffer&, const Selection&, const Regex&); @@ -615,7 +615,7 @@ SelectionList select_all_matches(const Buffer& buffer, const Selection& selectio for (auto& match : *re_it) captures.push_back(String(match.first, match.second)); - result.push_back(Selection(begin, begin == end ? end : utf8::previous(end), + result.push_back(Selection(begin.coord(), (begin == end ? end : utf8::previous(end)).coord(), std::move(captures))); } return result; @@ -634,10 +634,10 @@ SelectionList split_selection(const Buffer& buffer, const Selection& selection, { BufferIterator end = (*re_it)[0].first; - result.push_back(Selection(begin, (begin == end) ? end : utf8::previous(end))); + result.push_back(Selection(begin.coord(), (begin == end) ? end.coord() : utf8::previous(end).coord())); begin = (*re_it)[0].second; } - result.push_back(Selection(begin, selection.max())); + result.push_back(Selection(begin.coord(), selection.max())); return result; } diff --git a/src/unit_tests.cc b/src/unit_tests.cc index 90c707c6..52f11ea1 100644 --- a/src/unit_tests.cc +++ b/src/unit_tests.cc @@ -13,41 +13,39 @@ void test_buffer() Buffer buffer("test", Buffer::Flags::None, { "allo ?\n", "mais que fais la police\n", " hein ?\n", " youpi\n" }); kak_assert(buffer.line_count() == 4); - BufferIterator i = buffer.begin(); - kak_assert(*i == 'a'); - i += 6; - kak_assert(i.coord() == BufferCoord{0 COMMA 6}); - i += 1; - kak_assert(i.coord() == BufferCoord{1 COMMA 0}); - --i; - kak_assert(i.coord() == BufferCoord{0 COMMA 6}); - ++i; - kak_assert(i.coord() == BufferCoord{1 COMMA 0}); - buffer.insert(i, "tchou kanaky\n"); + BufferCoord pos = {0,0}; + kak_assert(buffer.byte_at(pos) == 'a'); + pos = buffer.advance(pos, 6); + kak_assert(pos == BufferCoord{0 COMMA 6}); + pos = buffer.next(pos); + kak_assert(pos == BufferCoord{1 COMMA 0}); + pos = buffer.prev(pos); + kak_assert(pos == BufferCoord{0 COMMA 6}); + pos = buffer.advance(pos, 1); + kak_assert(pos == BufferCoord{1 COMMA 0}); + buffer.insert(pos, "tchou kanaky\n"); kak_assert(buffer.line_count() == 5); - BufferIterator begin = buffer.iterator_at({ 4, 1 }); - BufferIterator end = buffer.iterator_at({ 4, 5 }) + 1; - String str = buffer.string(begin, end); + String str = buffer.string({ 4, 1 }, buffer.next({ 4, 5 })); kak_assert(str == "youpi"); // check insert at end behaviour: auto add end of line if necessary - begin = buffer.end() - 1; - buffer.insert(buffer.end(), "tchou"); - kak_assert(buffer.string(begin+1, buffer.end()) == "tchou\n"); + pos = buffer.back_coord(); + buffer.insert(pos, "tchou"); + kak_assert(buffer.string(pos, buffer.end_coord()) == "tchou\n"); - begin = buffer.end() - 1; - buffer.insert(buffer.end(), "kanaky\n"); - kak_assert(buffer.string(begin+1, buffer.end()) == "kanaky\n"); + pos = buffer.back_coord(); + buffer.insert(buffer.end_coord(), "kanaky\n"); + kak_assert(buffer.string(buffer.next(pos), buffer.end_coord()) == "kanaky\n"); buffer.commit_undo_group(); - buffer.erase(begin+1, buffer.end()); - buffer.insert(buffer.end(), "mutch\n"); + buffer.erase(buffer.next(pos), buffer.end_coord()); + buffer.insert(buffer.end_coord(), "mutch\n"); buffer.commit_undo_group(); buffer.undo(); - kak_assert(buffer.string(buffer.end() - 7, buffer.end()) == "kanaky\n"); + kak_assert(buffer.string(buffer.advance(buffer.end_coord(), -7), buffer.end_coord()) == "kanaky\n"); buffer.redo(); - kak_assert(buffer.string(buffer.end() - 6, buffer.end()) == "mutch\n"); + kak_assert(buffer.string(buffer.advance(buffer.end_coord(), -6), buffer.end_coord()) == "mutch\n"); } void test_editor() @@ -68,7 +66,7 @@ void test_editor() } editor.undo(); - Selection sel{ buffer.iterator_at(2_line), buffer.end()-1 }; + Selection sel{ 2_line, buffer.back_coord() }; editor.select(sel, SelectMode::Replace); editor.insert("",InsertMode::Replace); kak_assert(not buffer.is_end(editor.main_selection().first())); @@ -79,13 +77,13 @@ void test_incremental_inserter() Buffer buffer("test", Buffer::Flags::None, { "test\n", "\n", "youpi\n", "matin\n" }); Editor editor(buffer); - editor.select(buffer.begin()); + editor.select({0,0}); { IncrementalInserter inserter(editor, InsertMode::OpenLineAbove); kak_assert(editor.is_editing()); kak_assert(editor.selections().size() == 1); - kak_assert(editor.selections().front().first() == buffer.begin()); - kak_assert(editor.selections().front().last() == buffer.begin()); + kak_assert(editor.selections().front().first() == BufferCoord{0 COMMA 0}); + kak_assert(editor.selections().front().last() == BufferCoord{0 COMMA 0}); kak_assert(*buffer.begin() == L'\n'); } kak_assert(not editor.is_editing());