diff --git a/docs/changelog.rst b/docs/changelog.rst index 6eb056b46..038c634e6 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -79,6 +79,9 @@ Detailed list of changes - macOS: Allow opening text files, images and directories with kitty when launched using "Open with" in Finder (:iss:`4460`) +- Allow including config files matching glob patterns in :file:`kitty.conf` + (:iss:`4533`) + - Shell integration: Fix bash integration not working when ``PROMPT_COMMAND`` is used to change the prompt variables (:iss:`4476`) diff --git a/docs/conf.rst b/docs/conf.rst index 067d736d4..50d37bc56 100644 --- a/docs/conf.rst +++ b/docs/conf.rst @@ -25,12 +25,14 @@ character. This works only if the ``#`` character is the first character in the line. You can include secondary config files via the :code:`include` directive. If -you use a relative path for include, it is resolved with respect to the +you use a relative path for :code:`include`, it is resolved with respect to the location of the current config file. Note that environment variables are expanded, so :code:`${USER}.conf` becomes :file:`name.conf` if -:code:`USER=name`. For example:: +:code:`USER=name`. Also, you can use :code:`globinclude` to include files +matching a shell glob pattern. For example:: include other.conf + globinclude kitty.d/**/*.conf .. note:: Syntax highlighting for :file:`kitty.conf` in vim is available via diff --git a/kitty/conf/utils.py b/kitty/conf/utils.py index 716ae519e..6a940cd2d 100644 --- a/kitty/conf/utils.py +++ b/kitty/conf/utils.py @@ -170,24 +170,30 @@ def parse_line( log_error(f'Ignoring invalid config line: {line}') return key, val = m.groups() - if key == 'include': + if key in ('include', 'globinclude'): val = os.path.expandvars(os.path.expanduser(val.strip())) - if not os.path.isabs(val): - val = os.path.join(base_path_for_includes, val) - try: - with open(val, encoding='utf-8', errors='replace') as include: - with currently_parsing.set_file(val): - _parse(include, parse_conf_item, ans, accumulate_bad_lines) - except FileNotFoundError: - log_error( - 'Could not find included config file: {}, ignoring'. - format(val) - ) - except OSError: - log_error( - 'Could not read from included config file: {}, ignoring'. - format(val) - ) + if key == 'globinclude': + from pathlib import Path + vals = tuple(map(lambda x: str(os.fspath(x)), Path(base_path_for_includes).glob(val))) + else: + if not os.path.isabs(val): + val = os.path.join(base_path_for_includes, val) + vals = (val,) + for val in vals: + try: + with open(val, encoding='utf-8', errors='replace') as include: + with currently_parsing.set_file(val): + _parse(include, parse_conf_item, ans, accumulate_bad_lines) + except FileNotFoundError: + log_error( + 'Could not find included config file: {}, ignoring'. + format(val) + ) + except OSError: + log_error( + 'Could not read from included config file: {}, ignoring'. + format(val) + ) return if not parse_conf_item(key, val, ans): log_error(f'Ignoring unknown config key: {key}')