summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2012-08-15 22:36:45 +0200
committerMaxime Coste <frrrwww@gmail.com>2012-08-15 22:36:45 +0200
commitc1fcc593a1316c450302de66c7bb466ea75c0fae (patch)
treefffed63072047ae771a413c72e922d33e597dfb7 /src
parenta2aefa299874437a87e3ff0aec8f71d7a490408a (diff)
Store the current client in context
Diffstat (limited to 'src')
-rw-r--r--src/client.cc35
-rw-r--r--src/client.hh13
-rw-r--r--src/commands.cc33
-rw-r--r--src/context.hh36
-rw-r--r--src/main.cc63
5 files changed, 84 insertions, 96 deletions
diff --git a/src/client.cc b/src/client.cc
deleted file mode 100644
index bfa0099a..00000000
--- a/src/client.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "client.hh"
-
-#include "window.hh"
-
-namespace Kakoune
-{
-
-Client* current_client = nullptr;
-
-void draw_editor_ifn(Editor& editor)
-{
- Window* window = dynamic_cast<Window*>(&editor);
- if (current_client and window)
- current_client->draw_window(*window);
-}
-
-String prompt(const String& text, const Context& context, Completer completer)
-{
- assert(current_client);
- return current_client->prompt(text, context, completer);
-}
-
-Key get_key()
-{
- assert(current_client);
- return current_client->get_key();
-}
-
-void print_status(const String& status)
-{
- assert(current_client);
- return current_client->print_status(status);
-}
-
-}
diff --git a/src/client.hh b/src/client.hh
index 3ec36620..84adab4f 100644
--- a/src/client.hh
+++ b/src/client.hh
@@ -3,6 +3,7 @@
#include "keys.hh"
#include "completion.hh"
+#include "utils.hh"
namespace Kakoune
{
@@ -12,26 +13,20 @@ class Window;
class String;
class Context;
-class Client
+class Client : public SafeCountable
{
public:
virtual ~Client() {}
virtual void draw_window(Window& window) = 0;
virtual void print_status(const String& status) = 0;
- virtual String prompt(const String& prompt, const Context& context, Completer completer) = 0;
+ virtual String prompt(const String& prompt, const Context& context,
+ Completer completer = complete_nothing) = 0;
virtual Key get_key() = 0;
};
struct prompt_aborted {};
-extern Client* current_client;
-
-void draw_editor_ifn(Editor& editor);
-String prompt(const String& text, const Context& context, Completer completer = complete_nothing);
-Key get_key();
-void print_status(const String& status);
-
}
#endif // client_hh_INCLUDED
diff --git a/src/commands.cc b/src/commands.cc
index faf399c9..596519ae 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -214,7 +214,7 @@ private:
std::unordered_map<String, bool> m_options;
};
-Buffer* open_or_create(const String& filename)
+Buffer* open_or_create(const String& filename, Context& context)
{
Buffer* buffer = NULL;
try
@@ -223,7 +223,7 @@ Buffer* open_or_create(const String& filename)
}
catch (file_not_found& what)
{
- print_status("new file " + filename);
+ context.print_status("new file " + filename);
buffer = new Buffer(filename, Buffer::Type::NewFile);
}
return buffer;
@@ -248,7 +248,7 @@ void edit(const CommandParameters& params, Context& context)
if (parser.has_option("scratch"))
buffer = new Buffer(filename, Buffer::Type::Scratch);
else
- buffer = open_or_create(filename);
+ buffer = open_or_create(filename, context);
}
Window& window = *buffer->get_or_create_window();
@@ -262,7 +262,7 @@ void edit(const CommandParameters& params, Context& context)
window.select(window.buffer().iterator_at({line, column}));
}
- context = Context(window);
+ context.change_editor(window);
}
void write_buffer(const CommandParameters& params, Context& context)
@@ -344,7 +344,7 @@ void show_buffer(const CommandParameters& params, Context& context)
if (not buffer)
throw runtime_error("buffer " + buffer_name + " does not exists");
- context = Context(*buffer->get_or_create_window());
+ context.change_editor(*buffer->get_or_create_window());
}
void delete_buffer(const CommandParameters& params, Context& context)
@@ -374,7 +374,7 @@ void delete_buffer(const CommandParameters& params, Context& context)
{
if (buf != buffer)
{
- context = Context(*buf->get_or_create_window());
+ context.change_editor(*buf->get_or_create_window());
break;
}
}
@@ -554,7 +554,7 @@ void echo_message(const CommandParameters& params, Context& context)
String message;
for (auto& param : params)
message += param + " ";
- print_status(message);
+ context.print_status(message);
}
void exec_commands_in_file(const CommandParameters& params,
@@ -626,16 +626,10 @@ private:
class BatchClient : public Client
{
public:
- BatchClient(const KeyList& keys)
+ BatchClient(const KeyList& keys, Client* previous_client)
: m_keys(keys), m_pos(0)
{
- m_previous_client = current_client;
- current_client = this;
- }
-
- ~BatchClient()
- {
- current_client = m_previous_client;
+ m_previous_client = previous_client;
}
String prompt(const String&, const Context&, Completer)
@@ -679,7 +673,8 @@ private:
void exec_keys(const KeyList& keys, Context& context)
{
- BatchClient batch_client(keys);
+ BatchClient batch_client(keys, context.has_client() ? &context.client()
+ : nullptr);
RegisterRestorer quote('"', context);
RegisterRestorer slash('/', context);
@@ -687,7 +682,8 @@ void exec_keys(const KeyList& keys, Context& context)
scoped_edition edition(context.editor());
int count = 0;
- Context new_context(context);
+ Context new_context(batch_client);
+ new_context.change_editor(context.window());
while (batch_client.has_key_left())
{
Key key = batch_client.get_key();
@@ -738,7 +734,8 @@ void menu(const CommandParameters& params, Context& context)
}
oss << "(empty cancels): ";
- String choice = prompt(oss.str(), context, complete_nothing);
+ String choice = context.client().prompt(oss.str(), context,
+ complete_nothing);
int i = str_to_int(choice);
if (i > 0 and i < (count / 2) + 1)
diff --git a/src/context.hh b/src/context.hh
index cc4e4fe6..f7bb5282 100644
--- a/src/context.hh
+++ b/src/context.hh
@@ -2,22 +2,26 @@
#define context_hh_INCLUDED
#include "window.hh"
+#include "client.hh"
namespace Kakoune
{
-class Buffer;
-
struct Context
{
Context() {}
Context(Editor& editor)
: m_editor(&editor) {}
+ Context(Client& client)
+ : m_client(&client) {}
+
// to allow func(Context(Editor(...)))
Context(Editor&& editor)
: m_editor(&editor) {}
+ Context& operator=(const Context&) = delete;
+
Buffer& buffer() const
{
if (not has_buffer())
@@ -42,6 +46,21 @@ struct Context
}
bool has_window() const { return m_editor and dynamic_cast<Window*>(m_editor.get()); }
+ Client& client() const
+ {
+ if (not has_client())
+ throw runtime_error("no client in context");
+ return *m_client;
+ }
+ bool has_client() const { return m_client; }
+
+ void change_editor(Editor& editor)
+ {
+ if (has_client() and not dynamic_cast<Window*>(&editor))
+ throw logic_error();
+ m_editor.reset(&editor);
+ }
+
OptionManager& option_manager() const
{
if (has_window())
@@ -51,11 +70,24 @@ struct Context
return GlobalOptionManager::instance();
}
+ void draw_ifn() const
+ {
+ if (has_client())
+ client().draw_window(window());
+ }
+
+ void print_status(const String& status) const
+ {
+ if (has_client())
+ client().print_status(status);
+ }
+
int numeric_param() const { return m_numeric_param; }
void numeric_param(int param) { m_numeric_param = param; }
public:
safe_ptr<Editor> m_editor;
+ safe_ptr<Client> m_client;
int m_numeric_param = 0;
};
diff --git a/src/main.cc b/src/main.cc
index 68e32262..b9fbecdb 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -97,12 +97,12 @@ void do_insert(Context& context)
last_insert_sequence.mode = mode;
last_insert_sequence.keys.clear();
IncrementalInserter inserter(context.editor(), mode);
- draw_editor_ifn(context.editor());
+ context.draw_ifn();
insert_sequence(inserter, context,
- [&]() { Key key = get_key();
+ [&]() { Key key = context.client().get_key();
last_insert_sequence.keys.push_back(key);
return key; },
- [&]() { draw_editor_ifn(context.editor()); });
+ [&]() { context.draw_ifn(); });
}
void do_repeat_insert(Context& context)
@@ -131,7 +131,7 @@ void do_go(Context& context)
}
else
{
- Key key = get_key();
+ Key key = context.client().get_key();
if (key.modifiers != Key::Modifiers::None)
return;
@@ -168,10 +168,10 @@ void do_command(Context& context)
{
try
{
- auto cmdline = prompt(":", context,
- std::bind(&CommandManager::complete,
- &CommandManager::instance(),
- _1, _2, _3));
+ auto cmdline = context.client().prompt(
+ ":", context, std::bind(&CommandManager::complete,
+ &CommandManager::instance(),
+ _1, _2, _3));
CommandManager::instance().execute(cmdline, context);
}
@@ -182,7 +182,7 @@ void do_pipe(Context& context)
{
try
{
- auto cmdline = prompt("|", context, complete_nothing);
+ auto cmdline = context.client().prompt("|", context, complete_nothing);
Editor& editor = context.editor();
std::vector<String> strings;
@@ -199,7 +199,7 @@ void do_search(Context& context)
{
try
{
- String ex = prompt("/", context);
+ String ex = context.client().prompt("/", context);
if (ex.empty())
ex = RegisterManager::instance()['/'].values(context)[0];
else
@@ -217,7 +217,7 @@ void do_search_next(Context& context)
if (not ex.empty())
context.editor().select(std::bind(select_next_match, _1, ex), append);
else
- print_status("no search pattern");
+ context.print_status("no search pattern");
}
void do_yank(Context& context)
@@ -274,7 +274,7 @@ void do_select_regex(Context& context)
{
try
{
- String ex = prompt("select: ", context);
+ String ex = context.client().prompt("select: ", context);
context.editor().multi_select(std::bind(select_all_matches, _1, ex));
}
catch (prompt_aborted&) {}
@@ -284,7 +284,7 @@ void do_split_regex(Context& context)
{
try
{
- String ex = prompt("split: ", context);
+ String ex = context.client().prompt("split: ", context);
context.editor().multi_select(std::bind(split_selection, _1, ex));
}
catch (prompt_aborted&) {}
@@ -321,7 +321,7 @@ void do_select_object(Context& context)
{ { Key::Modifiers::None, 'W' }, std::bind(select_whole_word<true>, _1, inner) },
};
- Key key = get_key();
+ Key key = context.client().get_key();
auto it = key_to_selector.find(key);
if (it != key_to_selector.end())
context.editor().select(it->second);
@@ -357,10 +357,10 @@ std::unordered_map<Key, std::function<void (Context& context)>> keymap =
{ { Key::Modifiers::None, 'K' }, [](Context& context) { context.editor().move_selections(BufferCoord(-std::max(context.numeric_param(),1), 0), true); } },
{ { Key::Modifiers::None, 'L' }, [](Context& context) { context.editor().move_selections(BufferCoord(0, std::max(context.numeric_param(),1)), true); } },
- { { Key::Modifiers::None, 't' }, [](Context& context) { context.editor().select(std::bind(select_to, _1, get_key().key, context.numeric_param(), false)); } },
- { { Key::Modifiers::None, 'f' }, [](Context& context) { context.editor().select(std::bind(select_to, _1, get_key().key, context.numeric_param(), true)); } },
- { { Key::Modifiers::None, 'T' }, [](Context& context) { context.editor().select(std::bind(select_to, _1, get_key().key, context.numeric_param(), false), true); } },
- { { Key::Modifiers::None, 'F' }, [](Context& context) { context.editor().select(std::bind(select_to, _1, get_key().key, context.numeric_param(), true), true); } },
+ { { Key::Modifiers::None, 't' }, [](Context& context) { context.editor().select(std::bind(select_to, _1, context.client().get_key().key, context.numeric_param(), false)); } },
+ { { Key::Modifiers::None, 'f' }, [](Context& context) { context.editor().select(std::bind(select_to, _1, context.client().get_key().key, context.numeric_param(), true)); } },
+ { { Key::Modifiers::None, 'T' }, [](Context& context) { context.editor().select(std::bind(select_to, _1, context.client().get_key().key, context.numeric_param(), false), true); } },
+ { { Key::Modifiers::None, 'F' }, [](Context& context) { context.editor().select(std::bind(select_to, _1, context.client().get_key().key, context.numeric_param(), true), true); } },
{ { Key::Modifiers::None, 'd' }, do_erase },
{ { Key::Modifiers::None, 'c' }, do_change },
@@ -410,16 +410,16 @@ std::unordered_map<Key, std::function<void (Context& context)>> keymap =
{ { Key::Modifiers::None, 'n' }, do_search_next<false> },
{ { Key::Modifiers::None, 'N' }, do_search_next<true> },
- { { Key::Modifiers::None, 'u' }, repeated([](Context& context) { if (not context.editor().undo()) { print_status("nothing left to undo"); } }) },
- { { Key::Modifiers::None, 'U' }, repeated([](Context& context) { if (not context.editor().redo()) { print_status("nothing left to redo"); } }) },
+ { { Key::Modifiers::None, 'u' }, repeated([](Context& context) { if (not context.editor().undo()) { context.print_status("nothing left to undo"); } }) },
+ { { Key::Modifiers::None, 'U' }, repeated([](Context& context) { if (not context.editor().redo()) { context.print_status("nothing left to redo"); } }) },
{ { Key::Modifiers::Alt, 'i' }, do_select_object<true> },
{ { Key::Modifiers::Alt, 'a' }, do_select_object<false> },
- { { Key::Modifiers::Alt, 't' }, [](Context& context) { context.editor().select(std::bind(select_to_reverse, _1, get_key().key, context.numeric_param(), false)); } },
- { { Key::Modifiers::Alt, 'f' }, [](Context& context) { context.editor().select(std::bind(select_to_reverse, _1, get_key().key, context.numeric_param(), true)); } },
- { { Key::Modifiers::Alt, 'T' }, [](Context& context) { context.editor().select(std::bind(select_to_reverse, _1, get_key().key, context.numeric_param(), false), true); } },
- { { Key::Modifiers::Alt, 'F' }, [](Context& context) { context.editor().select(std::bind(select_to_reverse, _1, get_key().key, context.numeric_param(), true), true); } },
+ { { Key::Modifiers::Alt, 't' }, [](Context& context) { context.editor().select(std::bind(select_to_reverse, _1, context.client().get_key().key, context.numeric_param(), false)); } },
+ { { Key::Modifiers::Alt, 'f' }, [](Context& context) { context.editor().select(std::bind(select_to_reverse, _1, context.client().get_key().key, context.numeric_param(), true)); } },
+ { { Key::Modifiers::Alt, 'T' }, [](Context& context) { context.editor().select(std::bind(select_to_reverse, _1, context.client().get_key().key, context.numeric_param(), false), true); } },
+ { { Key::Modifiers::Alt, 'F' }, [](Context& context) { context.editor().select(std::bind(select_to_reverse, _1, context.client().get_key().key, context.numeric_param(), true), true); } },
{ { Key::Modifiers::Alt, 'w' }, repeated([](Context& context) { context.editor().select(select_to_next_word<true>); }) },
{ { Key::Modifiers::Alt, 'e' }, repeated([](Context& context) { context.editor().select(select_to_next_word_end<true>); }) },
@@ -480,8 +480,7 @@ int main(int argc, char* argv[])
try
{
NCursesClient client;
- current_client = &client;
- Context context;
+ Context context(client);
try
{
@@ -489,7 +488,7 @@ int main(int argc, char* argv[])
}
catch (Kakoune::runtime_error& error)
{
- print_status(error.description());
+ context.print_status(error.description());
}
@@ -506,16 +505,16 @@ int main(int argc, char* argv[])
else
{
auto buffer = new Buffer("*scratch*", Buffer::Type::Scratch);
- context = Context(*buffer->get_or_create_window());
+ context.change_editor(*buffer->get_or_create_window());
}
- current_client->draw_window(context.window());
+ context.draw_ifn();
int count = 0;
while(not quit_requested)
{
try
{
- Key key = get_key();
+ Key key = context.client().get_key();
if (key.modifiers == Key::Modifiers::None and isdigit(key.key))
count = count * 10 + key.key - '0';
else
@@ -525,14 +524,14 @@ int main(int argc, char* argv[])
{
context.numeric_param(count);
it->second(context);
- current_client->draw_window(context.window());
+ context.draw_ifn();
}
count = 0;
}
}
catch (Kakoune::runtime_error& error)
{
- print_status(error.description());
+ context.print_status(error.description());
}
}
}