diff --git a/src/class_cursor.py b/src/class_cursor.py index b0016db..c919324 100644 --- a/src/class_cursor.py +++ b/src/class_cursor.py @@ -194,8 +194,16 @@ def _multiselect_to(self, position: int, max_len: int) -> None: continue self.multiselect_up() - def multiselect_from( - self, stdscr: curses.window, first_digit: int, max_len: int + def _set_to_clamp(self, position: int, max_len: int) -> None: + """Set the current position to the given position if between 0 and maxlen""" + self.set_to(clamp(position, 0, max_len)) + + def relative_to( + self, + stdscr: curses.window, + first_digit: int, + max_len: int, + single: bool, ) -> None: """ Move the cursor to the specified position relative to the current position. @@ -210,56 +218,25 @@ def multiselect_from( key = stdscr.getch() except KeyboardInterrupt: # exit on ^C return - if key != Key.escape: # not an escape sequence - return - stdscr.nodelay(True) - subch = stdscr.getch() # alt + ... - stdscr.nodelay(False) - if subch == Key.k: - self._multiselect_to(self.positions[0] - int(total), max_len) - elif subch == Key.j: - self._multiselect_to(self.positions[0] + int(total), max_len) - elif subch in Key.digits(): - total += str(Key.normalize_ascii_digit_to_digit(subch)) + operation = self._set_to_clamp + if not single: + operation = self._multiselect_to + if key != Key.escape: # not an escape sequence + return + stdscr.nodelay(True) + key = stdscr.getch() # alt + ... + stdscr.nodelay(False) + if key == Key.k: + operation(self.positions[0] - int(total), max_len) + elif key == Key.j: + operation(self.positions[0] + int(total), max_len) + elif key in (Key.g, Key.G): # goto that enumerated position + operation(int(total) - 1, max_len) + elif key in Key.digits(): + total += str(Key.normalize_ascii_digit_to_digit(key)) continue return def multiselect_all(self, max_len: int) -> None: """Set internal positions to entirity of list""" self.positions = Positions(range(0, max_len)) - - @staticmethod - def relative_cursor_to( - win: curses.window, todos: Todos, selected: int, first_digit: int - ) -> int: - """ - Move the cursor to the specified position relative to the current position. - - Because the trigger can only be a single keypress, this function also uses a - window object to getch until the user presses g or shift + g. This allows - for relative movement greater than 9 lines away. - """ - total = str(first_digit) - while True: - try: - key = win.getch() - except Key.ctrl_c: - return selected - if key in (Key.up, Key.k): - return clamp( - selected - int(total), - 0, - len(todos), - ) - if key in (Key.down, Key.j): - return clamp( - selected + int(total), - 0, - len(todos), - ) - if key in (Key.g, Key.G): - return clamp(int(total) - 1, 0, len(todos)) - if key in Key.digits(): - total += str(Key.normalize_ascii_digit_to_digit(key)) - continue - return selected diff --git a/todo.py b/todo.py index 334ed9d..49912ef 100755 --- a/todo.py +++ b/todo.py @@ -341,17 +341,6 @@ def _handle_sort_menu( return selected.todo_set_to(sort_menu(stdscr, todos, selected)) -def _handle_digits( - stdscr: curses.window, todos: Todos, selected: Cursor, digit: int -) -> None: - - selected.set_to( - selected.relative_cursor_to( - stdscr, todos, int(selected), Key.normalize_ascii_digit_to_digit(digit) - ) - ) - - def _set_fold_state_under( state: FoldedState, parent_indent_level: int, todos: Todos, start_index: int ) -> None: @@ -574,16 +563,16 @@ def main(stdscr: curses.window) -> int: Key.escape: (lambda: None, "None"), Key.minus: (blank_todo, "todos, selected"), Key.slash: (search_menu, "stdscr, todos, selected"), - Key.zero: (_handle_digits, f"stdscr, todos, selected, {Key.zero}"), - Key.one: (_handle_digits, f"stdscr, todos, selected, {Key.one}"), - Key.two: (_handle_digits, f"stdscr, todos, selected, {Key.two}"), - Key.three: (_handle_digits, f"stdscr, todos, selected, {Key.three}"), - Key.four: (_handle_digits, f"stdscr, todos, selected, {Key.four}"), - Key.five: (_handle_digits, f"stdscr, todos, selected, {Key.five}"), - Key.six: (_handle_digits, f"stdscr, todos, selected, {Key.six}"), - Key.seven: (_handle_digits, f"stdscr, todos, selected, {Key.seven}"), - Key.eight: (_handle_digits, f"stdscr, todos, selected, {Key.eight}"), - Key.nine: (_handle_digits, f"stdscr, todos, selected, {Key.nine}"), + Key.zero: (selected.relative_to, "stdscr, 0, len(todos), True"), + Key.one: (selected.relative_to, "stdscr, 1, len(todos), True"), + Key.two: (selected.relative_to, "stdscr, 2, len(todos), True"), + Key.three: (selected.relative_to, "stdscr, 3, len(todos), True"), + Key.four: (selected.relative_to, "stdscr, 4, len(todos), True"), + Key.five: (selected.relative_to, "stdscr, 5, len(todos), True"), + Key.six: (selected.relative_to, "stdscr, 6, len(todos), True"), + Key.seven: (selected.relative_to, "stdscr, 7, len(todos), True"), + Key.eight: (selected.relative_to, "stdscr, 8, len(todos), True"), + Key.nine: (selected.relative_to, "stdscr, 9, len(todos), True"), Key.G: (selected.to_bottom, "len(todos)"), Key.J: (selected.multiselect_down, "len(todos)"), Key.K: (selected.multiselect_up, "None"), @@ -623,16 +612,16 @@ def main(stdscr: curses.window) -> int: Key.alt_g: (selected.multiselect_top, "None"), Key.alt_j: (_handle_todo_down, "todos, selected"), Key.alt_k: (_handle_todo_up, "todos, selected"), - Key.zero: (selected.multiselect_from, "stdscr, 0, len(todos)"), - Key.one: (selected.multiselect_from, "stdscr, 1, len(todos)"), - Key.two: (selected.multiselect_from, "stdscr, 2, len(todos)"), - Key.three: (selected.multiselect_from, "stdscr, 3, len(todos)"), - Key.four: (selected.multiselect_from, "stdscr, 4, len(todos)"), - Key.five: (selected.multiselect_from, "stdscr, 5, len(todos)"), - Key.six: (selected.multiselect_from, "stdscr, 6, len(todos)"), - Key.seven: (selected.multiselect_from, "stdscr, 7, len(todos)"), - Key.eight: (selected.multiselect_from, "stdscr, 8, len(todos)"), - Key.nine: (selected.multiselect_from, "stdscr, 9, len(todos)"), + Key.zero: (selected.relative_to, "stdscr, 0, len(todos), False"), + Key.one: (selected.relative_to, "stdscr, 1, len(todos), False"), + Key.two: (selected.relative_to, "stdscr, 2, len(todos), False"), + Key.three: (selected.relative_to, "stdscr, 3, len(todos), False"), + Key.four: (selected.relative_to, "stdscr, 4, len(todos), False"), + Key.five: (selected.relative_to, "stdscr, 5, len(todos), False"), + Key.six: (selected.relative_to, "stdscr, 6, len(todos), False"), + Key.seven: (selected.relative_to, "stdscr, 7, len(todos), False"), + Key.eight: (selected.relative_to, "stdscr, 8, len(todos), False"), + Key.nine: (selected.relative_to, "stdscr, 9, len(todos), False"), } history.add(todos, int(selected)) _print_history(history) @@ -671,6 +660,7 @@ def main(stdscr: curses.window) -> int: "stdscr": stdscr, "todos": todos, "True": True, + "False": False, }, ) if isinstance(next_step, Todos):