More work on the themes kitten

This commit is contained in:
Kovid Goyal 2021-08-04 14:13:09 +05:30
parent 55319cd6d6
commit 7090c24321
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 92 additions and 3 deletions

View File

@ -19,6 +19,8 @@ from kitty.config import parse_config
from kitty.constants import cache_dir, config_dir from kitty.constants import cache_dir, config_dir
from kitty.rgb import Color from kitty.rgb import Color
from ..choose.main import match
def fetch_themes( def fetch_themes(
name: str = 'kitty-themes', name: str = 'kitty-themes',
@ -226,6 +228,14 @@ class Themes:
ans.themes = {k: v for k, v in self.themes.items() if is_ok(v)} ans.themes = {k: v for k, v in self.themes.items() if is_ok(v)}
return ans return ans
def apply_search(self, expression: str, mark_before: str = '\033[32m', mark_after: str = '\033[39m') -> Iterator[str]:
for k, v in tuple(self.themes.items()):
result = match(v.name, expression, mark_before=mark_before, mark_after=mark_after)
if result and result[0]:
yield result[0]
else:
del self.themes[k]
def load_themes() -> Themes: def load_themes() -> Themes:
ans = Themes() ans = Themes()

View File

@ -6,9 +6,12 @@ import os
import sys import sys
import traceback import traceback
from enum import Enum, auto from enum import Enum, auto
from typing import Any, Callable, Dict, Iterable, List, Optional, Union from typing import (
Any, Callable, Dict, Iterable, Iterator, List, Optional, Tuple, Union
)
from kitty.config import cached_values_for from kitty.config import cached_values_for
from kitty.fast_data_types import wcswidth
from kitty.typing import KeyEventType from kitty.typing import KeyEventType
from kitty.utils import ScreenSize from kitty.utils import ScreenSize
@ -48,6 +51,43 @@ def create_recent_filter(names: Iterable[str]) -> Callable[[Theme], bool]:
return recent_filter return recent_filter
class ThemesList:
def __init__(self) -> None:
self.themes = Themes()
self.current_search: str = ''
self.display_strings: Tuple[str, ...] = ()
self.widths: Tuple[int, ...] = ()
self.max_width = 0
self.current_idx = 0
def update_themes(self, themes: Themes) -> None:
self.themes = themes
if self.current_search:
self.display_strings = tuple(self.themes.apply_search(self.current_search))
else:
self.display_strings = tuple(t.name for t in self.themes)
self.widths = tuple(map(wcswidth, self.display_strings))
self.max_width = max(self.widths) if self.widths else 0
def update_search(self, search: str = '') -> None:
if search == self.current_search:
return
self.current_search = search
self.update_themes(self.themes)
def lines(self, num_rows: int) -> Iterator[str]:
if num_rows < 1:
return
before_num = min(self.current_idx, num_rows - 1)
start = self.current_idx - before_num
for i in range(start, min(start + num_rows, len(self.display_strings))):
line = self.display_strings[i]
if i == self.current_idx:
line = styled(line, reverse=True)
yield line
class ThemesHandler(Handler): class ThemesHandler(Handler):
def __init__(self, cached_values: Dict[str, Any]) -> None: def __init__(self, cached_values: Dict[str, Any]) -> None:
@ -58,11 +98,13 @@ class ThemesHandler(Handler):
'dark': dark_filter, 'light': light_filter, 'all': all_filter, 'dark': dark_filter, 'light': light_filter, 'all': all_filter,
'recent': create_recent_filter(self.cached_values.get('recent', ())) 'recent': create_recent_filter(self.cached_values.get('recent', ()))
} }
self.themes_list = ThemesList()
def enforce_cursor_state(self) -> None: def enforce_cursor_state(self) -> None:
self.cmd.set_cursor_visible(self.state == State.fetching) self.cmd.set_cursor_visible(self.state == State.fetching)
def init_terminal_state(self) -> None: def init_terminal_state(self) -> None:
self.cmd.save_colors()
self.cmd.set_line_wrapping(False) self.cmd.set_line_wrapping(False)
self.cmd.set_window_title('Choose a theme for kitty') self.cmd.set_window_title('Choose a theme for kitty')
self.cmd.set_cursor_shape('bar') self.cmd.set_cursor_shape('bar')
@ -73,9 +115,26 @@ class ThemesHandler(Handler):
self.fetch_themes() self.fetch_themes()
def finalize(self) -> None: def finalize(self) -> None:
self.cmd.set_default_colors() self.cmd.restore_colors()
self.cmd.set_cursor_visible(True) self.cmd.set_cursor_visible(True)
@property
def current_category(self) -> str:
cat: str = self.cached_values.get('category', 'all')
if cat not in self.filter_map:
cat = 'all'
return cat
@current_category.setter
def current_category(self, cat: str) -> None:
if cat not in self.filter_map:
cat = 'all'
self.cached_values['category'] = cat
def redraw_after_category_change(self) -> None:
self.themes_list.update_themes(self.all_themes.filtered(self.filter_map[self.current_category]))
self.draw_screen()
# Theme fetching {{{ # Theme fetching {{{
def fetch_themes(self) -> None: def fetch_themes(self) -> None:
@ -86,7 +145,7 @@ class ThemesHandler(Handler):
return return
self.all_themes: Themes = themes_or_exception self.all_themes: Themes = themes_or_exception
self.state = State.browsing self.state = State.browsing
self.draw_screen() self.redraw_after_category_change()
def fetch() -> None: def fetch() -> None:
try: try:
@ -107,6 +166,14 @@ class ThemesHandler(Handler):
# }}} # }}}
# Theme browsing {{{
def draw_tab_bar(self) -> None:
pass
def draw_browsing_screen(self) -> None:
self.draw_tab_bar()
# }}}
def on_key_event(self, key_event: KeyEventType, in_bracketed_paste: bool = False) -> None: def on_key_event(self, key_event: KeyEventType, in_bracketed_paste: bool = False) -> None:
if self.state is State.fetching: if self.state is State.fetching:
self.on_fetching_key_event(key_event, in_bracketed_paste) self.on_fetching_key_event(key_event, in_bracketed_paste)
@ -116,6 +183,8 @@ class ThemesHandler(Handler):
self.enforce_cursor_state() self.enforce_cursor_state()
if self.state is State.fetching: if self.state is State.fetching:
self.draw_fetching_screen() self.draw_fetching_screen()
elif self.state is State.browsing:
self.draw_browsing_screen()
def on_resize(self, screen_size: ScreenSize) -> None: def on_resize(self, screen_size: ScreenSize) -> None:
self.screen_size = screen_size self.screen_size = screen_size

View File

@ -350,6 +350,16 @@ def set_default_colors(
return ans return ans
@cmd
def save_colors() -> str:
return '\x1b[#P'
@cmd
def restore_colors() -> str:
return '\x1b[#Q'
@cmd @cmd
def write_to_clipboard(data: Union[str, bytes], use_primary: bool = False) -> str: def write_to_clipboard(data: Union[str, bytes], use_primary: bool = False) -> str:
from base64 import standard_b64encode from base64 import standard_b64encode