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();
|
||||
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');
|
||||
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.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:
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
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