diff --git a/src/acurses.py b/src/acurses.py index bb952f9..994549e 100644 --- a/src/acurses.py +++ b/src/acurses.py @@ -109,7 +109,10 @@ def getmaxyx(self) -> tuple[int, int]: def _clear_buffer(self, attr: int = -1) -> None: self.addstr( - self._stored_y, self._stored_x, "".join(self._buffer), self._stored_attr + self._stored_y, + self._stored_x, + "".join(self._buffer), + self._stored_attr, ) if attr != -1: self._stored_attr = attr @@ -235,7 +238,10 @@ def color_pair(pair_number: int) -> int: def newwin( - nlines: int, ncols: int, begin_y: int = 0, begin_x: int = 0 + nlines: int, + ncols: int, + begin_y: int = 0, + begin_x: int = 0, ) -> _CursesWindow: """ Return a new window, whose left-upper corner is at (begin_y, begin_x), diff --git a/src/clipboard.py b/src/clipboard.py index c8e9779..69084c0 100644 --- a/src/clipboard.py +++ b/src/clipboard.py @@ -25,7 +25,10 @@ def copy_todo( - stdscr: curses.window, todos: Todos, selected: Cursor, copied_todo: Todo + stdscr: curses.window, + todos: Todos, + selected: Cursor, + copied_todo: Todo, ) -> None: """ Set `copied_todo` to be a duplicate of the first selected Todo. @@ -42,7 +45,10 @@ def copy_todo( def _todo_from_clipboard( - stdscr: curses.window, todos: Todos, selected: int, copied_todo: Todo + stdscr: curses.window, + todos: Todos, + selected: int, + copied_todo: Todo, ) -> Todos: """Retrieve copied_todo and insert into todo list""" if not CLIPBOARD_EXISTS: @@ -65,7 +71,10 @@ def _todo_from_clipboard( def paste_todo( - stdscr: curses.window, todos: Todos, selected: Cursor, copied_todo: Todo + stdscr: curses.window, + todos: Todos, + selected: Cursor, + copied_todo: Todo, ) -> Todos: """Paste a todo from copied_todo or clipboard if available""" temp = todos.copy() diff --git a/src/get_args.py b/src/get_args.py index 0b58b57..855deab 100644 --- a/src/get_args.py +++ b/src/get_args.py @@ -29,6 +29,7 @@ class GuiType(Enum): """Specifiy a GUI type, (curses default tui, ansi custom tui, tkinter gui)""" + CURSES = "curses" ANSI = "ansi" TKINTER = "tkinter" @@ -74,7 +75,7 @@ def _get_args() -> TypedNamespace: CONTROLS_END_INDEX, str(_DEFAULT_HELP_FILE), frozenset({"", ""}), - ) + ), ), ) parser.add_argument( diff --git a/src/get_todo.py b/src/get_todo.py index ac82b17..dc59925 100644 --- a/src/get_todo.py +++ b/src/get_todo.py @@ -34,7 +34,11 @@ class _EditString(NamedTuple): def hline( - win: curses.window, y_loc: int, x_loc: int, char: str | int, width: int + win: curses.window, + y_loc: int, + x_loc: int, + char: str | int, + width: int, ) -> None: """ Display a horizontal line starting at (y_loc, x_loc) @@ -49,7 +53,7 @@ def _ensure_valid(win: curses.window) -> None: if win.getmaxyx()[0] < 3: raise ValueError( "Window is too short, it won't be able to\ - display the minimum 1 line of text." + display the minimum 1 line of text.", ) if win.getmaxyx()[0] > 3: raise NotImplementedError("Multiline text editing is not supported") @@ -164,7 +168,11 @@ def _handle_toggle_note_todo(stdscr: curses.window, todo: Todo) -> None: def _handle_indent_dedent( - stdscr: curses.window, todo: Todo, action: str, chars: _Chars, position: int + stdscr: curses.window, + todo: Todo, + action: str, + chars: _Chars, + position: int, ) -> _EditString: if action == "indent": todo.indent() @@ -184,7 +192,9 @@ def _handle_end(chars: _Chars) -> _EditString: def _passthrough( - stdscr: curses.window, edit_string: _EditString, key_name: str + stdscr: curses.window, + edit_string: _EditString, + key_name: str, ) -> _EditString: alert(stdscr, f"Key `{key_name}` is not supported") return edit_string @@ -300,7 +310,10 @@ def _get_chars_position( def _set_once( - mode: SingleLineModeImpl, chars: _Chars, position: int, color: Color + mode: SingleLineModeImpl, + chars: _Chars, + position: int, + color: Color, ) -> str: mode.set_once() string = "".join(chars) @@ -374,7 +387,7 @@ def get_todo( while True: if len(chars) + 1 >= win.getmaxyx()[1] - 1: return todo.set_display_text( - _set_once(mode, chars, position, todo.get_color()) + _set_once(mode, chars, position, todo.get_color()), ) if position == len(chars): win.addch(1, len(chars) + 1, "█") @@ -392,7 +405,10 @@ def get_todo( mode.toggle() break next_step = _get_chars_position( - input_char, (stdscr, win), (chars, position, todo), mode + input_char, + (stdscr, win), + (chars, position, todo), + mode, ) if next_step is None: return original diff --git a/src/md_to_py.py b/src/md_to_py.py index 430e019..2a7a686 100644 --- a/src/md_to_py.py +++ b/src/md_to_py.py @@ -10,7 +10,9 @@ def _get_column_widths( - row: str, delimiter: str = "|", strip_spaces: bool = True + row: str, + delimiter: str = "|", + strip_spaces: bool = True, ) -> list[int]: """ Return a list of column widths. Columns are determined by a delimiter @@ -25,7 +27,7 @@ def _get_column_widths( if len(delimiter) != 1: raise ValueError( - f"`delimiter` must be one character, is {len(delimiter)} characters" + f"`delimiter` must be one character, is {len(delimiter)} characters", ) if delimiter == " ": raise ValueError("`delimiter` cannot be a space") @@ -70,7 +72,7 @@ def _pad_columns(row: str, widths: tuple[int, ...] | int, delimiter: str = "|") if len(delimiter) != 1: raise ValueError( - f"`delimiter` must be one character, is {len(delimiter)} characters" + f"`delimiter` must be one character, is {len(delimiter)} characters", ) if delimiter == " ": raise ValueError("`delimiter` cannot be a space") @@ -80,7 +82,7 @@ def _pad_columns(row: str, widths: tuple[int, ...] | int, delimiter: str = "|") if isinstance(widths, tuple) and len(widths) != column_count: raise ValueError( "`widths` cannot be a tuple of arbitrary length. " - f"Is {len(widths)}, should be {column_count}." + f"Is {len(widths)}, should be {column_count}.", ) if isinstance(widths, int): @@ -103,11 +105,12 @@ def _pad_columns(row: str, widths: tuple[int, ...] | int, delimiter: str = "|") if widths[column] < non_space_len: raise ValueError( f"Width of column `{column}` cannot be less than " - f"{non_space_len}, is {widths[column]}" + f"{non_space_len}, is {widths[column]}", ) change_amount = widths[column] - non_space_len for index in range( - prev_delimiter_index, prev_delimiter_index + non_space_len + 1 + prev_delimiter_index, + prev_delimiter_index + non_space_len + 1, ): new_row += row[index] new_row += " " * change_amount @@ -226,7 +229,7 @@ def md_table_to_lines( map( lambda iterable: max(iterable) + 2, zip(*_exclusive_map(_get_column_widths, lines, exclude=frozenset({1}))), - ) + ), ) for i, _ in enumerate(lines): diff --git a/src/menus.py b/src/menus.py index 347a7df..aba6af0 100644 --- a/src/menus.py +++ b/src/menus.py @@ -37,7 +37,10 @@ def _simple_scroll_keybinds( - win: curses.window, cursor: int, len_lines: int, len_new_lines: int + win: curses.window, + cursor: int, + len_lines: int, + len_new_lines: int, ) -> int: try: key = win.getch() @@ -53,7 +56,8 @@ def _simple_scroll_keybinds( def _get_move_options( - len_list: int, additional_options: dict[int, Callable[[int], int]] + len_list: int, + additional_options: dict[int, Callable[[int], int]], ) -> dict[int, Callable[[int], int]]: defaults: dict[int, Callable[[int], int]] = { Key.k: lambda cursor: cursor - 1, @@ -89,7 +93,10 @@ def help_menu(parent_win: curses.window) -> None: hline(win, 2, 0, curses.ACS_HLINE, win.getmaxyx()[1]) while True: new_lines, _, _ = make_printable_sublist( - win.getmaxyx()[0] - 4, lines[2:], cursor, 0 + win.getmaxyx()[0] - 4, + lines[2:], + cursor, + 0, ) for i, line in enumerate(new_lines): win.addstr(i + 3, 1, line) @@ -115,14 +122,18 @@ def magnify_menu(stdscr: curses.window, todos: Todos, selected: Cursor) -> None: stdscr.clear() set_header(stdscr, "Magnifying...") lines = big( # pyright: ignore - todos[int(selected)].get_display_text(), width=stdscr.getmaxyx()[1] + todos[int(selected)].get_display_text(), + width=stdscr.getmaxyx()[1], ).split("\n") lines.append("") lines = [line.ljust(stdscr.getmaxyx()[1] - 2) for line in lines] cursor = 0 while True: new_lines, _, _ = make_printable_sublist( - stdscr.getmaxyx()[0] - 2, lines, cursor, 0 + stdscr.getmaxyx()[0] - 2, + lines, + cursor, + 0, ) for i, line in enumerate(new_lines): stdscr.addstr(i + 1, 1, line) diff --git a/src/print_todos.py b/src/print_todos.py index 79f481d..2a1e4fe 100644 --- a/src/print_todos.py +++ b/src/print_todos.py @@ -165,7 +165,10 @@ def _get_display_string( # pylint: disable=too-many-arguments def _is_within_strikethrough_range( - counter: int, todo: Todo, display_string: str, window_width: int + counter: int, + todo: Todo, + display_string: str, + window_width: int, ) -> bool: # make sure to test with -s and -sx # issue lies with Alacritty terminal @@ -213,7 +216,10 @@ def _print_todo( STRIKETHROUGH and todo.is_toggled() and _is_within_strikethrough_range( - counter, todo, display_string, stdscr.getmaxyx()[1] + counter, + todo, + display_string, + stdscr.getmaxyx()[1], ) ): stdscr.addch(print_position + 1, counter, "\u0336") @@ -234,7 +240,10 @@ def _color_to_ansi(color: int) -> str: def print_todos( - stdscr: curses.window | None, todos: Todos, selected: Cursor, prev_start: int = 0 + stdscr: curses.window | None, + todos: Todos, + selected: Cursor, + prev_start: int = 0, ) -> int: """ Output list of Todo objects to a curses stdscr or stdout. @@ -248,7 +257,10 @@ def print_todos( except RuntimeError: return 0 new_todos, temp_selected, prev_start = make_printable_sublist( - height - 1, list(todos), int(selected), prev_start=prev_start + height - 1, + list(todos), + int(selected), + prev_start=prev_start, ) highlight = range(temp_selected, len(selected) + temp_selected) print_position = -1 @@ -261,8 +273,13 @@ def print_todos( print( _color_to_ansi(todo.get_color().as_int()) + _get_display_string( - Todos(new_todos), position, relative, range(0), width, True - ) + Todos(new_todos), + position, + relative, + range(0), + width, + True, + ), ) continue if not todo.is_folded() or DEBUG_FOLD: @@ -270,7 +287,12 @@ def print_todos( stdscr, todo, _get_display_string( - Todos(new_todos), position, relative, highlight, width, False + Todos(new_todos), + position, + relative, + highlight, + width, + False, ), (position, print_position), highlight, diff --git a/src/tcurses.py b/src/tcurses.py index d212b16..6a3b27e 100644 --- a/src/tcurses.py +++ b/src/tcurses.py @@ -17,7 +17,9 @@ class _CursesWindow: # pylint: disable=too-many-instance-attributes def _updates_screen(func: Callable[..., None]) -> Callable[..., None]: @wraps(func) def _inner( - self: "_CursesWindow", *args: list[Any], **kwargs: dict[Any, Any] + self: "_CursesWindow", + *args: list[Any], + **kwargs: dict[Any, Any], ) -> None: screen.configure(state="normal") func(self, *args, **kwargs) @@ -49,7 +51,8 @@ def __del__(self): root.bind("", stdscr._handle_key) def _handle_key( # pylint: disable=too-many-return-statements - self, event: "Event[Any]" + self, + event: "Event[Any]", ) -> None: if self.has_key.get() or event.keysym.endswith(("_R", "_L")): return @@ -172,7 +175,10 @@ def addch(self, y: int, x: int, char: str, attr: int = 0) -> None: or len(self.buffer) + self.stored_x >= self.width ): self.addstr( - self.stored_y, self.stored_x, "".join(self.buffer), self.stored_attr + self.stored_y, + self.stored_x, + "".join(self.buffer), + self.stored_attr, ) self.stored_attr = attr self.buffer.clear() @@ -293,7 +299,10 @@ def color_pair(pair_number: int) -> int: def newwin( - nlines: int, ncols: int, begin_y: int = 0, begin_x: int = 0 + nlines: int, + ncols: int, + begin_y: int = 0, + begin_x: int = 0, ) -> _CursesWindow: """ Return a new window, whose left-upper corner is at (begin_y, begin_x), diff --git a/src/utils.py b/src/utils.py index ceece62..dd98840 100644 --- a/src/utils.py +++ b/src/utils.py @@ -86,7 +86,10 @@ def set_header(stdscr: curses.window, message: str) -> None: Set the header to a specific message. """ stdscr.addstr( - 0, 0, message.ljust(stdscr.getmaxyx()[1]), curses.A_BOLD | curses.color_pair(2) + 0, + 0, + message.ljust(stdscr.getmaxyx()[1]), + curses.A_BOLD | curses.color_pair(2), ) @@ -132,7 +135,8 @@ def alert(stdscr: curses.window, message: str) -> int: border_width = 2 max_y, max_x = stdscr.getmaxyx() height_chunk, width_chunk, chunks = tee( - _chunk_message(message, max_x * 3 // 4 - border_width), 3 + _chunk_message(message, max_x * 3 // 4 - border_width), + 3, ) width = len(max(width_chunk, key=len)) + border_width height = sum(1 for _ in height_chunk) + border_width diff --git a/todo.py b/todo.py index 11f8c16..a62cb4c 100755 --- a/todo.py +++ b/todo.py @@ -184,7 +184,10 @@ def color_todo(stdscr: curses.window, todos: Todos, selected: Cursor) -> Todos: def edit_todo( - stdscr: curses.window, todos: Todos, selected: int, mode: SingleLineModeImpl + stdscr: curses.window, + todos: Todos, + selected: int, + mode: SingleLineModeImpl, ) -> Todos: """ Open a get_todo input box with the current todo contents. Set @@ -265,7 +268,10 @@ def _toggle_todo_note(todos: Todos, selected: Cursor) -> None: def _handle_delete_todo( - stdscr: curses.window, todos: Todos, selected: Cursor, copied_todo: Todo + stdscr: curses.window, + todos: Todos, + selected: Cursor, + copied_todo: Todo, ) -> Todos: if len(todos) > 0 and CLIPBOARD_EXISTS: copy_todo(stdscr, todos, selected, copied_todo) @@ -346,7 +352,10 @@ def _handle_sort_menu( def _set_fold_state_under( - state: FoldedState, parent_indent_level: int, todos: Todos, start_index: int + state: FoldedState, + parent_indent_level: int, + todos: Todos, + start_index: int, ) -> None: index = start_index while True: @@ -383,13 +392,19 @@ def _unset_folded(stdscr: curses.window, todos: Todos, selected: int) -> None: return parent.set_folded(FoldedState.DEFAULT) _set_fold_state_under( - FoldedState.DEFAULT, parent.get_indent_level(), todos, selected + FoldedState.DEFAULT, + parent.get_indent_level(), + todos, + selected, ) stdscr.clear() def _handle_enter( - stdscr: curses.window, todos: Todos, selected: Cursor, mode: SingleLineModeImpl + stdscr: curses.window, + todos: Todos, + selected: Cursor, + mode: SingleLineModeImpl, ) -> Todos: prev_todo = todos[int(selected)] if len(todos) > 0 else Todo() if prev_todo.has_box(): @@ -496,7 +511,7 @@ def join_lines(todos: Todos, selected: Cursor) -> None: current_todo = int(selected) todos[prev_todo].set_display_text( - f"{todos[prev_todo].get_display_text()} {todos[current_todo].get_display_text()}" + f"{todos[prev_todo].get_display_text()} {todos[current_todo].get_display_text()}", ) selected.slide_up() todos.pop(current_todo) @@ -684,7 +699,9 @@ def main(stdscr: curses.window) -> int: if NO_GUI: print(f"{HEADER}:") print_todos( - None, file_string_to_todos(read_file(FILENAME)), Cursor(0, Todos(())) + None, + file_string_to_todos(read_file(FILENAME)), + Cursor(0, Todos(())), ) sys_exit()