Implement placing of selected theme in kitty config dir

This commit is contained in:
Kovid Goyal 2021-08-07 15:04:32 +05:30
parent 2c96727c45
commit d01ac17334
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 54 additions and 2 deletions

View File

@ -15,7 +15,7 @@ from typing import Any, Callable, Dict, Iterator, Match, Optional, Tuple, Union
from urllib.error import HTTPError from urllib.error import HTTPError
from urllib.request import Request, urlopen from urllib.request import Request, urlopen
from kitty.config import parse_config from kitty.config import atomic_save, parse_config
from kitty.constants import cache_dir, config_dir from kitty.constants import cache_dir, config_dir
from kitty.options.types import Options as KittyOptions from kitty.options.types import Options as KittyOptions
from kitty.rgb import Color from kitty.rgb import Color
@ -198,6 +198,9 @@ class Theme:
self._opts = KittyOptions(options_dict=parse_config(self.raw.splitlines())) self._opts = KittyOptions(options_dict=parse_config(self.raw.splitlines()))
return self._opts return self._opts
def save_in_dir(self, dirpath: str) -> None:
atomic_save(self.raw.encode('utf-8'), os.path.join(dirpath, f'{self.name}.conf'))
class Themes: class Themes:

View File

@ -13,6 +13,7 @@ from typing import (
from kitty.cli import create_default_opts from kitty.cli import create_default_opts
from kitty.config import cached_values_for from kitty.config import cached_values_for
from kitty.constants import config_dir
from kitty.fast_data_types import truncate_point_for_length, wcswidth from kitty.fast_data_types import truncate_point_for_length, wcswidth
from kitty.rgb import color_as_sharp, color_from_int from kitty.rgb import color_as_sharp, color_from_int
from kitty.typing import KeyEventType from kitty.typing import KeyEventType
@ -42,6 +43,7 @@ class State(Enum):
fetching = auto() fetching = auto()
browsing = auto() browsing = auto()
searching = auto() searching = auto()
accepting = auto()
def dark_filter(q: Theme) -> bool: def dark_filter(q: Theme) -> bool:
@ -392,6 +394,12 @@ class ThemesHandler(Handler):
return self.next(delta=3 - self.screen_size.rows, allow_wrapping=False) return self.next(delta=3 - self.screen_size.rows, allow_wrapping=False)
if key_event.matches('s') or key_event.matches('/'): if key_event.matches('s') or key_event.matches('/'):
return self.start_search() return self.start_search()
if key_event.matches('c') or key_event.matches('enter'):
if not self.themes_list:
self.cmd.beep()
return
self.state = State.accepting
return self.draw_screen()
def start_search(self) -> None: def start_search(self) -> None:
self.line_edit.clear() self.line_edit.clear()
@ -412,6 +420,42 @@ class ThemesHandler(Handler):
self.cmd.bell() self.cmd.bell()
# }}} # }}}
# Accepting {{{
def draw_accepting_screen(self) -> None:
name = self.themes_list.current_theme.name
name = styled(name, bold=True, fg="green")
kc = styled('kitty.conf', italic=True)
def ac(x: str) -> str:
return styled(x, fg='red')
self.cmd.set_line_wrapping(True)
self.print(f'You have chosen the {name} theme')
self.print()
self.print('What would you like to do?')
self.print()
self.print(' ', f'{ac("M")}odify {kc} to load', styled(name, bold=True, fg="green"))
self.print()
self.print(' ', f'{ac("P")}lace the theme file in {config_dir} but do not modify {kc}')
self.print()
self.print(' ', f'{ac("A")}bort and return to list of themes')
self.print()
self.print(' ', f'{ac("Q")}uit')
def on_accepting_key_event(self, key_event: KeyEventType, in_bracketed_paste: bool = False) -> None:
if key_event.matches('q') or key_event.matches('esc'):
self.quit_loop(0)
return
if key_event.matches('a'):
self.state = State.browsing
self.draw_screen()
return
if key_event.matches('p'):
self.themes_list.current_theme.save_in_dir(config_dir)
self.quit_loop(0)
return
# }}}
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)
@ -419,15 +463,20 @@ class ThemesHandler(Handler):
self.on_browsing_key_event(key_event, in_bracketed_paste) self.on_browsing_key_event(key_event, in_bracketed_paste)
elif self.state is State.searching: elif self.state is State.searching:
self.on_searching_key_event(key_event, in_bracketed_paste) self.on_searching_key_event(key_event, in_bracketed_paste)
elif self.state is State.accepting:
self.on_accepting_key_event(key_event, in_bracketed_paste)
def draw_screen(self) -> None: def draw_screen(self) -> None:
with self.pending_update(): with self.pending_update():
self.cmd.clear_screen() self.cmd.clear_screen()
self.enforce_cursor_state() self.enforce_cursor_state()
self.cmd.set_line_wrapping(False)
if self.state is State.fetching: if self.state is State.fetching:
self.draw_fetching_screen() self.draw_fetching_screen()
elif self.state in (State.browsing, State.searching): elif self.state in (State.browsing, State.searching):
self.draw_browsing_screen() self.draw_browsing_screen()
elif self.state is State.accepting:
self.draw_accepting_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

@ -40,7 +40,7 @@ def atomic_save(data: bytes, path: str) -> None:
try: try:
with os.fdopen(fd, 'wb') as f: with os.fdopen(fd, 'wb') as f:
f.write(data) f.write(data)
os.rename(p, path) os.replace(p, path)
finally: finally:
try: try:
os.remove(p) os.remove(p)