summaryrefslogtreecommitdiff
path: root/src/normal.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2014-05-14 20:56:27 +0100
committerMaxime Coste <frrrwww@gmail.com>2014-05-14 20:56:49 +0100
commit4e280977a2fcd7ca423b5909b435b896b256cdaf (patch)
treecaf34647ab26f749f5c63f5af71f34302bc5e261 /src/normal.cc
parentc3f4ef9ba2e8ca58acc6cf56e552341a5af62f5d (diff)
Iterate in reversed order on selections when modifing buffer
This way, update only needs to be called once everything is done as we always modify after the next selection to be used.
Diffstat (limited to 'src/normal.cc')
-rw-r--r--src/normal.cc42
1 files changed, 25 insertions, 17 deletions
diff --git a/src/normal.cc b/src/normal.cc
index a8386b32..ff38c29d 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -23,13 +23,12 @@ namespace Kakoune
void erase(Buffer& buffer, SelectionList& selections)
{
- for (auto& sel : selections)
+ for (auto& sel : reversed(selections))
{
erase(buffer, sel);
- selections.update();
- avoid_eol(buffer, sel);
}
- selections.check_invariant();
+ selections.update();
+ selections.avoid_eol();
buffer.check_invariant();
}
@@ -66,20 +65,24 @@ BufferIterator prepare_insert(Buffer& buffer, const Selection& sel)
template<InsertMode mode>
void insert(Buffer& buffer, SelectionList& selections, const String& str)
{
- for (auto& sel : selections)
+ for (auto& sel : reversed(selections))
{
auto pos = prepare_insert<mode>(buffer, sel);
pos = buffer.insert(pos, str);
- selections.update();
- if (mode == InsertMode::Replace and pos != buffer.end())
+ if (mode == InsertMode::Replace)
{
+ if (pos == buffer.end())
+ --pos;
sel.anchor() = pos.coord();
sel.cursor() = str.empty() ?
pos.coord() : (pos + str.byte_count_to(str.char_length() - 1)).coord();
}
- avoid_eol(buffer, sel);
}
- selections.check_invariant();
+ if (mode == InsertMode::Replace)
+ selections.set_timestamp(buffer.timestamp());
+ else
+ selections.update();
+ selections.avoid_eol();
buffer.check_invariant();
}
@@ -90,20 +93,25 @@ void insert(Buffer& buffer, SelectionList& selections, memoryview<String> string
return;
for (size_t i = 0; i < selections.size(); ++i)
{
- auto& sel = selections[i];
+ size_t index = selections.size() - 1 - i;
+ auto& sel = selections[index];
auto pos = prepare_insert<mode>(buffer, sel);
- const String& str = strings[std::min(i, strings.size()-1)];
+ const String& str = strings[std::min(index, strings.size()-1)];
pos = buffer.insert(pos, str);
- selections.update();
- if (mode == InsertMode::Replace and pos != buffer.end())
+ if (mode == InsertMode::Replace)
{
+ if (pos == buffer.end())
+ --pos;
sel.anchor() = pos.coord();
sel.cursor() = (str.empty() ?
pos : pos + str.byte_count_to(str.char_length() - 1)).coord();
}
- avoid_eol(buffer, sel);
}
- selections.check_invariant();
+ if (mode == InsertMode::Replace)
+ selections.set_timestamp(buffer.timestamp());
+ else
+ selections.update();
+ selections.avoid_eol();
buffer.check_invariant();
}
@@ -1352,9 +1360,9 @@ void move(Context& context, int count)
: context.buffer().offset_coord(sel.cursor(), offset);
sel.anchor() = mode == SelectMode::Extend ? sel.anchor() : cursor;
- sel.cursor() = cursor;
- avoid_eol(context.buffer(), sel);
+ sel.cursor() = cursor;
}
+ selections.avoid_eol();
selections.sort_and_merge_overlapping();
}