From 1f11529837c69781179c7deea832f0b8b266305f Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Mon, 20 Nov 2023 20:02:36 +0100 Subject: rc tools menu: replace menu builtin with a prompt-based implementation prompt has fuzzy filtering which is more discoverable than the menu mode's regex filtering (because that one needs / to trigger it). There are no important differences left, so replace the menu builtin with a prompt-based command. prompt does not support markup in the completion menu, so drop that feature for now. --- src/input_handler.cc | 142 --------------------------------------------------- 1 file changed, 142 deletions(-) (limited to 'src/input_handler.cc') diff --git a/src/input_handler.cc b/src/input_handler.cc index 9bc495a2..dc9cd35e 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -632,143 +632,6 @@ private: const FaceRegistry& m_faces; }; -class Menu : public InputMode -{ -public: - Menu(InputHandler& input_handler, Vector choices, - MenuCallback callback) - : InputMode(input_handler), - m_callback(std::move(callback)), m_choices(choices.begin(), choices.end()), - m_selected(m_choices.begin()), - m_filter_editor{context().faces()} - { - if (not context().has_client()) - return; - context().client().menu_show(std::move(choices), {}, MenuStyle::Prompt); - context().client().menu_select(0); - } - - void on_key(Key key, bool) override - { - auto match_filter = [this](const DisplayLine& choice) { - for (auto& atom : choice) - { - const auto& contents = atom.content(); - if (regex_match(contents.begin(), contents.end(), m_filter)) - return true; - } - return false; - }; - - if (key == Key::Return) - { - if (context().has_client()) - context().client().menu_hide(); - context().print_status(DisplayLine{}); - - // Maintain hooks disabled in callback if they were before pop_mode - ScopedSetBool disable_hooks(context().hooks_disabled(), - context().hooks_disabled()); - pop_mode(); - int selected = m_selected - m_choices.begin(); - m_callback(selected, MenuEvent::Validate, context()); - return; - } - else if (key == Key::Escape or key == ctrl('c')) - { - if (m_edit_filter) - { - m_edit_filter = false; - m_filter = Regex{".*"}; - m_filter_editor.reset("", ""); - context().print_status(DisplayLine{}); - } - else - { - if (context().has_client()) - context().client().menu_hide(); - - // Maintain hooks disabled in callback if they were before pop_mode - ScopedSetBool disable_hooks(context().hooks_disabled(), - context().hooks_disabled()); - pop_mode(); - int selected = m_selected - m_choices.begin(); - m_callback(selected, MenuEvent::Abort, context()); - } - } - else if (key == Key::Down or key == Key::Tab or - key == ctrl('n') or (not m_edit_filter and key == 'j')) - { - auto it = std::find_if(m_selected+1, m_choices.end(), match_filter); - if (it == m_choices.end()) - it = std::find_if(m_choices.begin(), m_selected, match_filter); - select(it); - } - else if (key == Key::Up or key == shift(Key::Tab) or - key == ctrl('p') or (not m_edit_filter and key == 'k')) - { - ChoiceList::const_reverse_iterator selected(m_selected+1); - auto it = std::find_if(selected+1, m_choices.rend(), match_filter); - if (it == m_choices.rend()) - it = std::find_if(m_choices.rbegin(), selected, match_filter); - select(it.base()-1); - } - else if (key == '/' and not m_edit_filter) - { - m_edit_filter = true; - } - else if (m_edit_filter) - { - m_filter_editor.handle_key(key); - - auto search = ".*" + m_filter_editor.line() + ".*"; - m_filter = Regex{search}; - auto it = std::find_if(m_selected, m_choices.end(), match_filter); - if (it == m_choices.end()) - it = std::find_if(m_choices.begin(), m_selected, match_filter); - select(it); - } - - if (m_edit_filter and context().has_client()) - { - auto prompt = "filter:"_str; - auto width = context().client().dimensions().column - prompt.column_length(); - auto display_line = m_filter_editor.build_display_line(width); - display_line.insert(display_line.begin(), { prompt, context().faces()["Prompt"] }); - context().print_status(display_line); - } - } - - DisplayLine mode_line() const override - { - return { "menu", context().faces()["StatusLineMode"] }; - } - - KeymapMode keymap_mode() const override { return KeymapMode::Menu; } - - StringView name() const override { return "menu"; } - -private: - MenuCallback m_callback; - - using ChoiceList = Vector; - const ChoiceList m_choices; - ChoiceList::const_iterator m_selected; - - void select(ChoiceList::const_iterator it) - { - m_selected = it; - int selected = m_selected - m_choices.begin(); - if (context().has_client()) - context().client().menu_select(selected); - m_callback(selected, MenuEvent::Select, context()); - } - - Regex m_filter = Regex{".*"}; - bool m_edit_filter = false; - LineEditor m_filter_editor; -}; - static Optional get_raw_codepoint(Key key) { if (auto cp = key.codepoint()) @@ -1744,11 +1607,6 @@ void InputHandler::set_prompt_face(Face prompt_face) prompt->set_prompt_face(prompt_face); } -void InputHandler::menu(Vector choices, MenuCallback 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, Timer::Callback idle_callback) { -- cgit v1.2.3