diff --git a/src/input_handler.cc b/src/input_handler.cc index 0cf1de9a..9a582467 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -280,7 +280,7 @@ public: reset_normal_mode(); // call callback after reset_normal_mode so that callback // may change the mode - m_callback(line, context); + m_callback(line, PromptEvent::Validate, context); return; } else if (key == Key::Escape or key == Key { Key::Modifiers::Control, 'c' }) @@ -288,6 +288,7 @@ public: context.ui().print_status(""); context.ui().menu_hide(); reset_normal_mode(); + m_callback(line, PromptEvent::Abort, context); return; } else if (key == Key{Key::Modifiers::Control, 'r'}) @@ -385,6 +386,7 @@ public: } context.ui().print_status(m_prompt + line, m_prompt.char_length() + m_line_editor.cursor_pos()); + m_callback(line, PromptEvent::Change, context); } private: diff --git a/src/input_handler.hh b/src/input_handler.hh index e5509c22..3d520d27 100644 --- a/src/input_handler.hh +++ b/src/input_handler.hh @@ -13,7 +13,14 @@ class Editor; class Context; using MenuCallback = std::function; -using PromptCallback = std::function; + +enum class PromptEvent +{ + Change, + Abort, + Validate +}; +using PromptCallback = std::function; using KeyCallback = std::function; class InputMode; diff --git a/src/main.cc b/src/main.cc index 6e783ddc..fa8065f1 100644 --- a/src/main.cc +++ b/src/main.cc @@ -107,15 +107,20 @@ void do_command(Context& context) { context.input_handler().prompt( ":", std::bind(&CommandManager::complete, &CommandManager::instance(), _1, _2, _3), - [](const String& cmdline, Context& context) { CommandManager::instance().execute(cmdline, context); }, - context); + [](const String& cmdline, PromptEvent event, Context& context) { + if (event == PromptEvent::Validate) + CommandManager::instance().execute(cmdline, context); + }, context); } void do_pipe(Context& context) { context.input_handler().prompt("|", complete_nothing, - [](const String& cmdline, Context& context) + [](const String& cmdline, PromptEvent event, Context& context) { + if (event != PromptEvent::Validate) + return; + Editor& editor = context.editor(); std::vector strings; for (auto& sel : const_cast(context.editor()).selections()) @@ -129,14 +134,22 @@ void do_pipe(Context& context) template void do_search(Context& context) { + SelectionList selections = context.editor().selections(); context.input_handler().prompt("/", complete_nothing, - [](const String& str, Context& context) { - String ex = str; - if (ex.empty()) - ex = RegisterManager::instance()['/'].values(context)[0]; - else - RegisterManager::instance()['/'] = ex; + [selections](const String& str, PromptEvent event, Context& context) { + context.editor().select(selections); + if (str.empty() or event == PromptEvent::Abort) + return; + + String ex = str; + if (event == PromptEvent::Validate) + { + if (ex.empty()) + ex = RegisterManager::instance()['/'].values(context)[0]; + else + RegisterManager::instance()['/'] = ex; + } context.editor().select(std::bind(select_next_match, _1, ex), mode); }, context); } @@ -212,17 +225,19 @@ void do_paste(Context& context) void do_select_regex(Context& context) { context.input_handler().prompt("select: ", complete_nothing, - [](const String& ex, Context& context) - { context.editor().multi_select(std::bind(select_all_matches, _1, ex)); }, - context); + [](const String& ex, PromptEvent event, Context& context) { + if (event == PromptEvent::Validate) + context.editor().multi_select(std::bind(select_all_matches, _1, ex)); + }, context); } void do_split_regex(Context& context) { context.input_handler().prompt("split: ", complete_nothing, - [](const String& ex, Context& context) - { context.editor().multi_select(std::bind(split_selection, _1, ex)); }, - context); + [](const String& ex, PromptEvent event, Context& context) { + if (event == PromptEvent::Validate) + context.editor().multi_select(std::bind(split_selection, _1, ex)); + }, context); } void do_join(Context& context)