Make o/O open multiple lines when a count is given

Fixes #873
This commit is contained in:
Maxime Coste 2016-10-24 19:41:05 +01:00
parent dbae81fa5c
commit dc18963875
5 changed files with 33 additions and 14 deletions

View File

@ -376,8 +376,10 @@ Changes
* `I`: enter insert mode at current selection begin line start
* `A`: enter insert mode at current selection end line end
* `o`: enter insert mode in a new line below current selection end
* `O`: enter insert mode in a new line above current selection begin
* `o`: enter insert mode in one (or given count) new lines below
current selection end
* `O`: enter insert mode in one (or given count) new lines above
current selection begin
* `y`: yank selections
* `p`: paste after current selection end

View File

@ -190,10 +190,12 @@ Changes
enter insert mode at current selection end line end
*o*::
enter insert mode in a new line below current selection end
enter insert mode in one (or given count) new lines below
current selection end
*O*::
enter insert mode in a new line above current selection begin
enter insert mode in a on (or given count) lines above
current selection begin
*y*::
yank selections

View File

@ -952,7 +952,7 @@ private:
class Insert : public InputMode
{
public:
Insert(InputHandler& input_handler, InsertMode mode)
Insert(InputHandler& input_handler, InsertMode mode, int count)
: InputMode(input_handler),
m_insert_mode(mode),
m_edition(context()),
@ -969,7 +969,7 @@ public:
last_insert().keys.clear();
last_insert().disable_hooks = context().hooks_disabled();
context().hooks().run_hook("InsertBegin", "", context());
prepare(m_insert_mode);
prepare(m_insert_mode, count);
}
~Insert()
@ -1177,11 +1177,24 @@ private:
context().hooks().run_hook("InsertChar", str, context());
}
void prepare(InsertMode mode)
void prepare(InsertMode mode, int count)
{
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:
@ -1208,15 +1221,17 @@ private:
case InsertMode::OpenLineBelow:
for (auto& sel : selections)
sel = BufferCoord{sel.max().line, buffer[sel.max().line].length() - 1};
duplicate_selections(selections, count);
insert('\n');
break;
case InsertMode::OpenLineAbove:
for (auto& sel : selections)
sel = BufferCoord{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) // fix case where we inserted at begining
for (auto& sel : selections) // fixup selection positions
sel = BufferCoord{sel.cursor().line - 1};
context().hooks().run_hook("InsertChar", "\n", context());
break;
@ -1291,9 +1306,9 @@ void InputHandler::reset_normal_mode()
current_mode().on_enabled();
}
void InputHandler::insert(InsertMode mode)
void InputHandler::insert(InsertMode mode, int count)
{
push_mode(new InputModes::Insert(*this, mode));
push_mode(new InputModes::Insert(*this, mode, count));
}
void InputHandler::repeat_last_insert()
@ -1307,7 +1322,7 @@ void InputHandler::repeat_last_insert()
m_last_insert.disable_hooks);
// context.last_insert will be refilled by the new Insert
// this is very inefficient.
push_mode(new InputModes::Insert(*this, m_last_insert.mode));
push_mode(new InputModes::Insert(*this, m_last_insert.mode, 1));
for (auto& key : keys)
current_mode().handle_key(key);
kak_assert(dynamic_cast<InputModes::Normal*>(&current_mode()) != nullptr);

View File

@ -53,7 +53,7 @@ public:
~InputHandler();
// switch to insert mode
void insert(InsertMode mode);
void insert(InsertMode mode, int count);
// repeat last insert mode key sequence
void repeat_last_insert();

View File

@ -93,9 +93,9 @@ void select_coord(Buffer& buffer, BufferCoord coord, SelectionList& selections)
}
template<InsertMode mode>
void enter_insert_mode(Context& context, NormalParams)
void enter_insert_mode(Context& context, NormalParams params)
{
context.input_handler().insert(mode);
context.input_handler().insert(mode, params.count);
}
void repeat_last_insert(Context& context, NormalParams)