mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-28 03:01:57 +02:00
Get automatic theme switching working
This commit is contained in:
@@ -583,6 +583,7 @@ def load_ref_map() -> dict[str, dict[str, str]]:
|
|||||||
def generate_constants() -> str:
|
def generate_constants() -> str:
|
||||||
from kittens.hints.main import DEFAULT_REGEX
|
from kittens.hints.main import DEFAULT_REGEX
|
||||||
from kittens.query_terminal.main import all_queries
|
from kittens.query_terminal.main import all_queries
|
||||||
|
from kitty.colors import ThemeFile
|
||||||
from kitty.config import option_names_for_completion
|
from kitty.config import option_names_for_completion
|
||||||
from kitty.fast_data_types import FILE_TRANSFER_CODE
|
from kitty.fast_data_types import FILE_TRANSFER_CODE
|
||||||
from kitty.options.utils import allowed_shell_integration_values, url_style_map
|
from kitty.options.utils import allowed_shell_integration_values, url_style_map
|
||||||
@@ -638,6 +639,9 @@ Select_by_word_characters: `{Options.select_by_word_characters}`, Wheel_scroll_m
|
|||||||
Shell: "{Options.shell}", Url_excluded_characters: "{Options.url_excluded_characters}",
|
Shell: "{Options.shell}", Url_excluded_characters: "{Options.url_excluded_characters}",
|
||||||
}}
|
}}
|
||||||
const OptionNames = {option_names}
|
const OptionNames = {option_names}
|
||||||
|
const DarkThemeFileName = "{ThemeFile.dark.value}"
|
||||||
|
const LightThemeFileName = "{ThemeFile.light.value}"
|
||||||
|
const NoPreferenceThemeFileName = "{ThemeFile.no_preference.value}"
|
||||||
''' # }}}
|
''' # }}}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package themes
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"kitty"
|
||||||
"maps"
|
"maps"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -521,6 +522,24 @@ func (self *handler) on_accepting_key_event(ev *loop.KeyEvent) error {
|
|||||||
self.lp.Quit(0)
|
self.lp.Quit(0)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scheme := func(name string) error {
|
||||||
|
ev.Handled = true
|
||||||
|
self.themes_list.CurrentTheme().SaveInFile(utils.ConfigDir(), name)
|
||||||
|
self.update_recent()
|
||||||
|
self.lp.Quit(0)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
if ev.MatchesCaseInsensitiveTextOrKey("d") || ev.MatchesPressOrRepeat("shift+d") {
|
||||||
|
return scheme(kitty.DarkThemeFileName)
|
||||||
|
}
|
||||||
|
if ev.MatchesCaseInsensitiveTextOrKey("l") || ev.MatchesPressOrRepeat("shift+l") {
|
||||||
|
return scheme(kitty.LightThemeFileName)
|
||||||
|
}
|
||||||
|
if ev.MatchesCaseInsensitiveTextOrKey("n") || ev.MatchesPressOrRepeat("shift+n") {
|
||||||
|
return scheme(kitty.NoPreferenceThemeFileName)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,6 +577,15 @@ func (self *handler) draw_accepting_screen() {
|
|||||||
self.lp.Printf(` %slace the theme file in %s but do not modify %s`, ac("P"), utils.ConfigDir(), kc)
|
self.lp.Printf(` %slace the theme file in %s but do not modify %s`, ac("P"), utils.ConfigDir(), kc)
|
||||||
self.lp.Println()
|
self.lp.Println()
|
||||||
self.lp.Println()
|
self.lp.Println()
|
||||||
|
self.lp.Printf(` Save as colors to use when the OS switches to:`)
|
||||||
|
self.lp.Println()
|
||||||
|
self.lp.Printf(` %sark mode`, ac("D"))
|
||||||
|
self.lp.Println()
|
||||||
|
self.lp.Printf(` %sight mode`, ac("L"))
|
||||||
|
self.lp.Println()
|
||||||
|
self.lp.Printf(` %so preference mode`, ac("N"))
|
||||||
|
self.lp.Println()
|
||||||
|
self.lp.Println()
|
||||||
self.lp.Printf(` %sbort and return to list of themes`, ac("A"))
|
self.lp.Printf(` %sbort and return to list of themes`, ac("A"))
|
||||||
self.lp.Println()
|
self.lp.Println()
|
||||||
self.lp.Println()
|
self.lp.Println()
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ from typing import (
|
|||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
Any,
|
Any,
|
||||||
Callable,
|
Callable,
|
||||||
Literal,
|
|
||||||
Optional,
|
Optional,
|
||||||
Union,
|
Union,
|
||||||
)
|
)
|
||||||
@@ -36,7 +35,7 @@ from .clipboard import (
|
|||||||
set_clipboard_string,
|
set_clipboard_string,
|
||||||
set_primary_selection,
|
set_primary_selection,
|
||||||
)
|
)
|
||||||
from .colors import ColorsSpec, TransparentBackgroundColors, patch_options_with_color_spec, theme_colors
|
from .colors import ColorSchemes, theme_colors
|
||||||
from .conf.utils import BadLine, KeyAction, to_cmdline
|
from .conf.utils import BadLine, KeyAction, to_cmdline
|
||||||
from .config import common_opts_as_dict, prepare_config_file_for_editing
|
from .config import common_opts_as_dict, prepare_config_file_for_editing
|
||||||
from .constants import (
|
from .constants import (
|
||||||
@@ -93,7 +92,6 @@ from .fast_data_types import (
|
|||||||
monotonic,
|
monotonic,
|
||||||
os_window_focus_counters,
|
os_window_focus_counters,
|
||||||
os_window_font_size,
|
os_window_font_size,
|
||||||
patch_global_colors,
|
|
||||||
redirect_mouse_handling,
|
redirect_mouse_handling,
|
||||||
ring_bell,
|
ring_bell,
|
||||||
run_with_activation_token,
|
run_with_activation_token,
|
||||||
@@ -2638,20 +2636,6 @@ class Boss:
|
|||||||
window.screen.disable_ligatures = strategy
|
window.screen.disable_ligatures = strategy
|
||||||
window.refresh()
|
window.refresh()
|
||||||
|
|
||||||
def patch_colors(self, spec: ColorsSpec, transparent_background_colors: TransparentBackgroundColors, configured: bool = False) -> None:
|
|
||||||
opts = get_options()
|
|
||||||
if configured:
|
|
||||||
patch_options_with_color_spec(opts, spec, transparent_background_colors)
|
|
||||||
for tm in self.all_tab_managers:
|
|
||||||
tm.tab_bar.patch_colors(spec)
|
|
||||||
tm.tab_bar.layout()
|
|
||||||
tm.mark_tab_bar_dirty()
|
|
||||||
t = tm.active_tab
|
|
||||||
if t is not None:
|
|
||||||
t.relayout_borders()
|
|
||||||
set_os_window_chrome(tm.os_window_id)
|
|
||||||
patch_global_colors(spec, configured)
|
|
||||||
|
|
||||||
def apply_new_options(self, opts: Options) -> None:
|
def apply_new_options(self, opts: Options) -> None:
|
||||||
from .fonts.box_drawing import set_scale
|
from .fonts.box_drawing import set_scale
|
||||||
# Update options storage
|
# Update options storage
|
||||||
@@ -3062,9 +3046,8 @@ class Boss:
|
|||||||
def sanitize_url_for_dispay_to_user(self, url: str) -> str:
|
def sanitize_url_for_dispay_to_user(self, url: str) -> str:
|
||||||
return sanitize_url_for_dispay_to_user(url)
|
return sanitize_url_for_dispay_to_user(url)
|
||||||
|
|
||||||
def on_system_color_scheme_change(self, appearance: Literal['light', 'dark', 'no_preference'], is_initial_value: bool) -> None:
|
def on_system_color_scheme_change(self, appearance: ColorSchemes, is_initial_value: bool) -> None:
|
||||||
if not is_initial_value and appearance != 'no_preference':
|
theme_colors.on_system_color_scheme_change(appearance, is_initial_value)
|
||||||
theme_colors.on_system_color_scheme_change(appearance)
|
|
||||||
|
|
||||||
@ac('win', '''
|
@ac('win', '''
|
||||||
Toggle to the tab matching the specified expression
|
Toggle to the tab matching the specified expression
|
||||||
|
|||||||
136
kitty/colors.py
136
kitty/colors.py
@@ -3,35 +3,60 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from typing import Iterable, Literal, Optional, Union
|
from enum import Enum
|
||||||
|
from typing import Iterable, Literal, Optional, Sequence, Union
|
||||||
|
|
||||||
from .config import parse_config
|
from .config import parse_config
|
||||||
from .constants import config_dir
|
from .constants import config_dir
|
||||||
from .fast_data_types import Color, get_boss, glfw_get_system_color_theme
|
from .fast_data_types import Color, get_boss, get_options, glfw_get_system_color_theme, patch_color_profiles, patch_global_colors, set_os_window_chrome
|
||||||
from .options.types import Options, nullable_colors
|
from .options.types import Options, nullable_colors
|
||||||
from .rgb import color_from_int
|
from .rgb import color_from_int
|
||||||
|
from .typing import WindowType
|
||||||
|
|
||||||
ColorsSpec = dict[str, Optional[int]]
|
ColorsSpec = dict[str, Optional[int]]
|
||||||
TransparentBackgroundColors = tuple[tuple[Color, float], ...]
|
TransparentBackgroundColors = tuple[tuple[Color, float], ...]
|
||||||
|
ColorSchemes = Literal['light', 'dark', 'no_preference']
|
||||||
|
|
||||||
|
|
||||||
|
class ThemeFile(Enum):
|
||||||
|
dark: str = 'dark-theme.auto.conf'
|
||||||
|
light: str = 'light-theme.auto.conf'
|
||||||
|
no_preference: str = 'no-preference-theme.auto.conf'
|
||||||
|
|
||||||
|
|
||||||
class ThemeColors:
|
class ThemeColors:
|
||||||
|
|
||||||
dark_mtime: float = -1
|
dark_mtime: int = -1
|
||||||
light_mtime: float = -1
|
light_mtime: int = -1
|
||||||
applied_theme: Literal['light', 'dark', ''] = ''
|
no_preference_mtime: int = -1
|
||||||
|
applied_theme: Literal['light', 'dark', 'no_preference', ''] = ''
|
||||||
|
|
||||||
def refresh(self) -> None:
|
def refresh(self) -> bool:
|
||||||
with suppress(FileNotFoundError), open(os.path.join(config_dir, 'dark-theme.conf')) as f:
|
found = False
|
||||||
mtime = os.stat(f.fileno()).st_mtime
|
with suppress(FileNotFoundError):
|
||||||
if mtime > self.dark_mtime:
|
for x in os.scandir(config_dir):
|
||||||
self.dark_spec, self.dark_tbc = parse_colors((f,))
|
if x.name == ThemeFile.dark.value:
|
||||||
self.dark_mtime = mtime
|
mtime = x.stat().st_mtime_ns
|
||||||
with suppress(FileNotFoundError), open(os.path.join(config_dir, 'light-theme.conf')) as f:
|
if mtime > self.dark_mtime:
|
||||||
mtime = os.stat(f.fileno()).st_mtime
|
with open(x.path) as f:
|
||||||
if mtime > self.light_mtime:
|
self.dark_spec, self.dark_tbc = parse_colors((f,))
|
||||||
self.light_spec, self.light_tbc = parse_colors((f,))
|
self.dark_mtime = mtime
|
||||||
self.light_mtime = mtime
|
found = True
|
||||||
|
elif x.name == ThemeFile.light.value:
|
||||||
|
mtime = x.stat().st_mtime_ns
|
||||||
|
if mtime > self.light_mtime:
|
||||||
|
with open(x.path) as f:
|
||||||
|
self.light_spec, self.light_tbc = parse_colors((f,))
|
||||||
|
self.light_mtime = mtime
|
||||||
|
found = True
|
||||||
|
elif x.name == ThemeFile.no_preference.value:
|
||||||
|
mtime = x.stat().st_mtime_ns
|
||||||
|
if mtime > self.no_preference_mtime:
|
||||||
|
with open(x.path) as f:
|
||||||
|
self.no_preference_spec, self.no_preference_tbc = parse_colors((f,))
|
||||||
|
self.no_preference_mtime = mtime
|
||||||
|
found = True
|
||||||
|
return found
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_dark_theme(self) -> bool:
|
def has_dark_theme(self) -> bool:
|
||||||
@@ -41,24 +66,56 @@ class ThemeColors:
|
|||||||
def has_light_theme(self) -> bool:
|
def has_light_theme(self) -> bool:
|
||||||
return self.light_mtime > -1
|
return self.light_mtime > -1
|
||||||
|
|
||||||
def patch_opts(self, opts: Options) -> None:
|
@property
|
||||||
|
def has_no_preference_theme(self) -> bool:
|
||||||
|
return self.no_preference_mtime > -1
|
||||||
|
|
||||||
|
def patch_opts(self, opts: Options, debug_rendering: bool = False) -> None:
|
||||||
|
from .utils import log_error
|
||||||
|
if debug_rendering:
|
||||||
|
log_error('Querying system for current color scheme')
|
||||||
which = glfw_get_system_color_theme()
|
which = glfw_get_system_color_theme()
|
||||||
|
if debug_rendering:
|
||||||
|
log_error('Current system color scheme:', which)
|
||||||
if which == 'dark' and self.has_dark_theme:
|
if which == 'dark' and self.has_dark_theme:
|
||||||
patch_options_with_color_spec(opts, self.dark_spec, self.dark_tbc)
|
patch_options_with_color_spec(opts, self.dark_spec, self.dark_tbc)
|
||||||
self.applied_theme = 'dark'
|
if debug_rendering:
|
||||||
|
log_error(f'Applied {which} color theme')
|
||||||
|
self.applied_theme = which
|
||||||
elif which == 'light' and self.has_light_theme:
|
elif which == 'light' and self.has_light_theme:
|
||||||
patch_options_with_color_spec(opts, self.light_spec, self.light_tbc)
|
patch_options_with_color_spec(opts, self.light_spec, self.light_tbc)
|
||||||
self.applied_theme = 'light'
|
if debug_rendering:
|
||||||
|
log_error(f'Applied {which} color theme')
|
||||||
|
self.applied_theme = which
|
||||||
|
elif which == 'no_preference' and self.has_no_preference_theme:
|
||||||
|
patch_options_with_color_spec(opts, self.no_preference_spec, self.no_preference_tbc)
|
||||||
|
if debug_rendering:
|
||||||
|
log_error(f'Applied {which} color theme')
|
||||||
|
self.applied_theme = which
|
||||||
|
|
||||||
def on_system_color_scheme_change(self, new_value: Literal['light', 'dark']) -> bool:
|
def on_system_color_scheme_change(self, new_value: ColorSchemes, is_initial_value: bool = False) -> bool:
|
||||||
|
if is_initial_value:
|
||||||
|
return False
|
||||||
|
from .utils import log_error
|
||||||
|
self.refresh()
|
||||||
boss = get_boss()
|
boss = get_boss()
|
||||||
if new_value == 'dark' and self.has_dark_theme:
|
if new_value == 'dark' and self.has_dark_theme:
|
||||||
boss.patch_colors(self.dark_spec, self.dark_tbc, True)
|
patch_colors(self.dark_spec, self.dark_tbc, True)
|
||||||
self.applied_theme = 'dark'
|
self.applied_theme = new_value
|
||||||
|
if boss.args.debug_rendering:
|
||||||
|
log_error(f'Applied color theme {new_value}')
|
||||||
return True
|
return True
|
||||||
if new_value == 'light' and self.has_light_theme:
|
if new_value == 'light' and self.has_light_theme:
|
||||||
boss.patch_colors(self.light_spec, self.light_tbc, True)
|
patch_colors(self.light_spec, self.light_tbc, True)
|
||||||
self.applied_theme = 'light'
|
self.applied_theme = new_value
|
||||||
|
if boss.args.debug_rendering:
|
||||||
|
log_error(f'Applied color theme {new_value}')
|
||||||
|
return True
|
||||||
|
if new_value == 'no_preference' and self.has_no_preference_theme:
|
||||||
|
patch_colors(self.no_preference_spec, self.no_preference_tbc, True)
|
||||||
|
self.applied_theme = new_value
|
||||||
|
if boss.args.debug_rendering:
|
||||||
|
log_error(f'Applied color theme {new_value}')
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -92,7 +149,6 @@ def parse_colors(args: Iterable[Union[str, Iterable[str]]]) -> tuple[ColorsSpec,
|
|||||||
|
|
||||||
|
|
||||||
def patch_options_with_color_spec(opts: Options, spec: ColorsSpec, transparent_background_colors: TransparentBackgroundColors) -> None:
|
def patch_options_with_color_spec(opts: Options, spec: ColorsSpec, transparent_background_colors: TransparentBackgroundColors) -> None:
|
||||||
|
|
||||||
for k, v in spec.items():
|
for k, v in spec.items():
|
||||||
if hasattr(opts, k):
|
if hasattr(opts, k):
|
||||||
if v is None:
|
if v is None:
|
||||||
@@ -101,3 +157,33 @@ def patch_options_with_color_spec(opts: Options, spec: ColorsSpec, transparent_b
|
|||||||
else:
|
else:
|
||||||
setattr(opts, k, color_from_int(v))
|
setattr(opts, k, color_from_int(v))
|
||||||
opts.transparent_background_colors = transparent_background_colors
|
opts.transparent_background_colors = transparent_background_colors
|
||||||
|
|
||||||
|
|
||||||
|
def patch_colors(
|
||||||
|
spec: ColorsSpec, transparent_background_colors: TransparentBackgroundColors, configured: bool = False,
|
||||||
|
windows: Optional[Sequence[WindowType]] = None
|
||||||
|
) -> None:
|
||||||
|
boss = get_boss()
|
||||||
|
if windows is None:
|
||||||
|
windows = tuple(boss.all_windows)
|
||||||
|
profiles = tuple(w.screen.color_profile for w in windows if w)
|
||||||
|
patch_color_profiles(spec, transparent_background_colors, profiles, configured)
|
||||||
|
opts = get_options()
|
||||||
|
if configured:
|
||||||
|
patch_options_with_color_spec(opts, spec, transparent_background_colors)
|
||||||
|
for tm in get_boss().all_tab_managers:
|
||||||
|
tm.tab_bar.patch_colors(spec)
|
||||||
|
tm.tab_bar.layout()
|
||||||
|
tm.mark_tab_bar_dirty()
|
||||||
|
t = tm.active_tab
|
||||||
|
if t is not None:
|
||||||
|
t.relayout_borders()
|
||||||
|
set_os_window_chrome(tm.os_window_id)
|
||||||
|
patch_global_colors(spec, configured)
|
||||||
|
default_bg_changed = 'background' in spec
|
||||||
|
boss = get_boss()
|
||||||
|
for w in windows:
|
||||||
|
if w:
|
||||||
|
if default_bg_changed:
|
||||||
|
boss.default_bg_changed_for(w.id)
|
||||||
|
w.refresh()
|
||||||
|
|||||||
@@ -249,8 +249,8 @@ class AppRunner:
|
|||||||
def __call__(self, opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = (), talk_fd: int = -1) -> None:
|
def __call__(self, opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = (), talk_fd: int = -1) -> None:
|
||||||
set_scale(opts.box_drawing_scale)
|
set_scale(opts.box_drawing_scale)
|
||||||
set_options(opts, is_wayland(), args.debug_rendering, args.debug_font_fallback)
|
set_options(opts, is_wayland(), args.debug_rendering, args.debug_font_fallback)
|
||||||
theme_colors.refresh()
|
if theme_colors.refresh():
|
||||||
theme_colors.patch_opts(opts)
|
theme_colors.patch_opts(opts, args.debug_rendering)
|
||||||
try:
|
try:
|
||||||
set_font_family(opts, add_builtin_nerd_font=True)
|
set_font_family(opts, add_builtin_nerd_font=True)
|
||||||
_run_app(opts, args, bad_lines, talk_fd)
|
_run_app(opts, args, bad_lines, talk_fd)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
from typing import TYPE_CHECKING, Dict, Optional
|
from typing import TYPE_CHECKING, Dict, Optional
|
||||||
|
|
||||||
from kitty.cli import emph
|
from kitty.cli import emph
|
||||||
from kitty.fast_data_types import Color, patch_color_profiles
|
from kitty.fast_data_types import Color
|
||||||
|
|
||||||
from .base import (
|
from .base import (
|
||||||
MATCH_TAB_OPTION,
|
MATCH_TAB_OPTION,
|
||||||
@@ -87,25 +87,18 @@ this option, any color arguments are ignored and :option:`kitten @ set-colors --
|
|||||||
return ans
|
return ans
|
||||||
|
|
||||||
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
|
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
|
||||||
|
from kitty.colors import patch_colors
|
||||||
windows = self.windows_for_payload(boss, window, payload_get)
|
windows = self.windows_for_payload(boss, window, payload_get)
|
||||||
colors: Dict[str, int | None] = payload_get('colors')
|
colors: Dict[str, int | None] = payload_get('colors')
|
||||||
tbc = colors.get('transparent_background_colors')
|
tbc = colors.get('transparent_background_colors')
|
||||||
if payload_get('reset'):
|
if payload_get('reset'):
|
||||||
colors = {k: None if v is None else int(v) for k, v in boss.color_settings_at_startup.items()}
|
colors = {k: None if v is None else int(v) for k, v in boss.color_settings_at_startup.items()}
|
||||||
profiles = tuple(w.screen.color_profile for w in windows if w)
|
|
||||||
if tbc:
|
if tbc:
|
||||||
from kitty.options.utils import transparent_background_colors
|
from kitty.options.utils import transparent_background_colors
|
||||||
parsed_tbc = transparent_background_colors(str(tbc))
|
parsed_tbc = transparent_background_colors(str(tbc))
|
||||||
else:
|
else:
|
||||||
parsed_tbc = ()
|
parsed_tbc = ()
|
||||||
patch_color_profiles(colors, parsed_tbc, profiles, payload_get('configured'))
|
patch_colors(colors, parsed_tbc, bool(payload_get('configured')), windows=windows)
|
||||||
boss.patch_colors(colors, parsed_tbc, payload_get('configured'))
|
|
||||||
default_bg_changed = 'background' in colors
|
|
||||||
for w in windows:
|
|
||||||
if w:
|
|
||||||
if default_bg_changed:
|
|
||||||
boss.default_bg_changed_for(w.id)
|
|
||||||
w.refresh()
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -586,15 +586,18 @@ func (self *Theme) SaveInDir(dirpath string) (err error) {
|
|||||||
return utils.AtomicUpdateFile(path, bytes.NewReader(utils.UnsafeStringToBytes(code)), 0o644)
|
return utils.AtomicUpdateFile(path, bytes.NewReader(utils.UnsafeStringToBytes(code)), 0o644)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Theme) SaveInConf(config_dir, reload_in, config_file_name string) (err error) {
|
func (self *Theme) SaveInFile(config_dir, config_file_name string) (err error) {
|
||||||
_ = os.MkdirAll(config_dir, 0o755)
|
_ = os.MkdirAll(config_dir, 0o755)
|
||||||
path := filepath.Join(config_dir, `current-theme.conf`)
|
path := filepath.Join(config_dir, config_file_name)
|
||||||
code, err := self.Code()
|
code, err := self.Code()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = utils.AtomicUpdateFile(path, bytes.NewReader(utils.UnsafeStringToBytes(code)), 0o644)
|
return utils.AtomicUpdateFile(path, bytes.NewReader(utils.UnsafeStringToBytes(code)), 0o644)
|
||||||
if err != nil {
|
}
|
||||||
|
|
||||||
|
func (self *Theme) SaveInConf(config_dir, reload_in, config_file_name string) (err error) {
|
||||||
|
if err = self.SaveInFile(config_dir, `current-theme.conf`); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
confpath := config_file_name
|
confpath := config_file_name
|
||||||
|
|||||||
Reference in New Issue
Block a user