Make on_next_key_with_autoinfo() respect idle_timeout

The prompt and autocomplete normally wait for `idle_timeout` before showing
suggestions, however commands like `g`, `v`, or the lead-key show Clippy
instantly.

This fixes the issue by making `on_next_key_with_autoinfo()` wait for
`idle_timeout` before displaying suggestions.

Fixes mawww/kakoune#3365
Fixes mawww/kakoune#2066
This commit is contained in:
Nicolas Ouellet-Payeur 2020-02-27 10:36:15 -05:00 committed by Nicolas Ouellet-payeur
parent 97e5e75d4c
commit 10d887583f
4 changed files with 33 additions and 17 deletions

View File

@ -45,6 +45,7 @@ enum class Hook
RuntimeError, RuntimeError,
PromptIdle, PromptIdle,
NormalIdle, NormalIdle,
NextKeyIdle,
NormalKey, NormalKey,
ModeChange, ModeChange,
RawKey, RawKey,
@ -87,6 +88,7 @@ constexpr auto enum_desc(Meta::Type<Hook>)
{Hook::RuntimeError, "RuntimeError"}, {Hook::RuntimeError, "RuntimeError"},
{Hook::PromptIdle, "PromptIdle"}, {Hook::PromptIdle, "PromptIdle"},
{Hook::NormalIdle, "NormalIdle"}, {Hook::NormalIdle, "NormalIdle"},
{Hook::NextKeyIdle, "NextKeyIdle"},
{Hook::NormalKey, "NormalKey"}, {Hook::NormalKey, "NormalKey"},
{Hook::ModeChange, "ModeChange"}, {Hook::ModeChange, "ModeChange"},
{Hook::RawKey, "RawKey"}, {Hook::RawKey, "RawKey"},

View File

