Registers need a context to return their values

This commit is contained in:
Maxime Coste 2012-08-05 20:13:41 +02:00
parent 18ca422306
commit 4dc9973288
11 changed files with 51 additions and 57 deletions

View File

@ -14,10 +14,10 @@ void draw_editor_ifn(Editor& editor)
current_client->draw_window(*window); current_client->draw_window(*window);
} }
String prompt(const String& text, Completer completer) String prompt(const String& text, const Context& context, Completer completer)
{ {
assert(current_client); assert(current_client);
return current_client->prompt(text, completer); return current_client->prompt(text, context, completer);
} }
Key get_key() Key get_key()

View File

@ -10,6 +10,7 @@ namespace Kakoune
class Editor; class Editor;
class Window; class Window;
class String; class String;
class Context;
class Client class Client
{ {
@ -18,7 +19,7 @@ public:
virtual void draw_window(Window& window) = 0; virtual void draw_window(Window& window) = 0;
virtual void print_status(const String& status) = 0; virtual void print_status(const String& status) = 0;
virtual String prompt(const String& prompt, Completer completer) = 0; virtual String prompt(const String& prompt, const Context& context, Completer completer) = 0;
virtual Key get_key() = 0; virtual Key get_key() = 0;
}; };
@ -27,7 +28,7 @@ struct prompt_aborted {};
extern Client* current_client; extern Client* current_client;
void draw_editor_ifn(Editor& editor); void draw_editor_ifn(Editor& editor);
String prompt(const String& text, Completer completer = complete_nothing); String prompt(const String& text, const Context& context, Completer completer = complete_nothing);
Key get_key(); Key get_key();
void print_status(const String& status); void print_status(const String& status);

View File

