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.
This commit is contained in:
parent
850f561096
commit
2fd42fe5fc
|
@ -1314,19 +1314,6 @@ private:
|
||||||
SelectionList& selections = context().selections();
|
SelectionList& selections = context().selections();
|
||||||
Buffer& buffer = context().buffer();
|
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)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case InsertMode::Insert:
|
case InsertMode::Insert:
|
||||||
|
@ -1351,22 +1338,41 @@ private:
|
||||||
sel.set({sel.max().line, buffer[sel.max().line].length() - 1});
|
sel.set({sel.max().line, buffer[sel.max().line].length() - 1});
|
||||||
break;
|
break;
|
||||||
case InsertMode::OpenLineBelow:
|
case InsertMode::OpenLineBelow:
|
||||||
for (auto& sel : selections)
|
{
|
||||||
sel.set({sel.max().line, buffer[sel.max().line].length() - 1});
|
Vector<Selection> new_sels;
|
||||||
duplicate_selections(selections, count);
|
count = count > 0 ? count : 1;
|
||||||
insert('\n');
|
LineCount inserted_count = 0;
|
||||||
break;
|
for (auto sel : selections)
|
||||||
case InsertMode::OpenLineAbove:
|
{
|
||||||
for (auto& sel : selections)
|
buffer.insert(sel.max().line + inserted_count + 1,
|
||||||
sel.set({sel.min().line});
|
String{'\n', CharCount{count}});
|
||||||
duplicate_selections(selections, count);
|
for (int i = 0; i < count; ++i)
|
||||||
// Do not use insert method here as we need to fixup selection
|
new_sels.push_back({sel.max().line + inserted_count + i + 1});
|
||||||
// before running the InsertChar hook.
|
inserted_count += count;
|
||||||
selections.insert("\n"_str, InsertMode::InsertCursor);
|
}
|
||||||
for (auto& sel : selections) // fixup selection positions
|
selections.set(std::move(new_sels),
|
||||||
sel.set({sel.cursor().line - 1});
|
selections.main_index() * count + count - 1);
|
||||||
context().hooks().run_hook("InsertChar", "\n", context());
|
context().hooks().run_hook("InsertChar", "\n", context());
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case InsertMode::OpenLineAbove:
|
||||||
|
{
|
||||||
|
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:
|
case InsertMode::InsertAtLineBegin:
|
||||||
for (auto& sel : selections)
|
for (auto& sel : selections)
|
||||||
{
|
{
|
||||||
|
|
1
test/normal/open-multiple-above/cmd
Normal file
1
test/normal/open-multiple-above/cmd
Normal file
|
@ -0,0 +1 @@
|
||||||
|
3Obar<esc>
|
1
test/normal/open-multiple-above/in
Normal file
1
test/normal/open-multiple-above/in
Normal file
|
@ -0,0 +1 @@
|
||||||
|
foo
|
4
test/normal/open-multiple-above/out
Normal file
4
test/normal/open-multiple-above/out
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
bar
|
||||||
|
bar
|
||||||
|
bar
|
||||||
|
foo
|
1
test/normal/open-multiple-below/cmd
Normal file
1
test/normal/open-multiple-below/cmd
Normal file
|
@ -0,0 +1 @@
|
||||||
|
3obar<esc>
|
1
test/normal/open-multiple-below/in
Normal file
1
test/normal/open-multiple-below/in
Normal file
|
@ -0,0 +1 @@
|
||||||
|
foo
|
4
test/normal/open-multiple-below/out
Normal file
4
test/normal/open-multiple-below/out
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
foo
|
||||||
|
bar
|
||||||
|
bar
|
||||||
|
bar
|
|
@ -0,0 +1 @@
|
||||||
|
x;:exec -draft o<ret>
|
|
@ -0,0 +1 @@
|
||||||
|
foo
|
|
@ -0,0 +1,2 @@
|
||||||
|
foo
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
1.4,1.4
|
Loading…
Reference in New Issue
Block a user