Implement auto reload of config

This commit is contained in:
Kovid Goyal 2026-04-16 14:39:51 +05:30
parent efbfbb49f9
commit e9f3844f64
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
8 changed files with 29 additions and 4 deletions

View file

@ -181,6 +181,8 @@ Detailed list of changes
- Draw a progress bar at the top of the window when a program reports progress using the OSC 9;4 escape sequence, controlled by :opt:`progress_bar` (:iss:`9777`)
- Automatically reload configuration on changes, controlled by :opt:`auto_reload_config`
- Allow specifying multiple background images for :opt:`background_image` that are stored on GPU to allow fast image switching (:pull:`9836`)
- :doc:`Remote control <remote-control>`: Expose :code:`session_name` and :code:`last_focused_at` in the output of ``kitten @ ls`` for each window (:iss:`9732`, :iss:`9799`)

View file

@ -16,7 +16,8 @@ frames-per-second. See below for an overview of all customization possibilities.
You can open the config file within |kitty| by pressing :sc:`edit_config_file`
(:kbd:`⌘+,` on macOS). A :file:`kitty.conf` with commented default
configurations and descriptions will be created if the file does not exist.
You can reload the config file within |kitty| by pressing
The configuration is automatically reloaded when modified, controlled by
:opt:`auto_reload_config`. You can manually reload the config by pressing
:sc:`reload_config_file` (:kbd:`⌃+⌘+,` on macOS) or sending |kitty| the
``SIGUSR1`` signal with ``kill -SIGUSR1 $KITTY_PID``. You can also display the
current configuration by pressing :sc:`debug_config` (:kbd:`⌥+⌘+,` on macOS).

View file

@ -1390,10 +1390,15 @@ class Boss:
else:
self.startup_first_child(first_os_window_id, startup_sessions=startup_sessions)
if get_options().update_check_interval > 0 and not self.update_check_started and getattr(sys, 'frozen', False):
if (opts := get_options()).update_check_interval > 0 and not self.update_check_started and getattr(sys, 'frozen', False):
from .update_check import run_update_check
run_update_check(get_options().update_check_interval * 60 * 60)
self.update_check_started = True
if opts.auto_reload_config >= 0 and not hasattr(self, 'config_reload_watcher_process'):
self.config_reload_watcher_process = subprocess.Popen(
[kitten_exe(), '__watch_conf__', str(os.getpid()), str(int(opts.auto_reload_config * 1000))] +
list(opts.all_config_paths), stdin=subprocess.PIPE)
def handle_window_title_bar_mouse(self, os_window_id: int, window_id: int, x: float, y: float, button: int, modifiers: int, action: int) -> None:
if tm := self.os_window_map.get(os_window_id):

View file

@ -2393,6 +2393,15 @@ reloading the config is not supported.
'''
)
opt('auto_reload_config', '0.1', option_type='float', long_text='''
Automatically reload configuration files when they are changed. The setting
is the number of seconds to wait before reloading the config files. This allows
multiple changes to be debounced. Use a negative value to disable automatic reload.
You can manually reload with :sc:`reload_config_file`. Note that automatic
reload works only if the :file:`kitty.conf` already exists when kitty is started.
Changes to this setting by reloading configuration are ignored.
''')
opt('startup_session', 'none',
option_type='config_or_absolute_path',
long_text='''

View file

@ -71,6 +71,9 @@ class Parser:
choices_for_allow_remote_control = frozenset(('password', 'socket-only', 'socket', 'no', 'n', 'false', 'yes', 'y', 'true'))
def auto_reload_config(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['auto_reload_config'] = float(val)
def background(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['background'] = to_color(val)

View file

@ -53,6 +53,7 @@ option_names = (
'allow_cloning',
'allow_hyperlinks',
'allow_remote_control',
'auto_reload_config',
'background',
'background_blur',
'background_image',
@ -527,6 +528,7 @@ class Options:
allow_cloning: choices_for_allow_cloning = 'ask'
allow_hyperlinks: int = 1
allow_remote_control: choices_for_allow_remote_control = 'no'
auto_reload_config: float = 0.1
background: Color = Color(0, 0, 0)
background_blur: int = 0
background_image: tuple[str, ...] = ()

View file

@ -37,6 +37,7 @@ import (
"github.com/kovidgoyal/kitty/tools/cmd/update_self"
"github.com/kovidgoyal/kitty/tools/tui"
"github.com/kovidgoyal/kitty/tools/utils/images"
"github.com/kovidgoyal/kitty/tools/watch"
)
var _ = fmt.Print
@ -135,7 +136,7 @@ func KittyToolEntryPoints(root *cli.Command) {
},
})
// __watch_conf__
watch.EntryPoint(root)
// __convert_image__
images.ConvertEntryPoint(root)
// __atexit__

View file

@ -27,7 +27,9 @@ func watch_dirs(ctx context.Context, paths []string, debounce time.Duration, eve
fswatcher.WithCooldown(debounce),
}
for _, path := range paths {
opts = append(opts, fswatcher.WithPath(path))
if unix.Access(path, unix.R_OK|unix.X_OK) == nil {
opts = append(opts, fswatcher.WithPath(path))
}
}
w, err := fswatcher.New(opts...)
if err != nil {