From ee4c6b04a6e3823cb8b4bf858aa2d08270d6cc3a Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 11 Sep 2012 14:27:21 +0200 Subject: [PATCH] Support Shift-Tab in prompt mode to go back in completions --- src/client.cc | 56 +++++++++++++++++++++++++------------------------- src/keys.hh | 1 + src/ncurses.cc | 1 + 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/client.cc b/src/client.cc index ccefbf76..d62842f7 100644 --- a/src/client.cc +++ b/src/client.cc @@ -107,9 +107,10 @@ private: class Client::PromptMode : public Client::Mode { public: - PromptMode(Client& client, const String& prompt, Completer completer, PromptCallback callback) - : Client::Mode(client), - m_prompt(prompt), m_completer(completer), m_callback(callback), m_cursor_pos(0) + PromptMode(Client& client, const String& prompt, + Completer completer, PromptCallback callback) + : Client::Mode(client), m_prompt(prompt), + m_completer(completer), m_callback(callback) { m_history_it = ms_history[m_prompt].end(); m_client.print_status(m_prompt, m_prompt.length()); @@ -135,6 +136,8 @@ public: PromptCallback callback = std::move(m_callback); String result = std::move(m_result); m_client.reset_normal_mode(); + // call callback after reset_normal_mode so that callback + // may change the mode callback(result, context); return; } @@ -217,40 +220,36 @@ public: String reg = RegisterManager::instance()[k.key].values(context)[0]; m_client.menu_hide(); m_current_completion = -1; - m_result = m_result.substr(0, m_cursor_pos) + reg + m_result.substr(m_cursor_pos, String::npos); + m_result = m_result.substr(0, m_cursor_pos) + reg + + m_result.substr(m_cursor_pos, String::npos); m_cursor_pos += reg.length(); } - else if (key == Key(Key::Modifiers::Control, 'i')) // tab + else if (key == Key(Key::Modifiers::Control, 'i') or // tab + key == Key::BackTab) { + const bool reverse = (key == Key::BackTab); + const CandidateList& candidates = m_completions.candidates; if (m_current_completion == -1) { m_completions = m_completer(context, m_result, m_cursor_pos); - if (m_completions.candidates.empty()) + if (candidates.empty()) return; m_client.menu_hide(); - m_client.menu_show(m_completions.candidates); - m_text_before_completion = m_result.substr(m_completions.start, - m_completions.end - m_completions.start); + m_client.menu_show(candidates); + m_completion_prefix = m_result.substr(m_completions.start, + m_completions.end - m_completions.start); + m_completion_count = contains(candidates, m_completion_prefix) ? + (int)candidates.size() : (int)candidates.size() + 1; } - ++m_current_completion; + m_current_completion += reverse ? -1 : 1; + if (m_current_completion >= m_completion_count) + m_current_completion = 0; + else if (m_current_completion < 0) + m_current_completion = m_completion_count-1; - String completion; - if (m_current_completion >= m_completions.candidates.size()) - { - if (m_current_completion == m_completions.candidates.size() and - std::find(m_completions.candidates.begin(), m_completions.candidates.end(), m_text_before_completion) == m_completions.candidates.end()) - { - completion = m_text_before_completion; - } - else - { - m_current_completion = 0; - completion = m_completions.candidates[0]; - } - } - else - completion = m_completions.candidates[m_current_completion]; + String completion = (m_current_completion == candidates.size()) ? + m_completion_prefix : candidates[m_current_completion]; m_client.menu_select(m_current_completion); m_result = m_result.substr(0, m_completions.start) + completion; @@ -270,10 +269,11 @@ private: PromptCallback m_callback; Completer m_completer; const String m_prompt; - CharCount m_cursor_pos; + CharCount m_cursor_pos = 0; Completions m_completions; + int m_completion_count = 0; int m_current_completion = -1; - String m_text_before_completion; + String m_completion_prefix; String m_result; String m_saved_result; diff --git a/src/keys.hh b/src/keys.hh index cb3acc67..788a25bd 100644 --- a/src/keys.hh +++ b/src/keys.hh @@ -26,6 +26,7 @@ struct Key Right, PageUp, PageDown, + BackTab, }; Modifiers modifiers; diff --git a/src/ncurses.cc b/src/ncurses.cc index ec435811..3f2f7990 100644 --- a/src/ncurses.cc +++ b/src/ncurses.cc @@ -189,6 +189,7 @@ Key NCursesClient::get_key() case KEY_RIGHT: return Key::Right; case KEY_PPAGE: return Key::PageUp; case KEY_NPAGE: return Key::PageDown; + case KEY_BTAB: return Key::BackTab; } return c; }