diff --git a/babi/file.py b/babi/file.py index 296b4aa..fac729b 100644 --- a/babi/file.py +++ b/babi/file.py @@ -764,15 +764,15 @@ class File: def rendered_y(self, margin: Margin) -> int: return self.buf.y - self.buf.file_y + margin.header - def rendered_x(self) -> int: - return self.buf.x - line_x(self.buf.x, curses.COLS) + def rendered_x(self, margin: Margin) -> int: + return self.buf.x - line_x(self.buf.x, margin.cols) def move_cursor( self, stdscr: 'curses._CursesWindow', margin: Margin, ) -> None: - stdscr.move(self.rendered_y(margin), self.rendered_x()) + stdscr.move(self.rendered_y(margin), self.rendered_x(margin)) def draw(self, stdscr: 'curses._CursesWindow', margin: Margin) -> None: to_display = min(self.buf.displayable_count, margin.body_lines) @@ -785,11 +785,11 @@ class File: draw_y = i + margin.header l_y = self.buf.file_y + i x = self.buf.x if l_y == self.buf.y else 0 - line = scrolled_line(self.buf[l_y], x, curses.COLS) + line = scrolled_line(self.buf[l_y], x, margin.cols) stdscr.insstr(draw_y, 0, line) - l_x = line_x(x, curses.COLS) - l_x_max = l_x + curses.COLS + l_x = line_x(x, margin.cols) + l_x_max = l_x + margin.cols for file_hl in self._file_hls: for region in file_hl.regions[l_y]: if region.x >= l_x_max: @@ -807,9 +807,9 @@ class File: if region.end >= l_x_max and l_x_max < len(self.buf[l_y]): if file_hl.include_edge: - h_e_x = curses.COLS + h_e_x = margin.cols else: - h_e_x = curses.COLS - 1 + h_e_x = margin.cols - 1 else: h_e_x = region.end - l_x diff --git a/babi/margin.py b/babi/margin.py index 4291066..fd4e9cf 100644 --- a/babi/margin.py +++ b/babi/margin.py @@ -3,12 +3,20 @@ from typing import NamedTuple class Margin(NamedTuple): - header: bool - footer: bool + lines: int + cols: int + + @property + def header(self) -> bool: + return self.lines > 2 + + @property + def footer(self) -> bool: + return self.lines > 1 @property def body_lines(self) -> int: - return curses.LINES - self.header - self.footer + return self.lines - self.header - self.footer @property def page_size(self) -> int: @@ -20,13 +28,8 @@ class Margin(NamedTuple): @property def scroll_amount(self) -> int: # integer round up without banker's rounding (so 1/2 => 1 instead of 0) - return int(curses.LINES / 2 + .5) + return int(self.lines / 2 + .5) @classmethod def from_current_screen(cls) -> 'Margin': - if curses.LINES == 1: - return cls(header=False, footer=False) - elif curses.LINES == 2: - return cls(header=False, footer=True) - else: - return cls(header=True, footer=True) + return cls(curses.LINES, curses.COLS) diff --git a/babi/prompt.py b/babi/prompt.py index 413f385..c2a76eb 100644 --- a/babi/prompt.py +++ b/babi/prompt.py @@ -33,18 +33,19 @@ class Prompt: def _render_prompt(self, *, base: Optional[str] = None) -> None: base = base or self._prompt - if not base or curses.COLS < 7: + if not base or self._screen.margin.cols < 7: prompt_s = '' - elif len(base) > curses.COLS - 6: - prompt_s = f'{base[:curses.COLS - 7]}…: ' + elif len(base) > self._screen.margin.cols - 6: + prompt_s = f'{base[:self._screen.margin.cols - 7]}…: ' else: prompt_s = f'{base}: ' - width = curses.COLS - len(prompt_s) + width = self._screen.margin.cols - len(prompt_s) line = scrolled_line(self._s, self._x, width) cmd = f'{prompt_s}{line}' - self._screen.stdscr.insstr(curses.LINES - 1, 0, cmd, curses.A_REVERSE) + prompt_line = self._screen.margin.lines - 1 + self._screen.stdscr.insstr(prompt_line, 0, cmd, curses.A_REVERSE) x = len(prompt_s) + self._x - line_x(self._x, width) - self._screen.stdscr.move(curses.LINES - 1, x) + self._screen.stdscr.move(prompt_line, x) def _up(self) -> None: self._y = max(0, self._y - 1) diff --git a/babi/screen.py b/babi/screen.py index 0fe0680..c9f7cb1 100644 --- a/babi/screen.py +++ b/babi/screen.py @@ -105,7 +105,7 @@ class Screen: else: files = '' version_width = len(VERSION_STR) + 2 - centered = filename.center(curses.COLS)[version_width:] + centered = filename.center(self.margin.cols)[version_width:] s = f' {VERSION_STR} {files}{centered}{files}' self.stdscr.insstr(0, 0, s, curses.A_REVERSE) @@ -236,13 +236,14 @@ class Screen: opts = [opt[0] for opt in opt_strs] while True: x = 0 + prompt_line = self.margin.lines - 1 def _write(s: str, *, attr: int = curses.A_REVERSE) -> None: nonlocal x - if x >= curses.COLS: + if x >= self.margin.cols: return - self.stdscr.insstr(curses.LINES - 1, x, s, attr) + self.stdscr.insstr(prompt_line, x, s, attr) x += len(s) _write(prompt) @@ -254,15 +255,15 @@ class Screen: _write(', ') _write(']?') - if x < curses.COLS - 1: - s = ' ' * (curses.COLS - x) - self.stdscr.insstr(curses.LINES - 1, x, s, curses.A_REVERSE) + if x < self.margin.cols - 1: + s = ' ' * (self.margin.cols - x) + self.stdscr.insstr(prompt_line, x, s, curses.A_REVERSE) x += 1 else: - x = curses.COLS - 1 - self.stdscr.insstr(curses.LINES - 1, x, '…', curses.A_REVERSE) + x = self.margin.cols - 1 + self.stdscr.insstr(prompt_line, x, '…', curses.A_REVERSE) - self.stdscr.move(curses.LINES - 1, x) + self.stdscr.move(prompt_line, x) key = self.get_char() if key.keyname == b'KEY_RESIZE': diff --git a/babi/status.py b/babi/status.py index 0d4e299..3b6410e 100644 --- a/babi/status.py +++ b/babi/status.py @@ -18,14 +18,14 @@ class Status: def draw(self, stdscr: 'curses._CursesWindow', margin: Margin) -> None: if margin.footer or self._status: - stdscr.insstr(curses.LINES - 1, 0, ' ' * curses.COLS) + stdscr.insstr(margin.lines - 1, 0, ' ' * margin.cols) if self._status: status = f' {self._status} ' - x = (curses.COLS - len(status)) // 2 + x = (margin.cols - len(status)) // 2 if x < 0: x = 0 status = status.strip() - stdscr.insstr(curses.LINES - 1, x, status, curses.A_REVERSE) + stdscr.insstr(margin.lines - 1, x, status, curses.A_REVERSE) def tick(self, margin: Margin) -> None: # when the window is only 1-tall, hide the status quicker