commit 25173a934a2b431150fdb3c43d704a794c213a4b Author: Sambuddha Basu sambuddhabasu1@gmail.com Date: Thu Jul 14 07:44:13 2016 -0700
Updated str_input functions --- nyx/curses.py | 146 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 75 insertions(+), 71 deletions(-)
diff --git a/nyx/curses.py b/nyx/curses.py index 48f015e..b4c34f2 100644 --- a/nyx/curses.py +++ b/nyx/curses.py @@ -149,6 +149,8 @@ SPECIAL_KEYS = {
Dimensions = collections.namedtuple('Dimensions', ['width', 'height'])
+HISTORY_DICT = {'selection_index': -1, 'custom_input': ''} +
def conf_handler(key, value): if key == 'features.colorOverride': @@ -245,101 +247,103 @@ def key_input(input_timeout = None): return KeyInput(CURSES_SCREEN.getch())
-def str_input(x, y, initial_text = '', backlog=None, tab_completion=None): - """ - Provides a text field where the user can input a string, blocking until - they've done so and returning the result. If the user presses escape then - this terminates and provides back **None**. +def str_input_handle_key(textbox, key): + y, x = textbox.win.getyx()
- This blanks any content within the space that the input field is rendered - (otherwise stray characters would be interpreted as part of the initial - input). + if key == 27: + return curses.ascii.BEL # user pressed esc + elif key == curses.KEY_HOME: + textbox.win.move(y, 0) + elif key in (curses.KEY_END, curses.KEY_RIGHT): + msg_length = len(textbox.gather()) + textbox.win.move(y, x) # reverts cursor movement during gather call
- :param int x: horizontal location - :param int y: vertical location - :param str initial_text: initial input of the field + if key == curses.KEY_END and msg_length > 0 and x < msg_length - 1: + textbox.win.move(y, msg_length - 1) # if we're in the content then move to the end + elif key == curses.KEY_RIGHT and x < msg_length - 1: + textbox.win.move(y, x + 1) # only move cursor if there's content after it + elif key == 410: + # if we're resizing the display during text entry then cancel it + # (otherwise the input field is filled with nonprintable characters)
- :returns: **str** with the user input or **None** if the prompt is caneled - """ + return curses.ascii.BEL + else: + return key + + +def str_input_handle_history_key(textbox, key, backlog): + global HISTORY_DICT + if key in (curses.KEY_UP, curses.KEY_DOWN): + offset = 1 if key == curses.KEY_UP else -1 + new_selection = HISTORY_DICT['selection_index'] + offset
- def handle_key(textbox, key): - y, x = textbox.win.getyx() + new_selection = max(-1, new_selection) + new_selection = min(len(backlog) - 1, new_selection)
- if key == 27: - return curses.ascii.BEL # user pressed esc - elif key == curses.KEY_HOME: - textbox.win.move(y, 0) - elif key in (curses.KEY_END, curses.KEY_RIGHT): - msg_length = len(textbox.gather()) - textbox.win.move(y, x) # reverts cursor movement during gather call + if HISTORY_DICT['selection_index'] == new_selection: + return None
- if key == curses.KEY_END and msg_length > 0 and x < msg_length - 1: - textbox.win.move(y, msg_length - 1) # if we're in the content then move to the end - elif key == curses.KEY_RIGHT and x < msg_length - 1: - textbox.win.move(y, x + 1) # only move cursor if there's content after it - elif key == 410: - # if we're resizing the display during text entry then cancel it - # (otherwise the input field is filled with nonprintable characters) + if HISTORY_DICT['selection_index'] == -1: + HISTORY_DICT['custom_input'] = textbox.gather().strip()
- return curses.ascii.BEL + if new_selection == -1: + new_input = HISTORY_DICT['custom_input'] else: - return key + new_input = backlog[new_selection]
- history_dict = {'selection_index': -1, 'custom_input': ''} + y, _ = textbox.win.getyx() + _, max_x = textbox.win.getmaxyx() + textbox.win.clear() + textbox.win.addstr(y, 0, new_input[:max_x - 1]) + textbox.win.move(y, min(len(new_input), max_x - 1))
- def handle_history_key(textbox, key): - if key in (curses.KEY_UP, curses.KEY_DOWN): - offset = 1 if key == curses.KEY_UP else -1 - new_selection = history_dict['selection_index'] + offset + HISTORY_DICT['selection_index'] = new_selection + return None
- new_selection = max(-1, new_selection) - new_selection = min(len(backlog) - 1, new_selection) + return str_input_handle_key(textbox, key)
- if history_dict['selection_index'] == new_selection: - return None
- if history_dict['selection_index'] == -1: - history_dict['custom_input'] = textbox.gather().strip() +def str_input_handle_tab_completion(textbox, key, backlog, tab_completion): + if key == 9: + current_contents = textbox.gather().strip() + matches = tab_completion(current_contents) + new_input = None
- if new_selection == -1: - new_input = history_dict['custom_input'] - else: - new_input = backlog[new_selection] + if len(matches) == 1: + new_input = matches[0] + elif len(matches) > 1: + common_prefix = os.path.commonprefix(matches) + if common_prefix != current_contents: + new_input = common_prefix
+ if new_input: y, _ = textbox.win.getyx() _, max_x = textbox.win.getmaxyx() textbox.win.clear() textbox.win.addstr(y, 0, new_input[:max_x - 1]) textbox.win.move(y, min(len(new_input), max_x - 1))
- history_dict['selection_index'] = new_selection - return None + return None
- return handle_key(textbox, key) + return str_input_handle_history_key(textbox, key, backlog)
- def handle_tab_completion(textbox, key): - if key == 9: - current_contents = textbox.gather().strip() - matches = tab_completion(current_contents) - new_input = None
- if len(matches) == 1: - new_input = matches[0] - elif len(matches) > 1: - common_prefix = os.path.commonprefix(matches) - if common_prefix != current_contents: - new_input = common_prefix +def str_input(x, y, initial_text = '', backlog=None, tab_completion=None): + """ + Provides a text field where the user can input a string, blocking until + they've done so and returning the result. If the user presses escape then + this terminates and provides back **None**.
- if new_input: - y, _ = textbox.win.getyx() - _, max_x = textbox.win.getmaxyx() - textbox.win.clear() - textbox.win.addstr(y, 0, new_input[:max_x - 1]) - textbox.win.move(y, min(len(new_input), max_x - 1)) + This blanks any content within the space that the input field is rendered + (otherwise stray characters would be interpreted as part of the initial + input).
- return None + :param int x: horizontal location + :param int y: vertical location + :param str initial_text: initial input of the field
- return handle_history_key(textbox, key) + :returns: **str** with the user input or **None** if the prompt is caneled + """
with CURSES_LOCK: if HALT_ACTIVITY: @@ -358,11 +362,11 @@ def str_input(x, y, initial_text = '', backlog=None, tab_completion=None):
textbox = curses.textpad.Textbox(curses_subwindow, insert_mode = True) if tab_completion is not None: - user_input = textbox.edit(lambda key: handle_tab_completion(textbox, key)).strip() + user_input = textbox.edit(lambda key: str_input_handle_tab_completion(textbox, key, backlog, tab_completion)).strip() elif backlog is not None: - user_input = textbox.edit(lambda key: handle_history_key(textbox, key)).strip() + user_input = textbox.edit(lambda key: str_input_handle_history_key(textbox, key, backlog)).strip() else: - user_input = textbox.edit(lambda key: handle_key(textbox, key)).strip() + user_input = textbox.edit(lambda key: str_input_handle_key(textbox, key)).strip()
try: curses.curs_set(0) # hide cursor
tor-commits@lists.torproject.org