mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-20 11:07:38 +03:00
Allow reloading conf in all kitty instances as well
This commit is contained in:
parent
a49f6799de
commit
ca9143bebc
@ -12,12 +12,15 @@
|
||||
import tempfile
|
||||
import zipfile
|
||||
from contextlib import suppress
|
||||
from typing import Any, Callable, Dict, Iterator, Match, Optional, Tuple, Union
|
||||
from typing import (
|
||||
Any, Callable, Dict, Iterable, Iterator, List, Match, Optional, Tuple,
|
||||
Union
|
||||
)
|
||||
from urllib.error import HTTPError
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
from kitty.config import atomic_save, parse_config
|
||||
from kitty.constants import cache_dir, config_dir
|
||||
from kitty.constants import cache_dir, config_dir, is_macos
|
||||
from kitty.options.types import Options as KittyOptions
|
||||
from kitty.rgb import Color
|
||||
|
||||
@ -27,6 +30,28 @@
|
||||
MARK_AFTER = '\033[39m'
|
||||
|
||||
|
||||
def is_kitty_gui(cmd: List[str]) -> bool:
|
||||
if not cmd:
|
||||
return False
|
||||
if os.path.basename(cmd[0]) != 'kitty':
|
||||
return False
|
||||
if len(cmd) == 1:
|
||||
return True
|
||||
if '+' in cmd or '@' in cmd or cmd[1].startswith('+') or cmd[1].startswith('@'):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def get_all_processes() -> Iterable[int]:
|
||||
if is_macos:
|
||||
from kitty.fast_data_types import get_all_processes as f
|
||||
yield from f()
|
||||
else:
|
||||
for c in os.listdir('/proc'):
|
||||
if c.isdigit():
|
||||
yield int(c)
|
||||
|
||||
|
||||
def patch_conf(raw: str) -> str:
|
||||
addition = '# BEGIN_KITTY_THEME\ninclude current-theme.conf\n# END_KITTY_THEME'
|
||||
nraw, num = re.subn(r'^# BEGIN_KITTY_THEME.+?# END_KITTY_THEME', addition, raw, flags=re.MULTILINE | re.DOTALL)
|
||||
@ -254,7 +279,7 @@ def kitty_opts(self) -> KittyOptions:
|
||||
def save_in_dir(self, dirpath: str) -> None:
|
||||
atomic_save(self.raw.encode('utf-8'), os.path.join(dirpath, f'{self.name}.conf'))
|
||||
|
||||
def save_in_conf(self, confdir: str) -> None:
|
||||
def save_in_conf(self, confdir: str, reload_in: str) -> None:
|
||||
atomic_save(self.raw.encode('utf-8'), os.path.join(confdir, 'current-theme.conf'))
|
||||
confpath = os.path.join(confdir, 'kitty.conf')
|
||||
try:
|
||||
@ -267,8 +292,18 @@ def save_in_conf(self, confdir: str) -> None:
|
||||
with open(confpath + '.bak', 'w') as f:
|
||||
f.write(raw)
|
||||
atomic_save(nraw.encode('utf-8'), confpath)
|
||||
if 'KITTY_PID' in os.environ:
|
||||
os.kill(int(os.environ['KITTY_PID']), signal.SIGUSR1)
|
||||
if reload_in == 'parent':
|
||||
if 'KITTY_PID' in os.environ:
|
||||
os.kill(int(os.environ['KITTY_PID']), signal.SIGUSR1)
|
||||
elif reload_in == 'all':
|
||||
from kitty.child import cmdline_of_process # type: ignore
|
||||
for pid in get_all_processes():
|
||||
try:
|
||||
cmd = cmdline_of_process(pid)
|
||||
except Exception:
|
||||
continue
|
||||
if cmd and is_kitty_gui(cmd):
|
||||
os.kill(pid, signal.SIGUSR1)
|
||||
|
||||
|
||||
class Themes:
|
||||
|
@ -466,7 +466,7 @@ def on_accepting_key_event(self, key_event: KeyEventType, in_bracketed_paste: bo
|
||||
self.quit_loop(0)
|
||||
return
|
||||
if key_event.matches('m'):
|
||||
self.themes_list.current_theme.save_in_conf(config_dir)
|
||||
self.themes_list.current_theme.save_in_conf(config_dir, self.cli_opts.reload_in)
|
||||
self.update_recent()
|
||||
self.quit_loop(0)
|
||||
return
|
||||
@ -520,6 +520,20 @@ def on_eot(self) -> None:
|
||||
is not available.
|
||||
|
||||
|
||||
--reload-in
|
||||
default=parent
|
||||
choices=none,parent,all
|
||||
By default, this kitten will signal only the parent kitty instance it is
|
||||
running in to reload its config, after making changes. Use this option
|
||||
to instead either not reload the config at all or in all running
|
||||
kitty instances.
|
||||
|
||||
|
||||
--dump-theme
|
||||
type=bool-set
|
||||
default=false
|
||||
When running non-interactively, dump the specified theme to STDOUT
|
||||
instead of changing kitty.conf.
|
||||
'''.format
|
||||
|
||||
|
||||
@ -536,7 +550,10 @@ def non_interactive(cli_opts: ThemesCLIOptions, theme_name: str) -> None:
|
||||
theme = themes[theme_name]
|
||||
except KeyError:
|
||||
raise SystemExit(f'No theme named: {theme_name}')
|
||||
theme.save_in_conf(config_dir)
|
||||
if cli_opts.dump_theme:
|
||||
print(theme.raw)
|
||||
return
|
||||
theme.save_in_conf(config_dir, cli_opts.reload_in)
|
||||
|
||||
|
||||
def main(args: List[str]) -> None:
|
||||
@ -548,7 +565,7 @@ def main(args: List[str]) -> None:
|
||||
input(_('Press Enter to quit'))
|
||||
return None
|
||||
if len(items) > 1:
|
||||
raise SystemExit('At most one theme name must be specified')
|
||||
items = [' '.join(items[1:])]
|
||||
if len(items) == 1:
|
||||
return non_interactive(cli_opts, items[0])
|
||||
|
||||
|
@ -1213,3 +1213,7 @@ class OSWindowSize(TypedDict):
|
||||
|
||||
def get_os_window_size(os_window_id: int) -> Optional[OSWindowSize]:
|
||||
pass
|
||||
|
||||
|
||||
def get_all_processes() -> Tuple[int, ...]:
|
||||
pass
|
||||
|
@ -34,6 +34,25 @@ get_argmax() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
get_all_processes(PyObject *self UNUSED, PyObject *args UNUSED) {
|
||||
pid_t num = proc_listallpids(NULL, 0);
|
||||
if (num <= 0) return PyTuple_New(0);
|
||||
size_t sz = sizeof(pid_t) * num * 2;
|
||||
pid_t *buf = malloc(sz);
|
||||
if (!buf) return PyErr_NoMemory();
|
||||
num = proc_listallpids(buf, sz);
|
||||
if (num <= 0) { free(buf); return PyTuple_New(0); }
|
||||
PyObject *ans = PyTuple_New(num);
|
||||
if (!ans) { free(buf); return NULL; }
|
||||
for (pid_t i = 0; i < num; i++) {
|
||||
long long pid = buf[i];
|
||||
PyObject *t = PyLong_FromLongLong(pid);
|
||||
if (!t) { free(buf); Py_CLEAR(ans); return NULL; }
|
||||
PyTuple_SET_ITEM(ans, i, t);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
cmdline_of_process(PyObject *self UNUSED, PyObject *pid_) {
|
||||
@ -255,6 +274,7 @@ static PyMethodDef module_methods[] = {
|
||||
{"cwd_of_process", (PyCFunction)cwd_of_process, METH_O, ""},
|
||||
{"cmdline_of_process", (PyCFunction)cmdline_of_process, METH_O, ""},
|
||||
{"environ_of_process", (PyCFunction)environ_of_process, METH_O, ""},
|
||||
{"get_all_processes", (PyCFunction)get_all_processes, METH_NOARGS, ""},
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user