Add support for mapping keys in goto/view commands
This commit is contained in:
parent
858132e771
commit
4c4d3cdd38
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -15,7 +15,9 @@ enum class KeymapMode : int
|
||||||
Normal,
|
Normal,
|
||||||
Insert,
|
Insert,
|
||||||
Prompt,
|
Prompt,
|
||||||
Menu
|
Menu,
|
||||||
|
Goto,
|
||||||
|
View,
|
||||||
};
|
};
|
||||||
|
|
||||||
class KeymapManager
|
class KeymapManager
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user