move lines and cols into margin

This commit is contained in:
Anthony Sottile
2020-03-30 17:56:50 -07:00
parent 9f36fe2f1b
commit 2b66c465a6
5 changed files with 41 additions and 36 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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':

View File

@@ -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