diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2013-06-06 19:39:53 +0200 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2013-06-06 19:44:08 +0200 |
| commit | 2a74b0e9e23e927121908ef534393ffd1b80e8ca (patch) | |
| tree | 5a7f99c72ff80ed959eb4264f58aaf451d39f7f0 /src | |
| parent | cf454ef904a93185c3e5318bc7b5c1d3d08fea39 (diff) | |
Buffer: insert and erase go back to taking iterators, and return iterators
Diffstat (limited to 'src')
| -rw-r--r-- | src/buffer.cc | 40 | ||||
| -rw-r--r-- | src/buffer.hh | 10 | ||||
| -rw-r--r-- | src/commands.cc | 5 | ||||
| -rw-r--r-- | src/editor.cc | 87 | ||||
| -rw-r--r-- | src/filters.cc | 4 | ||||
| -rw-r--r-- | src/input_handler.cc | 5 | ||||
| -rw-r--r-- | src/normal.cc | 8 | ||||
| -rw-r--r-- | src/selection.hh | 5 | ||||
| -rw-r--r-- | src/unit_tests.cc | 34 |
9 files changed, 95 insertions, 103 deletions
diff --git a/src/buffer.cc b/src/buffer.cc index 1b95fe9c..f46049de 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -412,12 +412,12 @@ void Buffer::check_invariant() const #endif } -void Buffer::do_insert(const BufferCoord& pos, const String& content) +BufferCoord Buffer::do_insert(const BufferCoord& pos, const String& content) { kak_assert(is_valid(pos)); if (content.empty()) - return; + return pos; ++m_timestamp; ByteCount offset = this->offset(pos); @@ -489,9 +489,10 @@ void Buffer::do_insert(const BufferCoord& pos, const String& content) for (auto listener : m_change_listeners) listener->on_insert(*this, begin, end); + return begin; } -void Buffer::do_erase(const BufferCoord& begin, const BufferCoord& end) +BufferCoord Buffer::do_erase(const BufferCoord& begin, const BufferCoord& end) { kak_assert(is_valid(begin)); kak_assert(is_valid(end)); @@ -501,19 +502,25 @@ void Buffer::do_erase(const BufferCoord& begin, const BufferCoord& end) String suffix = m_lines[end.line].content.substr(end.column); Line new_line = { m_lines[begin.line].start, prefix + suffix }; + BufferCoord next; if (new_line.length() != 0) { m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line); m_lines[begin.line] = std::move(new_line); + next = begin; } else + { m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line + 1); + next = is_end(begin) ? end_coord() : BufferCoord{begin.line, 0}; + } for (LineCount i = begin.line+1; i < line_count(); ++i) m_lines[i].start -= length; for (auto listener : m_change_listeners) listener->on_erase(*this, begin, end); + return next; } void Buffer::apply_modification(const Modification& modification) @@ -547,32 +554,33 @@ void Buffer::apply_modification(const Modification& modification) } } -void Buffer::insert(BufferCoord pos, String content) +BufferIterator Buffer::insert(const BufferIterator& pos, String content) { - kak_assert(is_valid(pos)); + kak_assert(is_valid(pos.coord())); if (content.empty()) - return; + return pos; - if (is_end(pos) and content.back() != '\n') + if (pos == end() and content.back() != '\n') content += '\n'; if (not (m_flags & Flags::NoUndo)) - m_current_undo_group.emplace_back(Modification::Insert, pos, content); - do_insert(pos, content); + m_current_undo_group.emplace_back(Modification::Insert, pos.coord(), content); + return {*this, do_insert(pos.coord(), content)}; } -void Buffer::erase(BufferCoord begin, BufferCoord end) +BufferIterator Buffer::erase(BufferIterator begin, BufferIterator end) { - if (is_end(end) and (begin.column != 0 or begin == BufferCoord{0,0})) - end = { line_count() - 1, m_lines.back().length() - 1}; + // do not erase last \n except if we erase from the start of a line + if (end == this->end() and (begin.coord().column != 0 or begin == this->begin())) + --end; if (begin == end) - return; + return begin; if (not (m_flags & Flags::NoUndo)) - m_current_undo_group.emplace_back(Modification::Erase, begin, - string(begin, end)); - do_erase(begin, end); + m_current_undo_group.emplace_back(Modification::Erase, begin.coord(), + string(begin.coord(), end.coord())); + return {*this, do_erase(begin.coord(), end.coord())}; } bool Buffer::is_modified() const diff --git a/src/buffer.hh b/src/buffer.hh index 26fa584a..61b9179e 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -100,8 +100,8 @@ public: bool set_name(String name); - void insert(BufferCoord pos, String content); - void erase(BufferCoord begin, BufferCoord end); + BufferIterator insert(const BufferIterator& pos, String content); + BufferIterator erase(BufferIterator begin, BufferIterator end); size_t timestamp() const { return m_timestamp; } @@ -160,8 +160,6 @@ public: void check_invariant() const; private: - friend class BufferIterator; - struct Line { ByteCount start; @@ -179,8 +177,8 @@ private: }; LineList m_lines; - void do_insert(const BufferCoord& pos, const String& content); - void do_erase(const BufferCoord& begin, const BufferCoord& end); + BufferCoord do_insert(const BufferCoord& pos, const String& content); + BufferCoord do_erase(const BufferCoord& begin, const BufferCoord& end); String m_name; Flags m_flags; diff --git a/src/commands.cc b/src/commands.cc index b46b1b63..4e62a65f 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -60,9 +60,8 @@ 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->back_coord(), - count > 0 ? String(data, data+count) - : "*** kak: fifo closed ***\n"); + buffer->insert(buffer->end()-1, count > 0 ? String(data, data+count) + : "*** kak: fifo closed ***\n"); ClientManager::instance().redraw_clients(); if (count <= 0) { diff --git a/src/editor.cc b/src/editor.cc index 81abd0e4..5d2e4a81 100644 --- a/src/editor.cc +++ b/src/editor.cc @@ -44,43 +44,31 @@ void Editor::erase() } } -static BufferCoord prepare_insert(Buffer& buffer, const Selection& sel, - InsertMode mode) +static BufferIterator prepare_insert(Buffer& buffer, const Selection& sel, + InsertMode mode) { switch (mode) { case InsertMode::Insert: - return sel.min(); + return buffer.iterator_at(sel.min()); case InsertMode::Replace: - { - BufferCoord pos = sel.min(); - Kakoune::erase(buffer, sel); - return pos; - } + return Kakoune::erase(buffer, sel); case InsertMode::Append: { // special case for end of lines, append to current line instead - auto& pos = std::max(sel.first(), sel.last()); - if (pos.column == buffer[pos.line].length() - 1) - return pos; - else - return buffer.char_next(pos); + auto pos = buffer.iterator_at(sel.max()); + return *pos == '\n' ? pos : utf8::next(pos); } case InsertMode::InsertAtLineBegin: - return sel.min().line; + return buffer.iterator_at(sel.min().line); case InsertMode::AppendAtLineEnd: - return {sel.max().line, buffer[sel.max().line].length() - 1}; + return buffer.iterator_at({sel.max().line, buffer[sel.max().line].length() - 1}); case InsertMode::InsertAtNextLineBegin: - return sel.max().line+1; + return buffer.iterator_at(sel.max().line+1); case InsertMode::OpenLineBelow: + return buffer.insert(buffer.iterator_at(sel.max().line + 1), "\n"); case InsertMode::OpenLineAbove: - { - auto line = mode == InsertMode::OpenLineAbove ? - sel.min().line : sel.max().line + 1; - buffer.insert(line, "\n"); - return line; - } - + return buffer.insert(buffer.iterator_at(sel.min().line), "\n"); } kak_assert(false); return {}; @@ -92,13 +80,13 @@ void Editor::insert(const String& str, InsertMode mode) for (auto& sel : m_selections) { - BufferCoord pos = prepare_insert(*m_buffer, sel, mode); - m_buffer->insert(pos, str); - if (mode == InsertMode::Replace and not m_buffer->is_end(pos)) + auto pos = prepare_insert(*m_buffer, sel, mode); + pos = m_buffer->insert(pos, str); + if (mode == InsertMode::Replace and pos != m_buffer->end()) { - sel.first() = pos; + sel.first() = pos.coord(); sel.last() = str.empty() ? - pos : m_buffer->advance(pos, str.byte_count_to(str.char_length() - 1)); + pos.coord() : (pos + str.byte_count_to(str.char_length() - 1)).coord(); } avoid_eol(*m_buffer, sel); } @@ -114,14 +102,14 @@ void Editor::insert(const memoryview<String>& strings, InsertMode mode) for (size_t i = 0; i < selections().size(); ++i) { auto& sel = m_selections[i]; - BufferCoord pos = prepare_insert(*m_buffer, sel, mode); + auto pos = prepare_insert(*m_buffer, sel, mode); const String& str = strings[std::min(i, strings.size()-1)]; - m_buffer->insert(pos, str); - if (mode == InsertMode::Replace and not m_buffer->is_end(pos)) + pos = m_buffer->insert(pos, str); + if (mode == InsertMode::Replace and pos != m_buffer->end()) { - sel.first() = pos; - sel.last() = str.empty() ? - pos : m_buffer->advance(pos, str.byte_count_to(str.char_length() - 1)); + sel.first() = pos.coord(); + sel.last() = (str.empty() ? + pos : pos + str.byte_count_to(str.char_length() - 1)).coord(); } avoid_eol(*m_buffer, sel); } @@ -462,27 +450,24 @@ IncrementalInserter::IncrementalInserter(Editor& editor, InsertMode mode) BufferCoord first, last; switch (mode) { - case InsertMode::Insert: first = sel.max(); last = sel.min(); break; + case InsertMode::Insert: + first = sel.max(); + last = sel.min(); + break; case InsertMode::Replace: - { - Kakoune::erase(buffer, sel); - first = last = sel.min(); + first = last = Kakoune::erase(buffer, sel).coord(); break; - } case InsertMode::Append: - { first = sel.min(); - last = sel.max(); + last = sel.max(); // special case for end of lines, append to current line instead if (last.column != buffer[last.line].length() - 1) last = buffer.char_next(last); break; - } case InsertMode::OpenLineBelow: case InsertMode::AppendAtLineEnd: - first = BufferCoord{sel.max().line, buffer[sel.max().line].length() - 1}; - last = first; + first = last = BufferCoord{sel.max().line, buffer[sel.max().line].length() - 1}; break; case InsertMode::OpenLineAbove: @@ -540,30 +525,32 @@ IncrementalInserter::~IncrementalInserter() void IncrementalInserter::insert(String content) { - Buffer& buffer = m_editor.buffer(); + auto& buffer = m_editor.buffer(); for (auto& sel : m_editor.m_selections) { m_editor.filters()(buffer, sel, content); - buffer.insert(sel.last(), content); + buffer.insert(buffer.iterator_at(sel.last()), content); } } void IncrementalInserter::insert(const memoryview<String>& strings) { + auto& buffer = m_editor.buffer(); for (size_t i = 0; i < m_editor.m_selections.size(); ++i) { size_t index = std::min(i, strings.size()-1); - m_editor.buffer().insert(m_editor.m_selections[i].last(), - strings[index]); + buffer.insert(buffer.iterator_at(m_editor.m_selections[i].last()), + strings[index]); } } void IncrementalInserter::erase() { + auto& buffer = m_editor.buffer(); for (auto& sel : m_editor.m_selections) { - BufferCoord pos = sel.last(); - m_editor.buffer().erase(m_editor.buffer().char_prev(pos), pos); + auto pos = buffer.iterator_at(sel.last()); + buffer.erase(pos-1, pos); } } diff --git a/src/filters.cc b/src/filters.cc index 61d98bca..02be6767 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -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.coord(), position.coord()); + buffer.erase(whitespace_start, position); } } @@ -81,10 +81,10 @@ struct RegexFilter { String suffix(it+1, content.end()); content = String(content.begin(), it-1); + buffer.insert(position, suffix); auto& first = selection.first(); auto& last = selection.last(); - 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 6dc74390..283b86ea 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -613,9 +613,8 @@ public: if (offset >= beg_offset and offset + end_offset < buffer_len and std::equal(pos - beg_offset, pos, begin)) { - auto beg = buffer.advance(sel.last(), -beg_offset); - buffer.erase(beg, buffer.advance(sel.last(), end_offset)); - buffer.insert(beg, candidate); + pos = buffer.erase(pos - beg_offset, pos + end_offset); + buffer.insert(pos, candidate); } } diff --git a/src/normal.cc b/src/normal.cc index a0fba585..fb5306e7 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -474,9 +474,9 @@ void join_select_spaces(Context& context) SelectionList res = select_all_matches(buffer, sel, Regex{"(\n\\h*)+"}); // remove last end of line if selected kak_assert(std::is_sorted(res.begin(), res.end(), - [](const Selection& lhs, const Selection& rhs) - { return lhs.min() < rhs.min(); })); - if (not res.empty() and buffer.is_end(buffer.char_next(res.back().max()))) + [](const Selection& lhs, const Selection& rhs) + { return lhs.min() < rhs.min(); })); + if (not res.empty() and res.back().max() == buffer.back_coord()) res.pop_back(); return res; }); @@ -713,7 +713,7 @@ void align(Context& context) for (auto& sel : selections) { CharCount padding = max_col - get_column(sel.last()); - buffer.insert(sel.last(), String{ ' ', padding }); + buffer.insert(buffer.iterator_at(sel.last()), String{ ' ', padding }); } } diff --git a/src/selection.hh b/src/selection.hh index c7e5e2c3..fb5f20dd 100644 --- a/src/selection.hh +++ b/src/selection.hh @@ -45,9 +45,10 @@ inline String content(const Buffer& buffer, const Range& range) return buffer.string(range.min(), buffer.char_next(range.max())); } -inline void erase(Buffer& buffer, const Range& range) +inline BufferIterator erase(Buffer& buffer, const Range& range) { - return buffer.erase(range.min(), buffer.char_next(range.max())); + return buffer.erase(buffer.iterator_at(range.min()), + utf8::next(buffer.iterator_at(range.max()))); } using CaptureList = std::vector<String>; diff --git a/src/unit_tests.cc b/src/unit_tests.cc index 52f11ea1..00f54eb3 100644 --- a/src/unit_tests.cc +++ b/src/unit_tests.cc @@ -13,16 +13,16 @@ 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); - 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}); + BufferIterator pos = buffer.begin(); + kak_assert(*pos == 'a'); + pos += 6; + kak_assert(pos.coord() == BufferCoord{0 COMMA 6}); + ++pos; + kak_assert(pos.coord() == BufferCoord{1 COMMA 0}); + --pos; + kak_assert(pos.coord() == BufferCoord{0 COMMA 6}); + pos += 1; + kak_assert(pos.coord() == BufferCoord{1 COMMA 0}); buffer.insert(pos, "tchou kanaky\n"); kak_assert(buffer.line_count() == 5); @@ -30,17 +30,17 @@ void test_buffer() kak_assert(str == "youpi"); // check insert at end behaviour: auto add end of line if necessary - pos = buffer.back_coord(); + pos = buffer.end()-1; buffer.insert(pos, "tchou"); - kak_assert(buffer.string(pos, buffer.end_coord()) == "tchou\n"); + kak_assert(buffer.string(pos.coord(), buffer.end_coord()) == "tchou\n"); - pos = buffer.back_coord(); - buffer.insert(buffer.end_coord(), "kanaky\n"); - kak_assert(buffer.string(buffer.next(pos), buffer.end_coord()) == "kanaky\n"); + pos = buffer.end()-1; + buffer.insert(buffer.end(), "kanaky\n"); + kak_assert(buffer.string((pos+1).coord(), buffer.end_coord()) == "kanaky\n"); buffer.commit_undo_group(); - buffer.erase(buffer.next(pos), buffer.end_coord()); - buffer.insert(buffer.end_coord(), "mutch\n"); + buffer.erase(pos+1, buffer.end()); + buffer.insert(buffer.end(), "mutch\n"); buffer.commit_undo_group(); buffer.undo(); kak_assert(buffer.string(buffer.advance(buffer.end_coord(), -7), buffer.end_coord()) == "kanaky\n"); |
