Add support for mapping keys in goto/view commands

This commit is contained in:
Maxime Coste 2014-09-23 13:45:18 +01:00
parent 858132e771
commit 4c4d3cdd38
6 changed files with 33 additions and 18 deletions

View File

@ -146,7 +146,8 @@ void Client::check_buffer_fs_timestamp()
"press r or y to reload, k or n to keep", "press r or y to reload, k or n to keep",
pos, get_face("Information"), MenuStyle::Prompt); pos, get_face("Information"), MenuStyle::Prompt);
m_input_handler.on_next_key([this, filename, ts](Key key, Context& context) { m_input_handler.on_next_key(KeymapMode::None,
[this, filename, ts](Key key, Context& context) {
Buffer* buf = BufferManager::instance().get_buffer_ifp(filename); Buffer* buf = BufferManager::instance().get_buffer_ifp(filename);
m_ui->info_hide(); m_ui->info_hide();
// buffer got deleted while waiting for the key, do nothing // buffer got deleted while waiting for the key, do nothing

View File

@ -928,13 +928,15 @@ KeymapMode parse_keymap_mode(const String& str)
if (prefix_match("insert", str)) return KeymapMode::Insert; if (prefix_match("insert", str)) return KeymapMode::Insert;
if (prefix_match("menu", str)) return KeymapMode::Menu; if (prefix_match("menu", str)) return KeymapMode::Menu;
if (prefix_match("prompt", str)) return KeymapMode::Prompt; if (prefix_match("prompt", str)) return KeymapMode::Prompt;
if (prefix_match("goto", str)) return KeymapMode::Goto;
if (prefix_match("view", str)) return KeymapMode::View;
throw runtime_error("unknown keymap mode '" + str + "'"); throw runtime_error("unknown keymap mode '" + str + "'");
} }
CandidateList complete_mode(StringView prefix) CandidateList complete_mode(StringView prefix)
{ {
CandidateList res; CandidateList res;
for (auto mode : { "normal", "insert", "menu", "prompt" }) for (auto mode : { "normal", "insert", "menu", "prompt", "goto", "view" })
{ {
if (prefix_match(mode, prefix)) if (prefix_match(mode, prefix))
res.emplace_back(mode); res.emplace_back(mode);

View File

@ -730,8 +730,8 @@ std::unordered_map<String, std::vector<String>> Prompt::ms_history;
class NextKey : public InputMode class NextKey : public InputMode
{ {
public: public:
NextKey(InputHandler& input_handler, KeyCallback callback) NextKey(InputHandler& input_handler, KeymapMode keymap_mode, KeyCallback callback)
: InputMode(input_handler), m_callback(callback) {} : InputMode(input_handler), m_keymap_mode(keymap_mode), m_callback(callback) {}
void on_key(Key key) override void on_key(Key key) override
{ {
@ -744,10 +744,11 @@ public:
return { "enter key", Face(Colors::Yellow) }; return { "enter key", Face(Colors::Yellow) };
} }
KeymapMode keymap_mode() const override { return KeymapMode::None; } KeymapMode keymap_mode() const override { return m_keymap_mode; }
private: private:
KeyCallback m_callback; KeyCallback m_callback;
KeymapMode m_keymap_mode;
}; };
class Insert : public InputMode class Insert : public InputMode
@ -1078,9 +1079,9 @@ void InputHandler::menu(memoryview<String> choices,
change_input_mode(new InputModes::Menu(*this, choices, callback)); change_input_mode(new InputModes::Menu(*this, choices, callback));
} }
void InputHandler::on_next_key(KeyCallback callback) void InputHandler::on_next_key(KeymapMode keymap_mode, KeyCallback callback)
{ {
change_input_mode(new InputModes::NextKey(*this, callback)); change_input_mode(new InputModes::NextKey(*this, keymap_mode, callback));
} }
static bool is_valid(Key key) static bool is_valid(Key key)

View File

@ -33,6 +33,7 @@ using KeyCallback = std::function<void (Key, Context&)>;
class InputMode; class InputMode;
class DisplayLine; class DisplayLine;
enum class InsertMode : unsigned; enum class InsertMode : unsigned;
enum class KeymapMode : int;
class InputHandler : public SafeCountable class InputHandler : public SafeCountable
{ {
@ -62,7 +63,7 @@ public:
// execute callback on next keypress and returns to normal mode // execute callback on next keypress and returns to normal mode
// if callback does not change the mode itself // if callback does not change the mode itself
void on_next_key(KeyCallback callback); void on_next_key(KeymapMode mode, KeyCallback callback);
// process the given key // process the given key
void handle_key(Key key); void handle_key(Key key);

View File

@ -15,7 +15,9 @@ enum class KeymapMode : int
Normal, Normal,
Insert, Insert,
Prompt, Prompt,
Menu Menu,
Goto,
View,
}; };
class KeymapManager class KeymapManager

View File

@ -119,11 +119,12 @@ bool show_auto_info_ifn(const String& title, const String& info,
} }
template<typename Cmd> template<typename Cmd>
void on_next_key_with_autoinfo(const Context& context, Cmd cmd, void on_next_key_with_autoinfo(const Context& context, KeymapMode keymap_mode, Cmd cmd,
const String& title, const String& info) const String& title, const String& info)
{ {
const bool hide = show_auto_info_ifn(title, info, context); const bool hide = show_auto_info_ifn(title, info, context);
context.input_handler().on_next_key([hide,cmd](Key key, Context& context) mutable { context.input_handler().on_next_key(
keymap_mode, [hide,cmd](Key key, Context& context) mutable {
if (hide) if (hide)
context.ui().info_hide(); context.ui().info_hide();
cmd(key, context); cmd(key, context);
@ -142,7 +143,8 @@ void goto_commands(Context& context, int line)
} }
else else
{ {
on_next_key_with_autoinfo(context, [](Key key, Context& context) { on_next_key_with_autoinfo(context, KeymapMode::Goto,
[](Key key, Context& context) {
if (key.modifiers != Key::Modifiers::None) if (key.modifiers != Key::Modifiers::None)
return; return;
auto& buffer = context.buffer(); auto& buffer = context.buffer();
@ -260,7 +262,8 @@ void goto_commands(Context& context, int line)
void view_commands(Context& context, int param) void view_commands(Context& context, int param)
{ {
on_next_key_with_autoinfo(context, [param](Key key, Context& context) { on_next_key_with_autoinfo(context, KeymapMode::View,
[param](Key key, Context& context) {
if (key.modifiers != Key::Modifiers::None or not context.has_window()) if (key.modifiers != Key::Modifiers::None or not context.has_window())
return; return;
@ -303,7 +306,8 @@ void view_commands(Context& context, int param)
void replace_with_char(Context& context, int) void replace_with_char(Context& context, int)
{ {
on_next_key_with_autoinfo(context, [](Key key, Context& context) { on_next_key_with_autoinfo(context, KeymapMode::None,
[](Key key, Context& context) {
if (not iswprint(key.key)) if (not iswprint(key.key))
return; return;
ScopedEdition edition(context); ScopedEdition edition(context);
@ -829,7 +833,8 @@ template<ObjectFlags flags, SelectMode mode = SelectMode::Replace>
void select_object(Context& context, int param) void select_object(Context& context, int param)
{ {
int level = param <= 0 ? 0 : param - 1; int level = param <= 0 ? 0 : param - 1;
on_next_key_with_autoinfo(context, [level](Key key, Context& context) { on_next_key_with_autoinfo(context, KeymapMode::None,
[level](Key key, Context& context) {
if (key.modifiers != Key::Modifiers::None) if (key.modifiers != Key::Modifiers::None)
return; return;
const Codepoint c = key.key; const Codepoint c = key.key;
@ -957,7 +962,8 @@ constexpr bool operator&(SelectFlags lhs, SelectFlags rhs)
template<SelectFlags flags> template<SelectFlags flags>
void select_to_next_char(Context& context, int param) void select_to_next_char(Context& context, int param)
{ {
on_next_key_with_autoinfo(context, [param](Key key, Context& context) { on_next_key_with_autoinfo(context, KeymapMode::None,
[param](Key key, Context& context) {
select<flags & SelectFlags::Extend ? SelectMode::Extend : SelectMode::Replace>( select<flags & SelectFlags::Extend ? SelectMode::Extend : SelectMode::Replace>(
context, context,
std::bind(flags & SelectFlags::Reverse ? select_to_reverse : select_to, std::bind(flags & SelectFlags::Reverse ? select_to_reverse : select_to,
@ -970,7 +976,8 @@ void start_or_end_macro_recording(Context& context, int)
if (context.input_handler().is_recording()) if (context.input_handler().is_recording())
context.input_handler().stop_recording(); context.input_handler().stop_recording();
else else
on_next_key_with_autoinfo(context, [](Key key, Context& context) { on_next_key_with_autoinfo(context, KeymapMode::None,
[](Key key, Context& context) {
if (key.modifiers == Key::Modifiers::None and isalpha(key.key)) if (key.modifiers == Key::Modifiers::None and isalpha(key.key))
context.input_handler().start_recording(tolower(key.key)); context.input_handler().start_recording(tolower(key.key));
}, "record macro", "enter macro name "); }, "record macro", "enter macro name ");
@ -984,7 +991,8 @@ void end_macro_recording(Context& context, int)
void replay_macro(Context& context, int count) void replay_macro(Context& context, int count)
{ {
on_next_key_with_autoinfo(context, [count](Key key, Context& context) mutable { on_next_key_with_autoinfo(context, KeymapMode::None,
[count](Key key, Context& context) mutable {
if (key.modifiers == Key::Modifiers::None and isalpha(key.key)) if (key.modifiers == Key::Modifiers::None and isalpha(key.key))
{ {
static std::unordered_set<char> running_macros; static std::unordered_set<char> running_macros;