From c54e6738b911e5de86dfe94b9166df86751aacb1 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 5 Oct 2015 01:25:23 +0100 Subject: [PATCH] Use DisplayLine for menu choices --- src/commands.cc | 4 ++-- src/input_handler.cc | 30 +++++++++++++++++++++--------- src/input_handler.hh | 2 +- src/insert_completer.cc | 4 ++-- src/main.cc | 3 ++- src/ncurses_ui.cc | 40 ++++++++++++++++++++-------------------- src/ncurses_ui.hh | 6 ++---- src/remote.cc | 6 +++--- src/user_interface.hh | 2 +- 9 files changed, 54 insertions(+), 43 deletions(-) diff --git a/src/commands.cc b/src/commands.cc index 14a0353b..08af1efd 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -1406,12 +1406,12 @@ const CommandDesc menu_cmd = { return; } - Vector choices; + Vector choices; Vector commands; Vector select_cmds; for (int i = 0; i < count; i += modulo) { - choices.push_back(parser[i]); + choices.push_back({ parser[i], {} }); commands.push_back(parser[i+1]); if (with_select_cmds) select_cmds.push_back(parser[i+2]); diff --git a/src/input_handler.cc b/src/input_handler.cc index d5d44378..435d9d89 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -464,7 +464,7 @@ private: class Menu : public InputMode { public: - Menu(InputHandler& input_handler, ConstArrayView choices, + Menu(InputHandler& input_handler, ConstArrayView choices, MenuCallback callback) : InputMode(input_handler), m_callback(callback), m_choices(choices.begin(), choices.end()), @@ -479,8 +479,14 @@ public: void on_key(Key key, KeepAlive keep_alive) override { - auto match_filter = [this](const String& str) { - return regex_match(str.begin(), str.end(), m_filter); + 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 == ctrl('m')) @@ -564,7 +570,7 @@ public: private: MenuCallback m_callback; - using ChoiceList = Vector; + using ChoiceList = Vector; const ChoiceList m_choices; ChoiceList::const_iterator m_selected; @@ -823,10 +829,16 @@ private: const String& line = m_line_editor.line(); m_completions = m_completer(context(), flags, line, line.byte_count_to(m_line_editor.cursor_pos())); - CandidateList& candidates = m_completions.candidates; - if (context().has_ui() and not candidates.empty()) - context().ui().menu_show(candidates, CharCoord{}, get_face("MenuForeground"), - get_face("MenuBackground"), MenuStyle::Prompt); + if (context().has_ui() and not m_completions.candidates.empty()) + { + Vector items; + for (auto& candidate : m_completions.candidates) + items.push_back({ candidate, {} }); + context().ui().menu_show(items, CharCoord{}, + get_face("MenuForeground"), + get_face("MenuBackground"), + MenuStyle::Prompt); + } } catch (runtime_error&) {} } @@ -1280,7 +1292,7 @@ void InputHandler::set_prompt_face(Face prompt_face) prompt->set_prompt_face(prompt_face); } -void InputHandler::menu(ConstArrayView choices, MenuCallback callback) +void InputHandler::menu(ConstArrayView choices, MenuCallback callback) { push_mode(new InputModes::Menu(*this, choices, callback)); } diff --git a/src/input_handler.hh b/src/input_handler.hh index 4b4e325f..025f8979 100644 --- a/src/input_handler.hh +++ b/src/input_handler.hh @@ -62,7 +62,7 @@ public: // abort or validation with corresponding MenuEvent value // returns to normal mode after validation if callback does // not change the mode itself - void menu(ArrayView choices, MenuCallback callback); + void menu(ConstArrayView choices, MenuCallback callback); // execute callback on next keypress and returns to normal mode // if callback does not change the mode itself diff --git a/src/insert_completer.cc b/src/insert_completer.cc index 9ee00d14..b577c119 100644 --- a/src/insert_completer.cc +++ b/src/insert_completer.cc @@ -421,13 +421,13 @@ void InsertCompleter::menu_show() const CharCount tabstop = m_options["tabstop"].get(); const CharCount column = get_column(m_context.buffer(), tabstop, m_completions.begin); - Vector menu_entries; + Vector menu_entries; for (auto& candidate : m_matching_candidates) { const String& entry = candidate.menu_entry.empty() ? candidate.completion : candidate.menu_entry; - menu_entries.push_back(expand_tabs(entry, tabstop, column)); + menu_entries.push_back({ expand_tabs(entry, tabstop, column), {} }); } m_context.ui().menu_show(menu_entries, menu_pos, diff --git a/src/main.cc b/src/main.cc index 6fb68265..fbf61fbf 100644 --- a/src/main.cc +++ b/src/main.cc @@ -246,7 +246,8 @@ std::unique_ptr create_local_ui(bool dummy_ui) { struct DummyUI : UserInterface { - void menu_show(ConstArrayView, CharCoord, Face, Face, MenuStyle) override {} + void menu_show(ConstArrayView, CharCoord, + Face, Face, MenuStyle) override {} void menu_select(int) override {} void menu_hide() override {} diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc index 214d7245..5337f32e 100644 --- a/src/ncurses_ui.cc +++ b/src/ncurses_ui.cc @@ -338,28 +338,29 @@ void add_str(WINDOW* win, StringView str) waddnstr(win, str.begin(), (int)str.length()); } -void NCursesUI::draw_line(const DisplayLine& line, CharCount col_index, - const Face& default_face) const +static void draw_line(NCursesWin* window, const DisplayLine& line, + CharCount col_index, CharCount max_column, + const Face& default_face) { for (const DisplayAtom& atom : line) { - set_face(m_window, atom.face, default_face); + set_face(window, atom.face, default_face); StringView content = atom.content(); if (content.empty()) continue; - const auto remaining_columns = m_dimensions.column - col_index; + const auto remaining_columns = max_column - col_index; if (content.back() == '\n' and content.char_length() - 1 < remaining_columns) { - add_str(m_window, content.substr(0, content.length()-1)); - waddch(m_window, ' '); + add_str(window, content.substr(0, content.length()-1)); + waddch(window, ' '); } else { content = content.substr(0_char, remaining_columns); - add_str(m_window, content); + add_str(window, content); col_index += content.char_length(); } } @@ -377,7 +378,7 @@ void NCursesUI::draw(const DisplayBuffer& display_buffer, { wmove(m_window, (int)line_index, 0); wclrtoeol(m_window); - draw_line(line, 0, default_face); + draw_line(m_window, line, 0, m_dimensions.column, default_face); ++line_index; } @@ -402,7 +403,7 @@ void NCursesUI::draw_status(const DisplayLine& status_line, wbkgdset(m_window, COLOR_PAIR(get_color_pair(default_face))); wclrtoeol(m_window); - draw_line(status_line, 0, default_face); + draw_line(m_window, status_line, 0, m_dimensions.column, default_face); const auto mode_len = mode_line.length(); const auto remaining = m_dimensions.column - status_line.length(); @@ -410,7 +411,7 @@ void NCursesUI::draw_status(const DisplayLine& status_line, { CharCount col = m_dimensions.column - mode_len; wmove(m_window, status_line_pos, (int)col); - draw_line(mode_line, col, default_face); + draw_line(m_window, mode_line, col, m_dimensions.column, default_face); } else if (remaining > 2) { @@ -421,7 +422,7 @@ void NCursesUI::draw_status(const DisplayLine& status_line, CharCount col = m_dimensions.column - remaining + 1; wmove(m_window, status_line_pos, (int)col); - draw_line(trimmed_mode_line, col, default_face); + draw_line(m_window, trimmed_mode_line, col, m_dimensions.column, default_face); } if (m_set_title) @@ -620,14 +621,12 @@ void NCursesUI::draw_menu() + col; if (item_idx >= item_count) break; - if (item_idx == m_selected_item) - wattron(m_menu.win, COLOR_PAIR(menu_fg)); - StringView item = m_items[item_idx].substr(0_char, column_width); - add_str(m_menu.win, item); - const CharCount pad = column_width - item.char_length(); + const DisplayLine& item = m_items[item_idx]; + draw_line(m_menu.win, item, 0, column_width, + item_idx == m_selected_item ? m_menu_fg : m_menu_bg); + const CharCount pad = column_width - item.length(); add_str(m_menu.win, String{' ' COMMA pad}); - wattron(m_menu.win, COLOR_PAIR(menu_bg)); } const bool is_mark = line >= mark_line and line < mark_line + mark_height; @@ -639,7 +638,7 @@ void NCursesUI::draw_menu() m_dirty = true; } -void NCursesUI::menu_show(ConstArrayView items, +void NCursesUI::menu_show(ConstArrayView items, CharCoord anchor, Face fg, Face bg, MenuStyle style) { @@ -664,8 +663,9 @@ void NCursesUI::menu_show(ConstArrayView items, const CharCount maxlen = min((int)maxsize.column-2, 200); for (auto& item : items) { - m_items.push_back(item.substr(0_char, maxlen).str()); - longest = max(longest, m_items.back().char_length()); + m_items.push_back(item); + m_items.back().trim(0, maxlen, false); + longest = max(longest, m_items.back().length()); } longest += 1; diff --git a/src/ncurses_ui.hh b/src/ncurses_ui.hh index e2c804e6..e8759660 100644 --- a/src/ncurses_ui.hh +++ b/src/ncurses_ui.hh @@ -31,7 +31,7 @@ public: bool is_key_available() override; Key get_key() override; - void menu_show(ConstArrayView items, + void menu_show(ConstArrayView items, CharCoord anchor, Face fg, Face bg, MenuStyle style) override; void menu_select(int selected) override; @@ -54,8 +54,6 @@ public: private: void check_resize(bool force = false); void redraw(); - void draw_line(const DisplayLine& line, CharCount col_index, - const Face& default_face) const; NCursesWin* m_window = nullptr; @@ -77,7 +75,7 @@ private: void mark_dirty(const Window& win); Window m_menu; - Vector m_items; + Vector m_items; Face m_menu_fg; Face m_menu_bg; int m_selected_item = 0; diff --git a/src/remote.cc b/src/remote.cc index 0592d0a3..d4a84aa7 100644 --- a/src/remote.cc +++ b/src/remote.cc @@ -237,7 +237,7 @@ public: RemoteUI(int socket); ~RemoteUI(); - void menu_show(ConstArrayView choices, + void menu_show(ConstArrayView choices, CharCoord anchor, Face fg, Face bg, MenuStyle style) override; void menu_select(int selected) override; @@ -287,7 +287,7 @@ RemoteUI::~RemoteUI() m_socket_watcher.close_fd(); } -void RemoteUI::menu_show(ConstArrayView choices, +void RemoteUI::menu_show(ConstArrayView choices, CharCoord anchor, Face fg, Face bg, MenuStyle style) { @@ -468,7 +468,7 @@ void RemoteClient::process_next_message() { case RemoteUIMsg::MenuShow: { - auto choices = read_vector(socket); + auto choices = read_vector(socket); auto anchor = read(socket); auto fg = read(socket); auto bg = read(socket); diff --git a/src/user_interface.hh b/src/user_interface.hh index daae4f9d..67553922 100644 --- a/src/user_interface.hh +++ b/src/user_interface.hh @@ -41,7 +41,7 @@ class UserInterface : public SafeCountable public: virtual ~UserInterface() {} - virtual void menu_show(ConstArrayView choices, + virtual void menu_show(ConstArrayView choices, CharCoord anchor, Face fg, Face bg, MenuStyle style) = 0; virtual void menu_select(int selected) = 0;