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);
}
String prompt(const String& text, Completer completer)
String prompt(const String& text, const Context& context, Completer completer)
{
assert(current_client);
return current_client->prompt(text, completer);
return current_client->prompt(text, context, completer);
}
Key get_key()

View File

@ -10,6 +10,7 @@ namespace Kakoune
class Editor;
class Window;
class String;
class Context;
class Client
{
@ -18,7 +19,7 @@ public:
virtual void draw_window(Window& window) = 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;
};
@ -27,7 +28,7 @@ struct prompt_aborted {};
extern Client* current_client;
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();
void print_status(const String& status);

View File

@ -580,10 +580,10 @@ void set_option(OptionManager& option_manager, const CommandParameters& params,
class RegisterRestorer
{
public:
RegisterRestorer(char name)
RegisterRestorer(char name, const Context& context)
: 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());
}
@ -610,7 +610,7 @@ public:
current_client = m_previous_client;
}
String prompt(const String&, Completer)
String prompt(const String&, const Context&, Completer)
{
size_t begin = m_pos;
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);
RegisterRestorer quote('"');
RegisterRestorer slash('/');
RegisterRestorer quote('"', context);
RegisterRestorer slash('/', context);
Editor batch_editor(context.buffer());
Editor& editor = context.has_window() ? static_cast<Editor&>(context.window())
@ -717,7 +717,7 @@ void menu(const CommandParameters& params,
}
oss << "(empty cancels): ";
String choice = prompt(oss.str(), complete_nothing);
String choice = prompt(oss.str(), context, complete_nothing);
int i = str_to_int(choice);
if (i > 0 and i < (count / 2) + 1)

View File

@ -54,7 +54,6 @@ struct Context
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<Buffer> m_buffer;

View File

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

View File

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

View File

@ -18,7 +18,7 @@ public:
void draw_window(Window& window);
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();
};

View File

@ -23,7 +23,7 @@ hook global WinSetOption filetype=(?!cpp).* %{
}
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{

View File

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

View File

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

View File

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