diff options
| author | Maxime Coste <mawww@kakoune.org> | 2018-03-04 10:28:35 +1100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2018-03-04 10:32:21 +1100 |
| commit | 2fd42fe5fcd7af52ce2306ea78a416b4ed0d06ef (patch) | |
| tree | 99619e5f6cc7932b16b68fadd9beca0eb17e472f /src | |
| parent | 850f5610966c46eae86a97524dfe0ea9b9996af6 (diff) | |
Insert: Do not move end of line on open line (o/O)
Change the logic of open line commands so that if a selection lies
on the end of line character of the line from which we open a new
line, that selection does not move.
If we have two clients, A and B, with B's cursor on the eol character
of line L, and A hits `o` while on line L, B's cursor should stay
on the same (logical) line. Previous behaviour would make B's cursor
jump on the newly inserted line.
Diffstat (limited to 'src')
| -rw-r--r-- | src/input_handler.cc | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/src/input_handler.cc b/src/input_handler.cc index 6fa41d6f..ffa923b1 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -1314,19 +1314,6 @@ private: SelectionList& selections = context().selections(); Buffer& buffer = context().buffer(); - auto duplicate_selections = [](SelectionList& sels, int count) { - count = count > 0 ? count : 1; - Vector<Selection> new_sels; - new_sels.reserve(count * sels.size()); - for (auto& sel : sels) - for (int i = 0; i < count; ++i) - new_sels.push_back(sel); - - size_t new_main = sels.main_index() * count + count - 1; - sels = SelectionList{sels.buffer(), std::move(new_sels)}; - sels.set_main_index(new_main); - }; - switch (mode) { case InsertMode::Insert: @@ -1351,22 +1338,41 @@ private: sel.set({sel.max().line, buffer[sel.max().line].length() - 1}); break; case InsertMode::OpenLineBelow: - for (auto& sel : selections) - sel.set({sel.max().line, buffer[sel.max().line].length() - 1}); - duplicate_selections(selections, count); - insert('\n'); + { + Vector<Selection> new_sels; + count = count > 0 ? count : 1; + LineCount inserted_count = 0; + for (auto sel : selections) + { + buffer.insert(sel.max().line + inserted_count + 1, + String{'\n', CharCount{count}}); + for (int i = 0; i < count; ++i) + new_sels.push_back({sel.max().line + inserted_count + i + 1}); + inserted_count += count; + } + selections.set(std::move(new_sels), + selections.main_index() * count + count - 1); + context().hooks().run_hook("InsertChar", "\n", context()); break; + } case InsertMode::OpenLineAbove: - for (auto& sel : selections) - sel.set({sel.min().line}); - duplicate_selections(selections, count); - // Do not use insert method here as we need to fixup selection - // before running the InsertChar hook. - selections.insert("\n"_str, InsertMode::InsertCursor); - for (auto& sel : selections) // fixup selection positions - sel.set({sel.cursor().line - 1}); + { + Vector<Selection> new_sels; + count = count > 0 ? count : 1; + LineCount inserted_count = 0; + for (auto sel : selections) + { + buffer.insert(sel.min().line + inserted_count, + String{'\n', CharCount{count}}); + for (int i = 0; i < count; ++i) + new_sels.push_back({sel.max().line + inserted_count + i}); + inserted_count += count; + } + selections.set(std::move(new_sels), + selections.main_index() * count + count - 1); context().hooks().run_hook("InsertChar", "\n", context()); break; + } case InsertMode::InsertAtLineBegin: for (auto& sel : selections) { |
