Handle inserting in Client::InsertMode
This commit is contained in:
parent
d4446d1525
commit
bf42d77469
|
@ -309,9 +309,89 @@ private:
|
||||||
KeyCallback m_callback;
|
KeyCallback m_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
Client::Client()
|
class Client::InsertMode : public Client::Mode
|
||||||
: m_mode(new NormalMode(*this))
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
InsertMode(Client& client, Editor& editor, IncrementalInserter::Mode mode)
|
||||||
|
: Client::Mode(client), m_inserter(editor, mode)
|
||||||
|
{
|
||||||
|
m_client.m_last_insert.first = mode;
|
||||||
|
m_client.m_last_insert.second.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_key(const Key& key, Context& context) override
|
||||||
|
{
|
||||||
|
m_client.m_last_insert.second.push_back(key);
|
||||||
|
if (m_insert_reg)
|
||||||
|
{
|
||||||
|
if (key.modifiers == Key::Modifiers::None)
|
||||||
|
m_inserter.insert(RegisterManager::instance()[key.key].values(context));
|
||||||
|
m_insert_reg = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (key.modifiers)
|
||||||
|
{
|
||||||
|
case Key::Modifiers::None:
|
||||||
|
switch (key.key)
|
||||||
|
{
|
||||||
|
case 27:
|
||||||
|
m_client.reset_normal_mode();
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
m_inserter.insert(String() + key.key);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Key::Modifiers::Control:
|
||||||
|
switch (key.key)
|
||||||
|
{
|
||||||
|
case 'r':
|
||||||
|
m_insert_reg = true;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
m_inserter.insert(String() + '\n');
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
m_inserter.insert(String() + '\t');
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
m_inserter.move_cursors({0, -1});
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
m_inserter.move_cursors({0, 1});
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
m_inserter.erase();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool m_insert_reg = false;
|
||||||
|
IncrementalInserter m_inserter;
|
||||||
|
};
|
||||||
|
|
||||||
|
Client::Client()
|
||||||
|
: m_mode(new NormalMode(*this)),
|
||||||
|
m_last_insert(IncrementalInserter::Mode::Insert, {})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::insert(Editor& editor, IncrementalInserter::Mode mode)
|
||||||
|
{
|
||||||
|
m_mode.reset(new InsertMode(*this, editor, mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::repeat_last_insert(Editor& editor, Context& context)
|
||||||
|
{
|
||||||
|
std::vector<Key> keys;
|
||||||
|
swap(keys, m_last_insert.second);
|
||||||
|
// m_last_insert will be refilled by the new InsertMode
|
||||||
|
// this is very inefficient.
|
||||||
|
m_mode.reset(new InsertMode(*this, editor, m_last_insert.first));
|
||||||
|
for (auto& key : keys)
|
||||||
|
m_mode->on_key(key, context);
|
||||||
|
assert(dynamic_cast<NormalMode*>(m_mode.get()) != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::prompt(const String& prompt, Completer completer,
|
void Client::prompt(const String& prompt, Completer completer,
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "completion.hh"
|
#include "completion.hh"
|
||||||
#include "utils.hh"
|
#include "utils.hh"
|
||||||
#include "string.hh"
|
#include "string.hh"
|
||||||
|
#include "editor.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
@ -36,6 +37,9 @@ public:
|
||||||
virtual void print_status(const String& status,
|
virtual void print_status(const String& status,
|
||||||
CharCount cursor_pos = -1) = 0;
|
CharCount cursor_pos = -1) = 0;
|
||||||
|
|
||||||
|
void insert(Editor& editor, IncrementalInserter::Mode mode);
|
||||||
|
void repeat_last_insert(Editor& editor, Context& context);
|
||||||
|
|
||||||
void prompt(const String& prompt, Completer completer,
|
void prompt(const String& prompt, Completer completer,
|
||||||
PromptCallback callback);
|
PromptCallback callback);
|
||||||
|
|
||||||
|
@ -45,14 +49,15 @@ public:
|
||||||
void on_next_key(KeyCallback callback);
|
void on_next_key(KeyCallback callback);
|
||||||
|
|
||||||
void handle_next_input(Context& context);
|
void handle_next_input(Context& context);
|
||||||
virtual Key get_key() = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void show_menu(const memoryview<String>& choices) = 0;
|
virtual void show_menu(const memoryview<String>& choices) = 0;
|
||||||
virtual void menu_ctrl(MenuCommand command) = 0;
|
virtual void menu_ctrl(MenuCommand command) = 0;
|
||||||
|
virtual Key get_key() = 0;
|
||||||
|
|
||||||
void reset_normal_mode();
|
void reset_normal_mode();
|
||||||
|
std::pair<IncrementalInserter::Mode, std::vector<Key>> m_last_insert;
|
||||||
|
|
||||||
class Mode
|
class Mode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -71,6 +76,7 @@ private:
|
||||||
class MenuMode;
|
class MenuMode;
|
||||||
class PromptMode;
|
class PromptMode;
|
||||||
class NextKeyMode;
|
class NextKeyMode;
|
||||||
|
class InsertMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct prompt_aborted {};
|
struct prompt_aborted {};
|
||||||
|
|
80
src/main.cc
80
src/main.cc
|
@ -32,91 +32,15 @@ namespace Kakoune
|
||||||
|
|
||||||
bool quit_requested = false;
|
bool quit_requested = false;
|
||||||
|
|
||||||
struct InsertSequence
|
|
||||||
{
|
|
||||||
IncrementalInserter::Mode mode;
|
|
||||||
std::vector<Key> keys;
|
|
||||||
|
|
||||||
InsertSequence() : mode(IncrementalInserter::Mode::Insert) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
InsertSequence last_insert_sequence;
|
|
||||||
|
|
||||||
template<typename GetKey, typename Redraw>
|
|
||||||
void insert_sequence(IncrementalInserter& inserter,
|
|
||||||
const Context& context,
|
|
||||||
GetKey get_key, Redraw redraw)
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
Key key = get_key();
|
|
||||||
switch (key.modifiers)
|
|
||||||
{
|
|
||||||
case Key::Modifiers::None:
|
|
||||||
switch (key.key)
|
|
||||||
{
|
|
||||||
case 27:
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
inserter.insert(String() + key.key);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Key::Modifiers::Control:
|
|
||||||
switch (key.key)
|
|
||||||
{
|
|
||||||
case 'r':
|
|
||||||
{
|
|
||||||
Key next_key = get_key();
|
|
||||||
if (next_key.modifiers == Key::Modifiers::None)
|
|
||||||
inserter.insert(RegisterManager::instance()[next_key.key].values(context));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'm':
|
|
||||||
inserter.insert(String() + '\n');
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
inserter.insert(String() + '\t');
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
inserter.move_cursors({0, -1});
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
inserter.move_cursors({0, 1});
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
inserter.erase();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<IncrementalInserter::Mode mode>
|
template<IncrementalInserter::Mode mode>
|
||||||
void do_insert(Context& context)
|
void do_insert(Context& context)
|
||||||
{
|
{
|
||||||
last_insert_sequence.mode = mode;
|
context.client().insert(context.editor(), mode);
|
||||||
last_insert_sequence.keys.clear();
|
|
||||||
IncrementalInserter inserter(context.editor(), mode);
|
|
||||||
context.draw_ifn();
|
|
||||||
insert_sequence(inserter, context,
|
|
||||||
[&]() { Key key = context.client().get_key();
|
|
||||||
last_insert_sequence.keys.push_back(key);
|
|
||||||
return key; },
|
|
||||||
[&]() { context.draw_ifn(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_repeat_insert(Context& context)
|
void do_repeat_insert(Context& context)
|
||||||
{
|
{
|
||||||
if (last_insert_sequence.keys.empty())
|
context.client().repeat_last_insert(context.editor(), context);
|
||||||
return;
|
|
||||||
|
|
||||||
IncrementalInserter inserter(context.editor(), last_insert_sequence.mode);
|
|
||||||
size_t index = 0;
|
|
||||||
insert_sequence(inserter, context,
|
|
||||||
[&]() { return last_insert_sequence.keys[index++]; },
|
|
||||||
[](){});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool append>
|
template<bool append>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user