Fix highlight color in replace/selection

This commit is contained in:
Anthony Sottile
2020-03-21 21:08:43 -07:00
parent f1772ec829
commit bf1c3d1ee1
8 changed files with 41 additions and 47 deletions

View File

@@ -19,19 +19,16 @@ class ColorManager(NamedTuple):
raw_pairs: Dict[Tuple[int, int], int]
def init_color(self, color: Color) -> None:
if curses.COLORS < 256:
return
elif curses.can_change_color():
if curses.can_change_color():
n = min(self.colors.values(), default=256) - 1
self.colors[color] = n
curses.init_color(n, *_color_to_curses(color))
else:
elif curses.COLORS >= 256:
self.colors[color] = color_kd.nearest(color, color_kd.make_256())
else:
self.colors[color] = -1
def color_pair(self, fg: Optional[Color], bg: Optional[Color]) -> int:
if curses.COLORS < 256:
return 0
fg_i = self.colors[fg] if fg is not None else -1
bg_i = self.colors[bg] if bg is not None else -1
return self.raw_color_pair(fg_i, bg_i)

View File

@@ -21,10 +21,12 @@ from typing import TYPE_CHECKING
from typing import TypeVar
from typing import Union
from babi.color_manager import ColorManager
from babi.hl.interface import FileHL
from babi.hl.interface import HLFactory
from babi.hl.replace import Replace
from babi.hl.selection import Selection
from babi.hl.trailing_whitespace import TrailingWhitespace
from babi.horizontal_scrolling import line_x
from babi.horizontal_scrolling import scrolled_line
from babi.list_spy import ListSpy
@@ -211,6 +213,7 @@ class File:
def __init__(
self,
filename: Optional[str],
color_manager: ColorManager,
hl_factories: Tuple[HLFactory, ...],
) -> None:
self.filename = filename
@@ -222,6 +225,7 @@ class File:
self.undo_stack: List[Action] = []
self.redo_stack: List[Action] = []
self._hl_factories = hl_factories
self._trailing_whitespace = TrailingWhitespace(color_manager)
self._replace_hl = Replace()
self.selection = Selection()
self._file_hls: Tuple[FileHL, ...] = ()
@@ -260,7 +264,10 @@ class File:
file_hls.append(hl)
else:
file_hls.append(factory.blank_file_highlighter())
self._file_hls = (*file_hls, self._replace_hl, self.selection)
self._file_hls = (
*file_hls,
self._trailing_whitespace, self._replace_hl, self.selection,
)
def __repr__(self) -> str:
return f'<{type(self).__name__} {self.filename!r}>'

View File

@@ -8,8 +8,6 @@ from babi.hl.interface import HL
from babi.hl.interface import HLs
from babi.list_spy import SequenceNoSlice
HIGHLIGHT = curses.A_REVERSE | curses.A_DIM
class Replace:
include_edge = True
@@ -25,7 +23,9 @@ class Replace:
@contextlib.contextmanager
def region(self, y: int, x: int, end: int) -> Generator[None, None, None]:
self.regions[y] = (HL(x=x, end=end, attr=HIGHLIGHT),)
# XXX: this assumes pair 1 is the background
attr = curses.A_REVERSE | curses.A_DIM | curses.color_pair(1)
self.regions[y] = (HL(x=x, end=end, attr=attr),)
try:
yield
finally:

View File

@@ -8,8 +8,6 @@ from babi.hl.interface import HL
from babi.hl.interface import HLs
from babi.list_spy import SequenceNoSlice
ATTR = curses.A_REVERSE | curses.A_DIM
class Selection:
include_edge = True
@@ -23,18 +21,20 @@ class Selection:
if self.start is None or self.end is None:
return
# XXX: this assumes pair 1 is the background
attr = curses.A_REVERSE | curses.A_DIM | curses.color_pair(1)
(s_y, s_x), (e_y, e_x) = self.get()
if s_y == e_y:
self.regions[s_y] = (HL(x=s_x, end=e_x, attr=ATTR),)
self.regions[s_y] = (HL(x=s_x, end=e_x, attr=attr),)
else:
self.regions[s_y] = (
HL(x=s_x, end=len(lines[s_y]) + 1, attr=ATTR),
HL(x=s_x, end=len(lines[s_y]) + 1, attr=attr),
)
for l_y in range(s_y + 1, e_y):
self.regions[l_y] = (
HL(x=0, end=len(lines[l_y]) + 1, attr=ATTR),
HL(x=0, end=len(lines[l_y]) + 1, attr=attr),
)
self.regions[e_y] = (HL(x=0, end=e_x, attr=ATTR),)
self.regions[e_y] = (HL(x=0, end=e_x, attr=attr),)
def touch(self, lineno: int) -> None:
"""our highlight regions are populated in other ways"""

