When encountering errors in kitty.conf report them to the user instead of failing to start.
This commit is contained in:
parent
c6d3ede57e
commit
c660840c19
@ -114,6 +114,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
|||||||
- Use negative values for :opt:`mouse_hide_wait` to hide the mouse cursor
|
- Use negative values for :opt:`mouse_hide_wait` to hide the mouse cursor
|
||||||
immediately when pressing a key (:iss:`1534`)
|
immediately when pressing a key (:iss:`1534`)
|
||||||
|
|
||||||
|
- When encountering errors in :file:`kitty.conf` report them to the user
|
||||||
|
instead of failing to start.
|
||||||
|
|
||||||
|
|
||||||
0.13.3 [2019-01-19]
|
0.13.3 [2019-01-19]
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|||||||
@ -742,7 +742,7 @@ class Boss:
|
|||||||
self._run_kitten('ask', args)
|
self._run_kitten('ask', args)
|
||||||
|
|
||||||
def show_error(self, title, msg):
|
def show_error(self, title, msg):
|
||||||
self._run_kitten('show_error', ['--title', title], input_data=msg)
|
self._run_kitten('show_error', args=['--title', title], input_data=msg)
|
||||||
|
|
||||||
def do_set_tab_title(self, title, tab_id):
|
def do_set_tab_title(self, title, tab_id):
|
||||||
tm = self.active_tab_manager
|
tm = self.active_tab_manager
|
||||||
@ -1068,3 +1068,11 @@ class Boss:
|
|||||||
dbus_notification_activated(*args)
|
dbus_notification_activated(*args)
|
||||||
else:
|
else:
|
||||||
dbus_notification_created(*args)
|
dbus_notification_created(*args)
|
||||||
|
|
||||||
|
def show_bad_config_lines(self, bad_lines):
|
||||||
|
|
||||||
|
def format_bad_line(bad_line):
|
||||||
|
return '{}:{} in line: {}\n'.format(bad_line.number, bad_line.exception, bad_line.line)
|
||||||
|
|
||||||
|
msg = '\n'.join(map(format_bad_line, bad_lines)).rstrip()
|
||||||
|
self.show_error(_('Errors in kitty.conf'), msg)
|
||||||
|
|||||||
@ -710,7 +710,7 @@ def compare_opts(opts):
|
|||||||
compare_keymaps(final, initial)
|
compare_keymaps(final, initial)
|
||||||
|
|
||||||
|
|
||||||
def create_opts(args, debug_config=False):
|
def create_opts(args, debug_config=False, accumulate_bad_lines=None):
|
||||||
from .config import load_config
|
from .config import load_config
|
||||||
config = tuple(resolve_config(SYSTEM_CONF, defconf, args.config))
|
config = tuple(resolve_config(SYSTEM_CONF, defconf, args.config))
|
||||||
if debug_config:
|
if debug_config:
|
||||||
@ -729,7 +729,7 @@ def create_opts(args, debug_config=False):
|
|||||||
if config:
|
if config:
|
||||||
print(green('Loaded config files:'), ', '.join(config))
|
print(green('Loaded config files:'), ', '.join(config))
|
||||||
overrides = (a.replace('=', ' ', 1) for a in args.override or ())
|
overrides = (a.replace('=', ' ', 1) for a in args.override or ())
|
||||||
opts = load_config(*config, overrides=overrides)
|
opts = load_config(*config, overrides=overrides, accumulate_bad_lines=accumulate_bad_lines)
|
||||||
if debug_config:
|
if debug_config:
|
||||||
compare_opts(opts)
|
compare_opts(opts)
|
||||||
return opts
|
return opts
|
||||||
|
|||||||
@ -5,11 +5,13 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
from ..rgb import to_color as as_color
|
from ..rgb import to_color as as_color
|
||||||
from ..utils import log_error
|
from ..utils import log_error
|
||||||
|
|
||||||
key_pat = re.compile(r'([a-zA-Z][a-zA-Z0-9_-]*)\s+(.+)$')
|
key_pat = re.compile(r'([a-zA-Z][a-zA-Z0-9_-]*)\s+(.+)$')
|
||||||
|
BadLine = namedtuple('BadLine', 'number line exception')
|
||||||
|
|
||||||
|
|
||||||
def to_color(x):
|
def to_color(x):
|
||||||
@ -90,22 +92,28 @@ def parse_line(line, type_map, special_handling, ans, all_keys, base_path_for_in
|
|||||||
ans[key] = val
|
ans[key] = val
|
||||||
|
|
||||||
|
|
||||||
def _parse(lines, type_map, special_handling, ans, all_keys):
|
def _parse(lines, type_map, special_handling, ans, all_keys, accumulate_bad_lines=None):
|
||||||
name = getattr(lines, 'name', None)
|
name = getattr(lines, 'name', None)
|
||||||
if name:
|
if name:
|
||||||
base_path_for_includes = os.path.dirname(os.path.abspath(name))
|
base_path_for_includes = os.path.dirname(os.path.abspath(name))
|
||||||
else:
|
else:
|
||||||
from ..constants import config_dir
|
from ..constants import config_dir
|
||||||
base_path_for_includes = config_dir
|
base_path_for_includes = config_dir
|
||||||
for line in lines:
|
for i, line in enumerate(lines):
|
||||||
parse_line(line, type_map, special_handling, ans, all_keys, base_path_for_includes)
|
try:
|
||||||
|
parse_line(line, type_map, special_handling, ans, all_keys, base_path_for_includes)
|
||||||
|
except Exception as e:
|
||||||
|
if accumulate_bad_lines is None:
|
||||||
|
raise
|
||||||
|
accumulate_bad_lines.append(BadLine(i + 1, line.rstrip(), e))
|
||||||
|
|
||||||
|
|
||||||
def parse_config_base(
|
def parse_config_base(
|
||||||
lines, defaults, type_map, special_handling, ans, check_keys=True
|
lines, defaults, type_map, special_handling, ans, check_keys=True,
|
||||||
|
accumulate_bad_lines=None
|
||||||
):
|
):
|
||||||
all_keys = defaults._asdict() if check_keys else None
|
all_keys = defaults._asdict() if check_keys else None
|
||||||
_parse(lines, type_map, special_handling, ans, all_keys)
|
_parse(lines, type_map, special_handling, ans, all_keys, accumulate_bad_lines)
|
||||||
|
|
||||||
|
|
||||||
def create_options_class(keys):
|
def create_options_class(keys):
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
from . import fast_data_types as defines
|
from . import fast_data_types as defines
|
||||||
from .conf.definition import as_conf_file, config_lines
|
from .conf.definition import as_conf_file, config_lines
|
||||||
@ -439,7 +440,7 @@ def option_names_for_completion():
|
|||||||
yield from special_handlers
|
yield from special_handlers
|
||||||
|
|
||||||
|
|
||||||
def parse_config(lines, check_keys=True):
|
def parse_config(lines, check_keys=True, accumulate_bad_lines=None):
|
||||||
ans = {'symbol_map': {}, 'keymap': {}, 'sequence_map': {}, 'key_definitions': [], 'env': {}}
|
ans = {'symbol_map': {}, 'keymap': {}, 'sequence_map': {}, 'key_definitions': [], 'env': {}}
|
||||||
parse_config_base(
|
parse_config_base(
|
||||||
lines,
|
lines,
|
||||||
@ -447,7 +448,8 @@ def parse_config(lines, check_keys=True):
|
|||||||
type_map,
|
type_map,
|
||||||
special_handling,
|
special_handling,
|
||||||
ans,
|
ans,
|
||||||
check_keys=check_keys
|
check_keys=check_keys,
|
||||||
|
accumulate_bad_lines=accumulate_bad_lines
|
||||||
)
|
)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
@ -617,8 +619,11 @@ def finalize_keys(opts):
|
|||||||
opts.sequence_map = sequence_map
|
opts.sequence_map = sequence_map
|
||||||
|
|
||||||
|
|
||||||
def load_config(*paths, overrides=None):
|
def load_config(*paths, overrides=None, accumulate_bad_lines=None):
|
||||||
opts = _load_config(Options, defaults, parse_config, merge_configs, *paths, overrides=overrides)
|
parser = parse_config
|
||||||
|
if accumulate_bad_lines is not None:
|
||||||
|
parser = partial(parse_config, accumulate_bad_lines=accumulate_bad_lines)
|
||||||
|
opts = _load_config(Options, defaults, parser, merge_configs, *paths, overrides=overrides)
|
||||||
finalize_keys(opts)
|
finalize_keys(opts)
|
||||||
if opts.background_opacity < 1.0 and opts.macos_titlebar_color:
|
if opts.background_opacity < 1.0 and opts.macos_titlebar_color:
|
||||||
log_error('Cannot use both macos_titlebar_color and background_opacity')
|
log_error('Cannot use both macos_titlebar_color and background_opacity')
|
||||||
|
|||||||
@ -115,7 +115,7 @@ def get_new_os_window_trigger(opts):
|
|||||||
return new_os_window_trigger
|
return new_os_window_trigger
|
||||||
|
|
||||||
|
|
||||||
def _run_app(opts, args):
|
def _run_app(opts, args, bad_lines=()):
|
||||||
new_os_window_trigger = get_new_os_window_trigger(opts)
|
new_os_window_trigger = get_new_os_window_trigger(opts)
|
||||||
if is_macos and opts.macos_custom_beam_cursor:
|
if is_macos and opts.macos_custom_beam_cursor:
|
||||||
set_custom_ibeam_cursor()
|
set_custom_ibeam_cursor()
|
||||||
@ -132,18 +132,20 @@ def _run_app(opts, args):
|
|||||||
args.cls or appname, load_all_shaders)
|
args.cls or appname, load_all_shaders)
|
||||||
boss = Boss(window_id, opts, args, cached_values, new_os_window_trigger)
|
boss = Boss(window_id, opts, args, cached_values, new_os_window_trigger)
|
||||||
boss.start()
|
boss.start()
|
||||||
|
if bad_lines:
|
||||||
|
boss.show_bad_config_lines(bad_lines)
|
||||||
try:
|
try:
|
||||||
boss.child_monitor.main_loop()
|
boss.child_monitor.main_loop()
|
||||||
finally:
|
finally:
|
||||||
boss.destroy()
|
boss.destroy()
|
||||||
|
|
||||||
|
|
||||||
def run_app(opts, args):
|
def run_app(opts, args, bad_lines=()):
|
||||||
set_scale(opts.box_drawing_scale)
|
set_scale(opts.box_drawing_scale)
|
||||||
set_options(opts, is_wayland, args.debug_gl, args.debug_font_fallback)
|
set_options(opts, is_wayland, args.debug_gl, args.debug_font_fallback)
|
||||||
set_font_family(opts, debug_font_matching=args.debug_font_fallback)
|
set_font_family(opts, debug_font_matching=args.debug_font_fallback)
|
||||||
try:
|
try:
|
||||||
_run_app(opts, args)
|
_run_app(opts, args, bad_lines)
|
||||||
finally:
|
finally:
|
||||||
free_font_data() # must free font data before glfw/freetype/fontconfig/opengl etc are finalized
|
free_font_data() # must free font data before glfw/freetype/fontconfig/opengl etc are finalized
|
||||||
|
|
||||||
@ -262,12 +264,13 @@ def _main():
|
|||||||
talk_to_instance(args)
|
talk_to_instance(args)
|
||||||
return
|
return
|
||||||
init_glfw(args.debug_keyboard) # needed for parsing native keysyms
|
init_glfw(args.debug_keyboard) # needed for parsing native keysyms
|
||||||
opts = create_opts(args)
|
bad_lines = []
|
||||||
|
opts = create_opts(args, accumulate_bad_lines=bad_lines)
|
||||||
setup_environment(opts, args)
|
setup_environment(opts, args)
|
||||||
try:
|
try:
|
||||||
with setup_profiling(args):
|
with setup_profiling(args):
|
||||||
# Avoid needing to launch threads to reap zombies
|
# Avoid needing to launch threads to reap zombies
|
||||||
run_app(opts, args)
|
run_app(opts, args, bad_lines)
|
||||||
finally:
|
finally:
|
||||||
glfw_terminate()
|
glfw_terminate()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user