@ -580,10 +580,10 @@ void set_option(OptionManager& option_manager, const CommandParameters& params,
class RegisterRestorer class RegisterRestorer
{ {
public: public:
RegisterRestorer(char name) RegisterRestorer(char name, const Context& context)
: m_name(name) : m_name(name)
{ {
memoryview<String> save = RegisterManager::instance()[name]; memoryview<String> save = RegisterManager::instance()[name].values(context);
m_save = std::vector<String>(save.begin(), save.end()); m_save = std::vector<String>(save.begin(), save.end());
} }
@ -610,7 +610,7 @@ public:
current_client = m_previous_client; current_client = m_previous_client;
} }
String prompt(const String&, Completer) String prompt(const String&, const Context&, Completer)
{ {
size_t begin = m_pos; size_t begin = m_pos;
while (m_pos < m_keys.size() and m_keys[m_pos].key != '\n') while (m_pos < m_keys.size() and m_keys[m_pos].key != '\n')
@ -654,8 +654,8 @@ void exec_keys(const KeyList& keys,
{ {
BatchClient batch_client(keys); BatchClient batch_client(keys);
RegisterRestorer quote('"'); RegisterRestorer quote('"', context);
RegisterRestorer slash('/'); RegisterRestorer slash('/', context);
Editor batch_editor(context.buffer()); Editor batch_editor(context.buffer());
Editor& editor = context.has_window() ? static_cast<Editor&>(context.window()) Editor& editor = context.has_window() ? static_cast<Editor&>(context.window())
@ -717,7 +717,7 @@ void menu(const CommandParameters& params,
} }
oss << "(empty cancels): "; oss << "(empty cancels): ";
String choice = prompt(oss.str(), complete_nothing); String choice = prompt(oss.str(), context, complete_nothing);
int i = str_to_int(choice); int i = str_to_int(choice);
if (i > 0 and i < (count / 2) + 1) if (i > 0 and i < (count / 2) + 1)

View File

@ -54,7 +54,6 @@ struct Context
int numeric_param() const { return m_numeric_param; } int numeric_param() const { return m_numeric_param; }
void numeric_param(int param) { m_numeric_param = param; } void numeric_param(int param) { m_numeric_param = param; }
public: public:
safe_ptr<Editor> m_editor; safe_ptr<Editor> m_editor;
safe_ptr<Buffer> m_buffer; safe_ptr<Buffer> m_buffer;

View File

@ -43,6 +43,7 @@ InsertSequence last_insert_sequence;
template<typename GetKey, typename Redraw> template<typename GetKey, typename Redraw>
void insert_sequence(IncrementalInserter& inserter, void insert_sequence(IncrementalInserter& inserter,
const Context& context,
GetKey get_key, Redraw redraw) GetKey get_key, Redraw redraw)
{ {
while (true) while (true)
@ -66,7 +67,7 @@ void insert_sequence(IncrementalInserter& inserter,
{ {
Key next_key = get_key(); Key next_key = get_key();
if (next_key.modifiers == Key::Modifiers::None) if (next_key.modifiers == Key::Modifiers::None)
inserter.insert(RegisterManager::instance()[next_key.key]); inserter.insert(RegisterManager::instance()[next_key.key].values(context));
break; break;
} }
case 'm': case 'm':
@ -98,7 +99,7 @@ void do_insert(const Context& context)
last_insert_sequence.keys.clear(); last_insert_sequence.keys.clear();
IncrementalInserter inserter(context.editor(), mode); IncrementalInserter inserter(context.editor(), mode);
draw_editor_ifn(context.editor()); draw_editor_ifn(context.editor());
insert_sequence(inserter, insert_sequence(inserter, context,
[&]() { Key key = get_key(); [&]() { Key key = get_key();
last_insert_sequence.keys.push_back(key); last_insert_sequence.keys.push_back(key);
return key; }, return key; },
@ -112,7 +113,7 @@ void do_repeat_insert(const Context& context)
IncrementalInserter inserter(context.editor(), last_insert_sequence.mode); IncrementalInserter inserter(context.editor(), last_insert_sequence.mode);
size_t index = 0; size_t index = 0;
insert_sequence(inserter, insert_sequence(inserter, context,
[&]() { return last_insert_sequence.keys[index++]; }, [&]() { return last_insert_sequence.keys[index++]; },
[](){}); [](){});
} }
@ -168,7 +169,8 @@ void do_command(const Context& context)
{ {
try try
{ {
auto cmdline = prompt(":", std::bind(&CommandManager::complete, auto cmdline = prompt(":", context,
std::bind(&CommandManager::complete,
&CommandManager::instance(), &CommandManager::instance(),
_1, _2)); _1, _2));
@ -181,7 +183,7 @@ void do_pipe(const Context& context)
{ {
try try
{ {
auto cmdline = prompt("|", complete_nothing); auto cmdline = prompt("|", context, complete_nothing);
context.buffer().begin_undo_group(); context.buffer().begin_undo_group();
for (auto& sel : const_cast<const Editor&>(context.editor()).selections()) for (auto& sel : const_cast<const Editor&>(context.editor()).selections())
@ -201,9 +203,9 @@ void do_search(const Context& context)
{ {
try try
{ {
String ex = prompt("/"); String ex = prompt("/", context);
if (ex.empty()) if (ex.empty())
ex = RegisterManager::instance()['/'][0]; ex = RegisterManager::instance()['/'].values(context)[0];
else else
RegisterManager::instance()['/'] = ex; RegisterManager::instance()['/'] = ex;
@ -215,7 +217,7 @@ void do_search(const Context& context)
template<bool append> template<bool append>
void do_search_next(const Context& context) void do_search_next(const Context& context)
{ {
const String& ex = RegisterManager::instance()['/'][0]; const String& ex = RegisterManager::instance()['/'].values(context)[0];
if (not ex.empty()) if (not ex.empty())
context.editor().select(std::bind(select_next_match, _1, ex), append); context.editor().select(std::bind(select_next_match, _1, ex), append);
else else
@ -255,20 +257,20 @@ void do_paste(const Context& context)
if (count == 0) if (count == 0)
{ {
if (paste_mode == PasteMode::Before) if (paste_mode == PasteMode::Before)
editor.insert(reg); editor.insert(reg.values(context));
else if (paste_mode == PasteMode::After) else if (paste_mode == PasteMode::After)
editor.append(reg); editor.append(reg.values(context));
else if (paste_mode == PasteMode::Replace) else if (paste_mode == PasteMode::Replace)
editor.replace(reg); editor.replace(reg.values(context));
} }
else else
{ {
if (paste_mode == PasteMode::Before) if (paste_mode == PasteMode::Before)
editor.insert(reg[count-1]); editor.insert(reg.values(context)[count-1]);
else if (paste_mode == PasteMode::After) else if (paste_mode == PasteMode::After)
editor.append(reg[count-1]); editor.append(reg.values(context)[count-1]);
else if (paste_mode == PasteMode::Replace) else if (paste_mode == PasteMode::Replace)
editor.replace(reg[count-1]); editor.replace(reg.values(context)[count-1]);
} }
} }
@ -276,7 +278,7 @@ void do_select_regex(const Context& context)
{ {
try try
{ {
String ex = prompt("select: "); String ex = prompt("select: ", context);
context.editor().multi_select(std::bind(select_all_matches, _1, ex)); context.editor().multi_select(std::bind(select_all_matches, _1, ex));
} }
catch (prompt_aborted&) {} catch (prompt_aborted&) {}
@ -286,7 +288,7 @@ void do_split_regex(const Context& context)
{ {
try try
{ {
String ex = prompt("split: "); String ex = prompt("split: ", context);
context.editor().multi_select(std::bind(split_selection, _1, ex)); context.editor().multi_select(std::bind(split_selection, _1, ex));
} }
catch (prompt_aborted&) {} catch (prompt_aborted&) {}
@ -468,9 +470,12 @@ int main(int argc, char* argv[])
shell_manager.register_env_var("opt_.+", shell_manager.register_env_var("opt_.+",
[](const String& name, const Context& context) [](const String& name, const Context& context)
{ return context.option_manager()[name.substr(4)].as_string(); }); { return context.option_manager()[name.substr(4)].as_string(); });
shell_manager.register_env_var("reg_.+",
[](const String& name, const Context& context)
{ return RegisterManager::instance()[name[4]].values(context)[0]; });
register_manager.register_dynamic_register('%', [&]() { return std::vector<String>(1, main_context.buffer().name()); }); register_manager.register_dynamic_register('%', [&](const Context& context) { return std::vector<String>(1, context.buffer().name()); });
register_manager.register_dynamic_register('.', [&]() { return main_context.window().selections_content(); }); register_manager.register_dynamic_register('.', [&](const Context& context) { return context.editor().selections_content(); });
register_commands(); register_commands();
register_highlighters(); register_highlighters();

View File

@ -168,7 +168,7 @@ Key NCursesClient::get_key()
return Key(modifiers, c); return Key(modifiers, c);
} }
String NCursesClient::prompt(const String& text, Completer completer) String NCursesClient::prompt(const String& text, const Context& context, Completer completer)
{ {
curs_set(2); curs_set(2);
auto restore_cursor = on_scope_end([]() { curs_set(0); }); auto restore_cursor = on_scope_end([]() { curs_set(0); });
@ -249,7 +249,7 @@ String NCursesClient::prompt(const String& text, Completer completer)
case CTRL('r'): case CTRL('r'):
{ {
c = getch(); c = getch();
String reg = RegisterManager::instance()[c][0]; String reg = RegisterManager::instance()[c].values(context)[0];
current_completion = -1; current_completion = -1;
result = result.substr(0, cursor_pos) + reg + result.substr(cursor_pos, String::npos); result = result.substr(0, cursor_pos) + reg + result.substr(cursor_pos, String::npos);
cursor_pos += reg.length(); cursor_pos += reg.length();

View File

@ -18,7 +18,7 @@ public:
void draw_window(Window& window); void draw_window(Window& window);
void print_status(const String& status); void print_status(const String& status);
String prompt(const String& prompt, Completer completer); String prompt(const String& prompt, const Context& context, Completer completer);
Key get_key(); Key get_key();
}; };

View File

@ -23,7 +23,7 @@ hook global WinSetOption filetype=(?!cpp).* %{
} }
hook global BufNew .*\.(h|hh|hpp|hxx|H) %{ hook global BufNew .*\.(h|hh|hpp|hxx|H) %{
exec ggi<c-r>%<ret><esc>ggxs\.<ret>c_<esc><space>A_INCLUDED<esc>xyppI#ifndef<space><esc>jI#define<space><esc>jI#endif<space>//<space><esc>O<esc> exec ggi<c-r>%<ret><esc>ggxs\.<ret>c_<esc><space>A_INCLUDED<esc>ggxyppI#ifndef<space><esc>jI#define<space><esc>jI#endif<space>//<space><esc>O<esc>
} }
def alt %{ edit %sh{ def alt %{ edit %sh{

View File

@ -7,15 +7,15 @@
namespace Kakoune namespace Kakoune
{ {
class Context;
class Register class Register
{ {
public: public:
virtual ~Register() {} virtual ~Register() {}
virtual Register& operator=(const memoryview<String>& values) = 0; virtual Register& operator=(const memoryview<String>& values) = 0;
virtual const String& operator[](size_t index) = 0; virtual memoryview<String> values(const Context& context) = 0;
virtual operator memoryview<String>() = 0;
}; };
} }

View File

@ -17,16 +17,11 @@ public:
return *this; return *this;
} }
const String& operator[](size_t index) memoryview<String> values(const Context&)
{ {
if (m_content.size() > index) if (m_content.empty())
return m_content[index]; return memoryview<String>(ms_empty);
else else
return ms_empty;
}
operator memoryview<String>()
{
return memoryview<String>(m_content); return memoryview<String>(m_content);
} }
protected: protected:
@ -50,16 +45,10 @@ public:
throw runtime_error("this register is not assignable"); throw runtime_error("this register is not assignable");
} }
const String& operator[](size_t index) memoryview<String> values(const Context& context)
{ {
m_content = m_function(); m_content = m_function(context);
return StaticRegister::operator[](index); return StaticRegister::values(context);
}
operator memoryview<String>()
{
m_content = m_function();
return StaticRegister::operator memoryview<String>();
} }
private: private:

View File

@ -12,7 +12,7 @@
namespace Kakoune namespace Kakoune
{ {
typedef std::function<std::vector<String> ()> RegisterRetriever; typedef std::function<std::vector<String> (const Context&)> RegisterRetriever;
class RegisterManager : public Singleton<RegisterManager> class RegisterManager : public Singleton<RegisterManager>
{ {