@ -273,7 +273,7 @@ public:
context.print_status( context.print_status(
{ format("invalid register '{}'", *cp), { format("invalid register '{}'", *cp),
context.faces()["Error"] }); context.faces()["Error"] });
}, "enter target register", register_doc); }, "enter target register", register_doc.str());
} }
else else
{ {
@ -817,7 +817,7 @@ public:
display(); display();
m_line_changed = true; m_line_changed = true;
m_refresh_completion_pending = true; m_refresh_completion_pending = true;
}, "enter register name", register_doc); }, "enter register name", register_doc.str());
display(); display();
return; return;
} }
@ -1100,8 +1100,10 @@ private:
class NextKey : public InputMode class NextKey : public InputMode
{ {
public: public:
NextKey(InputHandler& input_handler, String name, KeymapMode keymap_mode, KeyCallback callback) NextKey(InputHandler& input_handler, String name, KeymapMode keymap_mode, KeyCallback callback,
: InputMode(input_handler), m_name{std::move(name)}, m_callback(std::move(callback)), m_keymap_mode(keymap_mode) {} Timer::Callback idle_callback)
: InputMode(input_handler), m_name{std::move(name)}, m_callback(std::move(callback)), m_keymap_mode(keymap_mode),
m_idle_timer{Clock::now() + get_idle_timeout(context()), std::move(idle_callback)} {}
void on_key(Key key) override void on_key(Key key) override
{ {
@ -1122,9 +1124,10 @@ public:
StringView name() const override { return m_name; } StringView name() const override { return m_name; }
private: private:
String m_name; String m_name;
KeyCallback m_callback; KeyCallback m_callback;
KeymapMode m_keymap_mode; KeymapMode m_keymap_mode;
Timer m_idle_timer;
}; };
class Insert : public InputMode class Insert : public InputMode
@ -1274,7 +1277,7 @@ public:
if (not cp or key == Key::Escape) if (not cp or key == Key::Escape)
return; return;
insert(RegisterManager::instance()[*cp].get(context())); insert(RegisterManager::instance()[*cp].get(context()));
}, "enter register name", register_doc); }, "enter register name", register_doc.str());
update_completions = false; update_completions = false;
} }
else if (key == ctrl('n')) else if (key == ctrl('n'))
@ -1588,9 +1591,11 @@ void InputHandler::menu(Vector<DisplayLine> choices, MenuCallback callback)
push_mode(new InputModes::Menu(*this, std::move(choices), std::move(callback))); push_mode(new InputModes::Menu(*this, std::move(choices), std::move(callback)));
} }
void InputHandler::on_next_key(StringView mode_name, KeymapMode keymap_mode, KeyCallback callback) void InputHandler::on_next_key(StringView mode_name, KeymapMode keymap_mode, KeyCallback callback,
Timer::Callback idle_callback)
{ {
push_mode(new InputModes::NextKey(*this, format("next-key[{}]", mode_name), keymap_mode, std::move(callback))); push_mode(new InputModes::NextKey(*this, format("next-key[{}]", mode_name), keymap_mode, std::move(callback),
std::move(idle_callback)));
} }
InputHandler::ScopedForceNormal::ScopedForceNormal(InputHandler& handler, NormalParams params) InputHandler::ScopedForceNormal::ScopedForceNormal(InputHandler& handler, NormalParams params)
@ -1706,10 +1711,14 @@ std::pair<CursorMode, DisplayCoord> InputHandler::get_cursor_info() const
return current_mode().get_cursor_info(); return current_mode().get_cursor_info();
} }
bool should_show_info(AutoInfo mask, const Context& context)
{
return (context.options()["autoinfo"].get<AutoInfo>() & mask) and context.has_client();
}
bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context) bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context)
{ {
if (not (context.options()["autoinfo"].get<AutoInfo>() & mask) or if (not should_show_info(mask, context))
not context.has_client())
return false; return false;
context.client().info_show(title.str(), info.str(), {}, InfoStyle::Prompt); context.client().info_show(title.str(), info.str(), {}, InfoStyle::Prompt);

View File

@ -11,6 +11,7 @@
#include "utils.hh" #include "utils.hh"
#include "safe_ptr.hh" #include "safe_ptr.hh"
#include "display_buffer.hh" #include "display_buffer.hh"
#include "event_manager.hh"
namespace Kakoune namespace Kakoune
{ {
@ -80,7 +81,8 @@ 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(StringView mode_name, KeymapMode mode, KeyCallback callback); void on_next_key(StringView mode_name, KeymapMode mode, KeyCallback callback,
Timer::Callback idle_callback = Timer::Callback{});
// process the given key // process the given key
void handle_key(Key key); void handle_key(Key key);
@ -171,19 +173,22 @@ constexpr auto enum_desc(Meta::Type<AutoComplete>)
}); });
} }
bool should_show_info(AutoInfo mask, const Context& context);
bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context); bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context);
void hide_auto_info_ifn(const Context& context, bool hide); void hide_auto_info_ifn(const Context& context, bool hide);
template<typename Cmd> template<typename Cmd>
void on_next_key_with_autoinfo(const Context& context, StringView mode_name, void on_next_key_with_autoinfo(const Context& context, StringView mode_name,
KeymapMode keymap_mode, Cmd cmd, KeymapMode keymap_mode, Cmd cmd,
StringView title, StringView info) String title, String info)
{ {
const bool hide = show_auto_info_ifn(title, info, AutoInfo::OnKey, context);
context.input_handler().on_next_key(mode_name, context.input_handler().on_next_key(mode_name,
keymap_mode, [hide,cmd](Key key, Context& context) mutable { keymap_mode, [cmd](Key key, Context& context) mutable {
bool hide = should_show_info(AutoInfo::OnKey, context);
hide_auto_info_ifn(context, hide); hide_auto_info_ifn(context, hide);
cmd(key, context); cmd(key, context);
}, [&context, title=std::move(title), info=std::move(info)](Timer&) {
show_auto_info_ifn(title, info, AutoInfo::OnKey, context);
}); });
} }

View File

@ -1881,7 +1881,7 @@ void combine_selections(Context& context, SelectionList list, Func func, StringV
list.set_main_index(sels.main_index()); list.set_main_index(sels.main_index());
} }
func(context, std::move(list)); func(context, std::move(list));
}, title, }, title.str(),
"'a': append lists\n" "'a': append lists\n"
"'u': union\n" "'u': union\n"
"'i': intersection\n" "'i': intersection\n"