move lines and cols into margin
This commit is contained in:
16
babi/file.py
16
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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user