View File

@@ -1,6 +1,5 @@
import curses
from typing import List
from typing import NamedTuple
from babi.color_manager import ColorManager
from babi.hl.interface import HL
@@ -8,7 +7,7 @@ from babi.hl.interface import HLs
from babi.list_spy import SequenceNoSlice
class FileTrailingWhitespace:
class TrailingWhitespace:
include_edge = False
def __init__(self, color_manager: ColorManager) -> None:
@@ -37,18 +36,3 @@ class FileTrailingWhitespace:
def touch(self, lineno: int) -> None:
del self.regions[lineno:]
class TrailingWhitespace(NamedTuple):
color_manager: ColorManager
def file_highlighter(
self,
filename: str,
first_line: str,
) -> FileTrailingWhitespace:
# no file-specific behaviour
return self.blank_file_highlighter()
def blank_file_highlighter(self) -> FileTrailingWhitespace:
return FileTrailingWhitespace(self.color_manager)

View File

@@ -20,7 +20,6 @@ from babi.file import File
from babi.file import get_lines
from babi.history import History
from babi.hl.syntax import Syntax
from babi.hl.trailing_whitespace import TrailingWhitespace
from babi.margin import Margin
from babi.perf import Perf
from babi.prompt import Prompt
@@ -77,12 +76,12 @@ class Screen:
perf: Perf,
) -> None:
self.stdscr = stdscr
color_manager = ColorManager.make()
self.hl_factories = (
Syntax.from_screen(stdscr, color_manager),
TrailingWhitespace(color_manager),
)
self.files = [File(f, self.hl_factories) for f in filenames]
self.color_manager = ColorManager.make()
self.hl_factories = (Syntax.from_screen(stdscr, self.color_manager),)
self.files = [
File(filename, self.color_manager, self.hl_factories)
for filename in filenames
]
self.i = 0
self.history = History()
self.perf = perf
@@ -459,7 +458,8 @@ class Screen:
def open_file(self) -> Optional[EditResult]:
response = self.prompt('enter filename', history='open')
if response is not PromptResult.CANCELLED:
self.files.append(File(response, self.hl_factories))
opened = File(response, self.color_manager, self.hl_factories)
self.files.append(opened)
return EditResult.OPEN
else:
return None

View File

@@ -2,12 +2,13 @@ import io
import pytest
from babi.color_manager import ColorManager
from babi.file import File
from babi.file import get_lines
def test_position_repr():
ret = repr(File('f.txt', ()))
ret = repr(File('f.txt', ColorManager.make(), ()))
assert ret == "<File 'f.txt'>"

View File

@@ -78,11 +78,16 @@ def syntax(tmpdir):
def test_init_screen_low_color(stdscr, syntax):
with FakeCurses.patch(n_colors=16, can_change_color=False) as fake_curses:
syntax._init_screen(stdscr)
assert syntax.color_manager.colors == {}
assert syntax.color_manager.raw_pairs == {}
assert syntax.color_manager.colors == {
Color.parse('#cccccc'): -1,
Color.parse('#333333'): -1,
Color.parse('#000000'): -1,
Color.parse('#009900'): -1,
}
assert syntax.color_manager.raw_pairs == {(-1, -1): 1}
assert fake_curses.colors == {}
assert fake_curses.pairs == {}
assert stdscr.attr == 0
assert fake_curses.pairs == {1: (-1, -1)}
assert stdscr.attr == 1 << 8
def test_init_screen_256_color(stdscr, syntax):