From a00381a2c28caf60ff80f46c5356da9fe190414d Mon Sep 17 00:00:00 2001 From: lohhiiccc <96543753+lohhiiccc@users.noreply.github.com> Date: Thu, 2 Jul 2026 20:45:34 +0200 Subject: [PATCH] fix: dynamic size column width and right-edge curses crash --- src/IO/UI.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/IO/UI.py b/src/IO/UI.py index a11d6bf..fbb2d80 100644 --- a/src/IO/UI.py +++ b/src/IO/UI.py @@ -32,11 +32,14 @@ class UI: stdscr.addstr(0, 0, str(navigator.history[-1])[:width - 1]) items = navigator.items + size_width = max((len(self._format_size(item.size)) for item in items), + default=0) available = max(0, height - self.HEADER_ROWS) top = self._update_scroll(navigator, available) for offset, item in enumerate(items[top:top + available]): index = top + offset - self._render_item(stdscr, item, index, offset + self.HEADER_ROWS, width) + self._render_item(stdscr, item, index, offset + self.HEADER_ROWS, + width, size_width) prompt = self.app.prompt if prompt: @@ -115,13 +118,22 @@ class UI: ARROW_LEN = len(ARROW) def _render_item(self, stdscr: curses.window, item: AItem, index: int, - row: int, width: int) -> None: + row: int, width: int, size_width: int) -> None: name, size, perm = item.fields() - name_len = len(name) - col_width = int(width / 3) - attr = self._get_attr(item, index) - stdscr.addstr(row, 0, name.ljust(col_width), attr) + + size_str = self._format_size(size).rjust(size_width) + stdscr.addstr(row, 0, size_str, attr) + + name_col = size_width + 1 + perm_str = stat.filemode(perm) + # -1 keeps the very last column free: writing to the bottom-right + # cell of the window makes curses raise addwstr() == ERR. + perm_col = max(name_col, width - len(perm_str) - 1) + name_width = max(0, perm_col - 1 - name_col) + name_len = len(name) + + stdscr.addstr(row, name_col, name.ljust(name_width)[:name_width], attr) if type(item) is Symlink: target_pair = self.app.config.theme.pair_for( @@ -131,11 +143,11 @@ class UI: if index == self.app.navigator.cursor.pos: attr_arrow |= curses.A_REVERSE attr_target |= curses.A_REVERSE - stdscr.addstr(row, name_len, self.ARROW, attr_arrow) - stdscr.addstr(row, name_len + self.ARROW_LEN, str(item.point_to), attr_target) + stdscr.addstr(row, name_col + name_len, self.ARROW, attr_arrow) + stdscr.addstr(row, name_col + name_len + self.ARROW_LEN, + str(item.point_to), attr_target) - stdscr.addstr(row, col_width, self._format_size(size).ljust(col_width * 2), attr) - stdscr.addstr(row, col_width * 2, stat.filemode(perm), attr) + stdscr.addstr(row, perm_col, perm_str, attr) @property def app(self) -> App: