Extract IncrementalInserter::Mode as InsertMode

move ClientMode classes in a namespace due to InsertMode name collisions
This commit is contained in:
Maxime Coste 2012-09-26 14:22:24 +02:00
parent f76323f56e
commit efc069b531
6 changed files with 74 additions and 67 deletions

View File

@ -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)

View File

@ -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 {};

View File

@ -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();
} }

View File

@ -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;
}; };

View File

@ -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> },

View File

@ -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());