diff --git a/kittens/themes/collection.py b/kittens/themes/collection.py index cd0f6343c..64081552b 100644 --- a/kittens/themes/collection.py +++ b/kittens/themes/collection.py @@ -23,6 +23,11 @@ from kitty.rgb import Color from ..choose.main import match +def set_comment_in_zip_file(path: str, data: str) -> None: + with zipfile.ZipFile(path, 'a') as zf: + zf.comment = data.encode('utf-8') + + def fetch_themes( name: str = 'kitty-themes', url: str = 'https://codeload.github.com/kovidgoyal/kitty-themes/zip/master' @@ -34,6 +39,9 @@ def fetch_themes( self.etag = '' self.timestamp = now + def __str__(self) -> str: + return json.dumps({'etag': self.etag, 'timestamp': self.timestamp.isoformat()}) + dest_path = os.path.join(cache_dir(), f'{name}.zip') m = Metadata() with suppress(Exception), zipfile.ZipFile(dest_path, 'r') as zf: @@ -43,12 +51,14 @@ def fetch_themes( if (now - m.timestamp).days < 1: return dest_path rq = Request(url) + m.timestamp = now if m.etag: rq.add_header('If-None-Match', m.etag) try: res = urlopen(rq, timeout=30) except HTTPError as e: if m.etag and e.code == http.HTTPStatus.NOT_MODIFIED: + set_comment_in_zip_file(dest_path, str(m)) return dest_path raise m.etag = res.headers.get('etag') or '' @@ -59,8 +69,7 @@ def fetch_themes( needs_delete = True shutil.copyfileobj(res, f) f.flush() - with zipfile.ZipFile(f.name, 'a') as zf: - zf.comment = json.dumps({'etag': m.etag, 'timestamp': m.timestamp.isoformat()}).encode('utf-8') + set_comment_in_zip_file(f.name, str(m)) os.replace(f.name, dest_path) needs_delete = False finally: diff --git a/kittens/themes/main.py b/kittens/themes/main.py index d7b8a7a34..4dec1e313 100644 --- a/kittens/themes/main.py +++ b/kittens/themes/main.py @@ -53,6 +53,11 @@ def create_recent_filter(names: Iterable[str]) -> Callable[[Theme], bool]: return recent_filter +def mark_shortcut(text: str, acc: str) -> str: + acc_idx = text.lower().index(acc.lower()) + return text[:acc_idx] + styled(text[acc_idx], underline='straight', bold=True, fg_intense=True) + text[acc_idx+1:] + + class ThemesList: def __init__(self) -> None: @@ -204,19 +209,19 @@ class ThemesHandler(Handler): def draw_tab_bar(self) -> None: self.print(styled(' ' * self.screen_size.cols, reverse=True), end='\r') - def draw_tab(text: str, name: str, acc_idx: int = 0) -> None: + def draw_tab(text: str, name: str, acc: str) -> None: is_active = name == self.current_category if is_active: text = styled(f'{text} #{len(self.themes_list)}', italic=True) else: - text = text[:acc_idx] + styled(text[acc_idx], underline='straight', underline_color='red', bold=True, fg_intense=True) + text[acc_idx+1:] + text = mark_shortcut(text, acc) - self.write(styled(f' {text} ', reverse=not is_active)) + self.cmd.styled(f' {text} ', reverse=not is_active) - draw_tab('All', 'all') - draw_tab('Dark', 'dark') - draw_tab('Light', 'light') - draw_tab('Recent', 'recent') + draw_tab('All', 'all', 'a') + draw_tab('Dark', 'dark', 'd') + draw_tab('Light', 'light', 'l') + draw_tab('Recent', 'recent', 'r') self.cmd.sgr('0') self.print()