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 | |
| 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.
| -rw-r--r-- | src/input_handler.cc | 56 | ||||
| -rw-r--r-- | test/normal/open-multiple-above/cmd | 1 | ||||
| -rw-r--r-- | test/normal/open-multiple-above/in | 1 | ||||
| -rw-r--r-- | test/normal/open-multiple-above/out | 4 | ||||
| -rw-r--r-- | test/normal/open-multiple-below/cmd | 1 | ||||
| -rw-r--r-- | test/normal/open-multiple-below/in | 1 | ||||
| -rw-r--r-- | test/normal/open-multiple-below/out | 4 | ||||
| -rw-r--r-- | test/regression/0-open-below-should-not-move-cursor-on-eol/cmd | 1 | ||||
| -rw-r--r-- | test/regression/0-open-below-should-not-move-cursor-on-eol/in | 1 | ||||
| -rw-r--r-- | test/regression/0-open-below-should-not-move-cursor-on-eol/out | 2 | ||||
| -rw-r--r-- | test/regression/0-open-below-should-not-move-cursor-on-eol/state | 1 |
11 files changed, 48 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) { diff --git a/test/normal/open-multiple-above/cmd b/test/normal/open-multiple-above/cmd new file mode 100644 index 00000000..b07421f6 --- /dev/null +++ b/test/normal/open-multiple-above/cmd @@ -0,0 +1 @@ +3Obar<esc> diff --git a/test/normal/open-multiple-above/in b/test/normal/open-multiple-above/in new file mode 100644 index 00000000..257cc564 --- /dev/null +++ b/test/normal/open-multiple-above/in @@ -0,0 +1 @@ +foo diff --git a/test/normal/open-multiple-above/out b/test/normal/open-multiple-above/out new file mode 100644 index 00000000..de926059 --- /dev/null +++ b/test/normal/open-multiple-above/out @@ -0,0 +1,4 @@ +bar +bar +bar +foo diff --git a/test/normal/open-multiple-below/cmd b/test/normal/open-multiple-below/cmd new file mode 100644 index 00000000..e4be15d6 --- /dev/null +++ b/test/normal/open-multiple-below/cmd @@ -0,0 +1 @@ +3obar<esc> diff --git a/test/normal/open-multiple-below/in b/test/normal/open-multiple-below/in new file mode 100644 index 00000000..257cc564 --- /dev/null +++ b/test/normal/open-multiple-below/in @@ -0,0 +1 @@ +foo diff --git a/test/normal/open-multiple-below/out b/test/normal/open-multiple-below/out new file mode 100644 index 00000000..1458786c --- /dev/null +++ b/test/normal/open-multiple-below/out @@ -0,0 +1,4 @@ +foo +bar +bar +bar diff --git a/test/regression/0-open-below-should-not-move-cursor-on-eol/cmd b/test/regression/0-open-below-should-not-move-cursor-on-eol/cmd new file mode 100644 index 00000000..f180a6b2 --- /dev/null +++ b/test/regression/0-open-below-should-not-move-cursor-on-eol/cmd @@ -0,0 +1 @@ +x;:exec -draft o<ret> diff --git a/test/regression/0-open-below-should-not-move-cursor-on-eol/in b/test/regression/0-open-below-should-not-move-cursor-on-eol/in new file mode 100644 index 00000000..257cc564 --- /dev/null +++ b/test/regression/0-open-below-should-not-move-cursor-on-eol/in @@ -0,0 +1 @@ +foo diff --git a/test/regression/0-open-below-should-not-move-cursor-on-eol/out b/test/regression/0-open-below-should-not-move-cursor-on-eol/out new file mode 100644 index 00000000..75d7bfb8 --- /dev/null +++ b/test/regression/0-open-below-should-not-move-cursor-on-eol/out @@ -0,0 +1,2 @@ +foo + diff --git a/test/regression/0-open-below-should-not-move-cursor-on-eol/state b/test/regression/0-open-below-should-not-move-cursor-on-eol/state new file mode 100644 index 00000000..d022d3dd --- /dev/null +++ b/test/regression/0-open-below-should-not-move-cursor-on-eol/state @@ -0,0 +1 @@ +1.4,1.4 |
