Extract IncrementalInserter::Mode as InsertMode
move ClientMode classes in a namespace due to InsertMode name collisions
This commit is contained in:
parent
f76323f56e
commit
efc069b531
|
@ -1,6 +1,7 @@
|
||||||
#include "client.hh"
|
#include "client.hh"
|
||||||
|
|
||||||
#include "context.hh"
|
#include "context.hh"
|
||||||
|
#include "editor.hh"
|
||||||
#include "register_manager.hh"
|
#include "register_manager.hh"
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -21,15 +22,18 @@ public:
|
||||||
virtual void on_key(const Key& key, Context& context) = 0;
|
virtual void on_key(const Key& key, Context& context) = 0;
|
||||||
protected:
|
protected:
|
||||||
void reset_normal_mode();
|
void reset_normal_mode();
|
||||||
std::pair<IncrementalInserter::Mode, std::vector<Key>>& last_insert() { return m_client.m_last_insert; }
|
std::pair<InsertMode, std::vector<Key>>& last_insert() { return m_client.m_last_insert; }
|
||||||
private:
|
private:
|
||||||
Client& m_client;
|
Client& m_client;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NormalMode : public ClientMode
|
namespace ClientModes
|
||||||
|
{
|
||||||
|
|
||||||
|
class Normal : public ClientMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NormalMode(Client& client)
|
Normal(Client& client)
|
||||||
: ClientMode(client)
|
: ClientMode(client)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -58,16 +62,11 @@ private:
|
||||||
int m_count = 0;
|
int m_count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ClientMode::reset_normal_mode()
|
class Menu : public ClientMode
|
||||||
{
|
|
||||||
m_client.m_mode.reset(new NormalMode(m_client));
|
|
||||||
}
|
|
||||||
|
|
||||||
class MenuMode : public ClientMode
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MenuMode(Context& context, const memoryview<String>& choices,
|
Menu(Context& context, const memoryview<String>& choices,
|
||||||
MenuCallback callback)
|
MenuCallback callback)
|
||||||
: ClientMode(context.client()),
|
: ClientMode(context.client()),
|
||||||
m_callback(callback), m_choice_count(choices.size()), m_selected(0)
|
m_callback(callback), m_choice_count(choices.size()), m_selected(0)
|
||||||
{
|
{
|
||||||
|
@ -125,11 +124,11 @@ private:
|
||||||
int m_choice_count;
|
int m_choice_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PromptMode : public ClientMode
|
class Prompt : public ClientMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PromptMode(Context& context, const String& prompt,
|
Prompt(Context& context, const String& prompt,
|
||||||
Completer completer, PromptCallback callback)
|
Completer completer, PromptCallback callback)
|
||||||
: ClientMode(context.client()), m_prompt(prompt),
|
: ClientMode(context.client()), m_prompt(prompt),
|
||||||
m_completer(completer), m_callback(callback)
|
m_completer(completer), m_callback(callback)
|
||||||
{
|
{
|
||||||
|
@ -296,12 +295,12 @@ private:
|
||||||
static std::unordered_map<String, std::vector<String>> ms_history;
|
static std::unordered_map<String, std::vector<String>> ms_history;
|
||||||
std::vector<String>::iterator m_history_it;
|
std::vector<String>::iterator m_history_it;
|
||||||
};
|
};
|
||||||
std::unordered_map<String, std::vector<String>> PromptMode::ms_history;
|
std::unordered_map<String, std::vector<String>> Prompt::ms_history;
|
||||||
|
|
||||||
class NextKeyMode : public ClientMode
|
class NextKey : public ClientMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NextKeyMode(Client& client, KeyCallback callback)
|
NextKey(Client& client, KeyCallback callback)
|
||||||
: ClientMode(client), m_callback(callback) {}
|
: ClientMode(client), m_callback(callback) {}
|
||||||
|
|
||||||
void on_key(const Key& key, Context& context) override
|
void on_key(const Key& key, Context& context) override
|
||||||
|
@ -316,10 +315,10 @@ private:
|
||||||
KeyCallback m_callback;
|
KeyCallback m_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InsertMode : public ClientMode
|
class Insert : public ClientMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InsertMode(Client& client, Editor& editor, IncrementalInserter::Mode mode)
|
Insert(Client& client, Editor& editor, InsertMode mode)
|
||||||
: ClientMode(client), m_inserter(editor, mode)
|
: ClientMode(client), m_inserter(editor, mode)
|
||||||
{
|
{
|
||||||
last_insert().first = mode;
|
last_insert().first = mode;
|
||||||
|
@ -384,9 +383,17 @@ private:
|
||||||
IncrementalInserter m_inserter;
|
IncrementalInserter m_inserter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientMode::reset_normal_mode()
|
||||||
|
{
|
||||||
|
m_client.m_mode.reset(new ClientModes::Normal(m_client));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Client::Client()
|
Client::Client()
|
||||||
: m_mode(new NormalMode(*this)),
|
: m_mode(new ClientModes::Normal(*this)),
|
||||||
m_last_insert(IncrementalInserter::Mode::Insert, {})
|
m_last_insert(InsertMode::Insert, {})
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,9 +401,9 @@ Client::~Client()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::insert(Editor& editor, IncrementalInserter::Mode mode)
|
void Client::insert(Editor& editor, InsertMode mode)
|
||||||
{
|
{
|
||||||
m_mode.reset(new InsertMode(*this, editor, mode));
|
m_mode.reset(new ClientModes::Insert(*this, editor, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::repeat_last_insert(Context& context)
|
void Client::repeat_last_insert(Context& context)
|
||||||
|
@ -408,29 +415,29 @@ void Client::repeat_last_insert(Context& context)
|
||||||
swap(keys, m_last_insert.second);
|
swap(keys, m_last_insert.second);
|
||||||
// m_last_insert will be refilled by the new InsertMode
|
// m_last_insert will be refilled by the new InsertMode
|
||||||
// this is very inefficient.
|
// this is very inefficient.
|
||||||
m_mode.reset(new InsertMode(*this, context.editor(), m_last_insert.first));
|
m_mode.reset(new ClientModes::Insert(*this, context.editor(), m_last_insert.first));
|
||||||
for (auto& key : keys)
|
for (auto& key : keys)
|
||||||
m_mode->on_key(key, context);
|
m_mode->on_key(key, context);
|
||||||
assert(dynamic_cast<NormalMode*>(m_mode.get()) != nullptr);
|
assert(dynamic_cast<ClientModes::Normal*>(m_mode.get()) != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::prompt(const String& prompt, Completer completer,
|
void Client::prompt(const String& prompt, Completer completer,
|
||||||
PromptCallback callback, Context& context)
|
PromptCallback callback, Context& context)
|
||||||
{
|
{
|
||||||
assert(&context.client() == this);
|
assert(&context.client() == this);
|
||||||
m_mode.reset(new PromptMode(context, prompt, completer, callback));
|
m_mode.reset(new ClientModes::Prompt(context, prompt, completer, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::menu(const memoryview<String>& choices,
|
void Client::menu(const memoryview<String>& choices,
|
||||||
MenuCallback callback, Context& context)
|
MenuCallback callback, Context& context)
|
||||||
{
|
{
|
||||||
assert(&context.client() == this);
|
assert(&context.client() == this);
|
||||||
m_mode.reset(new MenuMode(context, choices, callback));
|
m_mode.reset(new ClientModes::Menu(context, choices, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::on_next_key(KeyCallback callback)
|
void Client::on_next_key(KeyCallback callback)
|
||||||
{
|
{
|
||||||
m_mode.reset(new NextKeyMode(*this, callback));
|
m_mode.reset(new ClientModes::NextKey(*this, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::handle_next_input(Context& context)
|
void Client::handle_next_input(Context& context)
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "completion.hh"
|
#include "completion.hh"
|
||||||
#include "utils.hh"
|
#include "utils.hh"
|
||||||
#include "string.hh"
|
#include "string.hh"
|
||||||
#include "window.hh"
|
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
@ -18,6 +17,7 @@ using PromptCallback = std::function<void (const String&, Context&)>;
|
||||||
using KeyCallback = std::function<void (const Key&, Context&)>;
|
using KeyCallback = std::function<void (const Key&, Context&)>;
|
||||||
|
|
||||||
class ClientMode;
|
class ClientMode;
|
||||||
|
enum class InsertMode : unsigned;
|
||||||
|
|
||||||
class Client : public SafeCountable
|
class Client : public SafeCountable
|
||||||
{
|
{
|
||||||
|
@ -25,7 +25,7 @@ public:
|
||||||
Client();
|
Client();
|
||||||
~Client();
|
~Client();
|
||||||
|
|
||||||
void insert(Editor& editor, IncrementalInserter::Mode mode);
|
void insert(Editor& editor, InsertMode mode);
|
||||||
void repeat_last_insert(Context& context);
|
void repeat_last_insert(Context& context);
|
||||||
|
|
||||||
void prompt(const String& prompt, Completer completer,
|
void prompt(const String& prompt, Completer completer,
|
||||||
|
@ -41,7 +41,7 @@ public:
|
||||||
private:
|
private:
|
||||||
friend class ClientMode;
|
friend class ClientMode;
|
||||||
std::unique_ptr<ClientMode> m_mode;
|
std::unique_ptr<ClientMode> m_mode;
|
||||||
std::pair<IncrementalInserter::Mode, std::vector<Key>> m_last_insert;
|
std::pair<InsertMode, std::vector<Key>> m_last_insert;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct prompt_aborted {};
|
struct prompt_aborted {};
|
||||||
|
|
|
@ -303,12 +303,12 @@ void Editor::end_edition()
|
||||||
--m_edition_level;
|
--m_edition_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
IncrementalInserter::IncrementalInserter(Editor& editor, Mode mode)
|
IncrementalInserter::IncrementalInserter(Editor& editor, InsertMode mode)
|
||||||
: m_editor(editor), m_edition(editor), m_mode(mode)
|
: m_editor(editor), m_edition(editor), m_mode(mode)
|
||||||
{
|
{
|
||||||
m_editor.on_incremental_insertion_begin();
|
m_editor.on_incremental_insertion_begin();
|
||||||
|
|
||||||
if (mode == Mode::Change)
|
if (mode == InsertMode::Change)
|
||||||
{
|
{
|
||||||
for (auto& sel : editor.m_selections)
|
for (auto& sel : editor.m_selections)
|
||||||
editor.m_buffer.erase(sel.begin(), sel.end());
|
editor.m_buffer.erase(sel.begin(), sel.end());
|
||||||
|
@ -319,20 +319,20 @@ IncrementalInserter::IncrementalInserter(Editor& editor, Mode mode)
|
||||||
BufferIterator first, last;
|
BufferIterator first, last;
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case Mode::Insert: first = sel.end()-1; last = sel.begin(); break;
|
case InsertMode::Insert: first = sel.end()-1; last = sel.begin(); break;
|
||||||
case Mode::Change: first = sel.end()-1; last = sel.begin(); break;
|
case InsertMode::Change: first = sel.end()-1; last = sel.begin(); break;
|
||||||
case Mode::Append: first = sel.begin(); last = sel.end(); break;
|
case InsertMode::Append: first = sel.begin(); last = sel.end(); break;
|
||||||
|
|
||||||
case Mode::OpenLineBelow:
|
case InsertMode::OpenLineBelow:
|
||||||
case Mode::AppendAtLineEnd:
|
case InsertMode::AppendAtLineEnd:
|
||||||
first = m_editor.m_buffer.iterator_at_line_end(sel.end() - 1) - 1;
|
first = m_editor.m_buffer.iterator_at_line_end(sel.end() - 1) - 1;
|
||||||
last = first;
|
last = first;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Mode::OpenLineAbove:
|
case InsertMode::OpenLineAbove:
|
||||||
case Mode::InsertAtLineBegin:
|
case InsertMode::InsertAtLineBegin:
|
||||||
first = m_editor.m_buffer.iterator_at_line_begin(sel.begin());
|
first = m_editor.m_buffer.iterator_at_line_begin(sel.begin());
|
||||||
if (mode == Mode::OpenLineAbove)
|
if (mode == InsertMode::OpenLineAbove)
|
||||||
--first;
|
--first;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -351,10 +351,10 @@ IncrementalInserter::IncrementalInserter(Editor& editor, Mode mode)
|
||||||
--last;
|
--last;
|
||||||
sel = Selection(first, last);
|
sel = Selection(first, last);
|
||||||
}
|
}
|
||||||
if (mode == Mode::OpenLineBelow or mode == Mode::OpenLineAbove)
|
if (mode == InsertMode::OpenLineBelow or mode == InsertMode::OpenLineAbove)
|
||||||
{
|
{
|
||||||
insert("\n");
|
insert("\n");
|
||||||
if (mode == Mode::OpenLineAbove)
|
if (mode == InsertMode::OpenLineAbove)
|
||||||
{
|
{
|
||||||
for (auto& sel : m_editor.m_selections)
|
for (auto& sel : m_editor.m_selections)
|
||||||
{
|
{
|
||||||
|
@ -370,7 +370,7 @@ IncrementalInserter::~IncrementalInserter()
|
||||||
{
|
{
|
||||||
for (auto& sel : m_editor.m_selections)
|
for (auto& sel : m_editor.m_selections)
|
||||||
{
|
{
|
||||||
if (m_mode == Mode::Append)
|
if (m_mode == InsertMode::Append)
|
||||||
sel = Selection(sel.first(), sel.last()-1);
|
sel = Selection(sel.first(), sel.last()-1);
|
||||||
sel.avoid_eol();
|
sel.avoid_eol();
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,22 +101,22 @@ private:
|
||||||
Editor& m_editor;
|
Editor& m_editor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class InsertMode : unsigned
|
||||||
|
{
|
||||||
|
Insert,
|
||||||
|
Append,
|
||||||
|
Change,
|
||||||
|
InsertAtLineBegin,
|
||||||
|
AppendAtLineEnd,
|
||||||
|
OpenLineBelow,
|
||||||
|
OpenLineAbove
|
||||||
|
};
|
||||||
|
|
||||||
// An IncrementalInserter manage insert mode
|
// An IncrementalInserter manage insert mode
|
||||||
class IncrementalInserter
|
class IncrementalInserter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class Mode
|
IncrementalInserter(Editor& editor, InsertMode mode = InsertMode::Insert);
|
||||||
{
|
|
||||||
Insert,
|
|
||||||
Append,
|
|
||||||
Change,
|
|
||||||
InsertAtLineBegin,
|
|
||||||
AppendAtLineEnd,
|
|
||||||
OpenLineBelow,
|
|
||||||
OpenLineAbove
|
|
||||||
};
|
|
||||||
|
|
||||||
IncrementalInserter(Editor& editor, Mode mode = Mode::Insert);
|
|
||||||
~IncrementalInserter();
|
~IncrementalInserter();
|
||||||
|
|
||||||
void insert(const String& string);
|
void insert(const String& string);
|
||||||
|
@ -127,8 +127,8 @@ public:
|
||||||
Buffer& buffer() const { return m_editor.buffer(); }
|
Buffer& buffer() const { return m_editor.buffer(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mode m_mode;
|
InsertMode m_mode;
|
||||||
Editor& m_editor;
|
Editor& m_editor;
|
||||||
scoped_edition m_edition;
|
scoped_edition m_edition;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
16
src/main.cc
16
src/main.cc
|
@ -33,7 +33,7 @@ namespace Kakoune
|
||||||
|
|
||||||
bool quit_requested = false;
|
bool quit_requested = false;
|
||||||
|
|
||||||
template<IncrementalInserter::Mode mode>
|
template<InsertMode mode>
|
||||||
void do_insert(Context& context)
|
void do_insert(Context& context)
|
||||||
{
|
{
|
||||||
context.client().insert(context.editor(), mode);
|
context.client().insert(context.editor(), mode);
|
||||||
|
@ -156,7 +156,7 @@ void do_erase(Context& context)
|
||||||
void do_change(Context& context)
|
void do_change(Context& context)
|
||||||
{
|
{
|
||||||
RegisterManager::instance()['"'] = context.editor().selections_content();
|
RegisterManager::instance()['"'] = context.editor().selections_content();
|
||||||
do_insert<IncrementalInserter::Mode::Change>(context);
|
do_insert<InsertMode::Change>(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class PasteMode
|
enum class PasteMode
|
||||||
|
@ -358,12 +358,12 @@ std::unordered_map<Key, std::function<void (Context& context)>> keymap =
|
||||||
|
|
||||||
{ { Key::Modifiers::None, 'd' }, do_erase },
|
{ { Key::Modifiers::None, 'd' }, do_erase },
|
||||||
{ { Key::Modifiers::None, 'c' }, do_change },
|
{ { Key::Modifiers::None, 'c' }, do_change },
|
||||||
{ { Key::Modifiers::None, 'i' }, do_insert<IncrementalInserter::Mode::Insert> },
|
{ { Key::Modifiers::None, 'i' }, do_insert<InsertMode::Insert> },
|
||||||
{ { Key::Modifiers::None, 'I' }, do_insert<IncrementalInserter::Mode::InsertAtLineBegin> },
|
{ { Key::Modifiers::None, 'I' }, do_insert<InsertMode::InsertAtLineBegin> },
|
||||||
{ { Key::Modifiers::None, 'a' }, do_insert<IncrementalInserter::Mode::Append> },
|
{ { Key::Modifiers::None, 'a' }, do_insert<InsertMode::Append> },
|
||||||
{ { Key::Modifiers::None, 'A' }, do_insert<IncrementalInserter::Mode::AppendAtLineEnd> },
|
{ { Key::Modifiers::None, 'A' }, do_insert<InsertMode::AppendAtLineEnd> },
|
||||||
{ { Key::Modifiers::None, 'o' }, do_insert<IncrementalInserter::Mode::OpenLineBelow> },
|
{ { Key::Modifiers::None, 'o' }, do_insert<InsertMode::OpenLineBelow> },
|
||||||
{ { Key::Modifiers::None, 'O' }, do_insert<IncrementalInserter::Mode::OpenLineAbove> },
|
{ { Key::Modifiers::None, 'O' }, do_insert<InsertMode::OpenLineAbove> },
|
||||||
{ { Key::Modifiers::None, 'r' }, do_replace_with_char },
|
{ { Key::Modifiers::None, 'r' }, do_replace_with_char },
|
||||||
|
|
||||||
{ { Key::Modifiers::None, 'g' }, do_go<SelectMode::Replace> },
|
{ { Key::Modifiers::None, 'g' }, do_go<SelectMode::Replace> },
|
||||||
|
|
|
@ -61,7 +61,7 @@ void test_incremental_inserter()
|
||||||
|
|
||||||
editor.select(buffer.begin());
|
editor.select(buffer.begin());
|
||||||
{
|
{
|
||||||
IncrementalInserter inserter(editor, IncrementalInserter::Mode::OpenLineAbove);
|
IncrementalInserter inserter(editor, InsertMode::OpenLineAbove);
|
||||||
assert(editor.is_editing());
|
assert(editor.is_editing());
|
||||||
assert(editor.selections().size() == 1);
|
assert(editor.selections().size() == 1);
|
||||||
assert(editor.selections().front().first() == buffer.begin());
|
assert(editor.selections().front().first() == buffer.begin());
|
||||||
|
|
Loading…
Reference in New Issue
Block a user