Wire up config infrastructure for diff kitten

This commit is contained in:
Kovid Goyal 2018-04-22 21:44:47 +05:30
parent aa18429a8c
commit b5da109e7f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
7 changed files with 144 additions and 33 deletions

View File

@ -2,8 +2,78 @@
# vim:fileencoding=utf-8 # vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import os
from kitty.config_utils import (
init_config, load_config as _load_config, merge_dicts, parse_config_base,
resolve_config, to_color
)
from kitty.constants import config_dir
defaults = None
default_config_path = os.path.join(
os.path.dirname(os.path.abspath(__file__)), 'diff.conf'
)
formats = { formats = {
'title': '', 'title': '',
'margin': '', 'margin': '',
'text': '', 'text': '',
} }
type_map = {}
for name in (
'foreground background'
).split():
type_map[name] = to_color
def special_handling(*a):
pass
def parse_config(lines, check_keys=True):
ans = {}
parse_config_base(
lines,
defaults,
type_map,
special_handling,
ans,
check_keys=check_keys
)
return ans
def merge_configs(defaults, vals):
ans = {}
for k, v in defaults.items():
if isinstance(v, dict):
newvals = vals.get(k, {})
ans[k] = merge_dicts(v, newvals)
else:
ans[k] = vals.get(k, v)
return ans
def parse_defaults(lines, check_keys=False):
return parse_config(lines, check_keys)
Options, defaults = init_config(default_config_path, parse_defaults)
def load_config(*paths, overrides=None):
return _load_config(Options, defaults, parse_config, merge_configs, *paths, overrides=overrides)
SYSTEM_CONF = '/etc/xdg/kitty/diff.conf'
defconf = os.path.join(config_dir, 'diff.conf')
def init_config(args):
config = tuple(resolve_config(SYSTEM_CONF, defconf, args.config))
overrides = (a.replace('=', ' ', 1) for a in args.override or ())
opts = load_config(*config, overrides=overrides)
return opts

2
kittens/diff/diff.conf Normal file
View File

@ -0,0 +1,2 @@
foreground black
background #eeeeee

View File

@ -7,13 +7,14 @@ import sys
from functools import partial from functools import partial
from gettext import gettext as _ from gettext import gettext as _
from kitty.cli import parse_args from kitty.cli import CONFIG_HELP, appname, parse_args
from kitty.key_encoding import ESCAPE from kitty.key_encoding import ESCAPE
from ..tui.handler import Handler from ..tui.handler import Handler
from ..tui.loop import Loop from ..tui.loop import Loop
from ..tui.operations import clear_screen, set_line_wrapping, set_window_title from ..tui.operations import clear_screen, set_line_wrapping, set_window_title
from .collect import create_collection, data_for_path from .collect import create_collection, data_for_path
from .config import init_config
from .git import Differ from .git import Differ
from .render import render_diff from .render import render_diff
@ -59,6 +60,9 @@ class DiffHandler(Handler):
self.draw_screen() self.draw_screen()
self.create_collection() self.create_collection()
def finalize(self):
pass
def draw_screen(self): def draw_screen(self):
if self.state < DIFFED: if self.state < DIFFED:
self.write(clear_screen()) self.write(clear_screen())
@ -117,7 +121,19 @@ OPTIONS = partial('''\
type=int type=int
default=3 default=3
Number of lines of context to show between changes. Number of lines of context to show between changes.
'''.format, )
--config
type=list
{config_help}
--override -o
type=list
Override individual configuration options, can be specified multiple times.
Syntax: |_ name=value|. For example: |_ -o background=gray|
'''.format, config_help=CONFIG_HELP.format(conf_name='diff', appname=appname))
def main(args): def main(args):
@ -128,6 +144,7 @@ def main(args):
left, right = items left, right = items
if os.path.isdir(left) != os.path.isdir(right): if os.path.isdir(left) != os.path.isdir(right):
raise SystemExit('The items to be diffed should both be either directories or files. Comparing a directory to a file is not valid.') raise SystemExit('The items to be diffed should both be either directories or files. Comparing a directory to a file is not valid.')
init_config(args)
loop = Loop() loop = Loop()
handler = DiffHandler(args, left, right) handler = DiffHandler(args, left, right)

View File

@ -5,6 +5,7 @@
import sys import sys
from contextlib import contextmanager from contextlib import contextmanager
from kitty.rgb import color_as_sharp, to_color
from kitty.terminfo import string_capabilities from kitty.terminfo import string_capabilities
S7C1T = '\033 F' S7C1T = '\033 F'
@ -160,3 +161,16 @@ def alternate_screen(f=None):
print(set_mode('ALTERNATE_SCREEN'), end='', file=f) print(set_mode('ALTERNATE_SCREEN'), end='', file=f)
yield yield
print(reset_mode('ALTERNATE_SCREEN'), end='', file=f) print(reset_mode('ALTERNATE_SCREEN'), end='', file=f)
def set_default_colors(fg=None, bg=None):
ans = ''
if fg is None:
ans += '\x1b]110\x1b\\'
else:
ans += '\x1b]10;{}\x1b\\'.format(color_as_sharp(to_color(fg)))
if bg is None:
ans += '\x1b]111\x1b\\'
else:
ans += '\x1b]11;{}\x1b\\'.format(color_as_sharp(to_color(bg)))
return ans

View File

@ -9,9 +9,30 @@ import sys
from collections import deque from collections import deque
from .config import defaults, load_config from .config import defaults, load_config
from .config_utils import resolve_config
from .constants import appname, defconf, is_macos, is_wayland, str_version from .constants import appname, defconf, is_macos, is_wayland, str_version
from .layout import all_layouts from .layout import all_layouts
CONFIG_HELP = '''\
Specify a path to the configuration file(s) to use. All configuration files are
merged onto the builtin {conf_name}.conf, overriding the builtin values. This option
can be specified multiple times to read multiple configuration files in
sequence, which are merged. Use the special value NONE to not load a config
file.
If this option is not specified, config files are searched for in the order:
"$XDG_CONFIG_HOME/{appname}/{conf_name}.conf", "~/.config/{appname}/{conf_name}.conf", {macos_confpath}
"$XDG_CONFIG_DIRS/{appname}/{conf_name}.conf". The first one that exists is used as the
config file.
If the environment variable "KITTY_CONFIG_DIRECTORY" is specified, that
directory is always used and the above searching does not happen.
If "/etc/xdg/{appname}/{conf_name}.conf" exists it is merged before (i.e. with lower
priority) than any user config files. It can be used to specify system-wide
defaults for all users.
'''.replace('{macos_confpath}', '~/Library/Preferences/{appname}/{conf_name}.conf, ' if is_macos else '')
OPTIONS = ''' OPTIONS = '''
--class --class
dest=cls dest=cls
@ -32,24 +53,7 @@ only use this if you are running a program that does not set titles.
--config --config
type=list type=list
Specify a path to the configuration file(s) to use. All configuration files are {config_help}
merged onto the builtin kitty.conf, overriding the builtin values. This option
can be specified multiple times to read multiple configuration files in
sequence, which are merged. Use the special value NONE to not load a config
file.
If this option is not specified, config files are searched for in the order:
"$XDG_CONFIG_HOME/kitty/kitty.conf", "~/.config/kitty/kitty.conf", {macos_confpath}
"$XDG_CONFIG_DIRS/kitty/kitty.conf". The first one that exists is used as the
config file.
If the environment variable "KITTY_CONFIG_DIRECTORY" is specified, that
directory is always used and the above searching does not happen.
If "/etc/xdg/kitty/kitty.conf" exists it is merged before (i.e. with lower
priority) than any user config files. It can be used to specify system-wide
defaults for all users.
--override -o --override -o
type=list type=list
@ -480,7 +484,7 @@ def parse_cmdline(oc, disabled, args=None):
def options_spec(): def options_spec():
if not hasattr(options_spec, 'ans'): if not hasattr(options_spec, 'ans'):
options_spec.ans = OPTIONS.format( options_spec.ans = OPTIONS.format(
appname=appname, macos_confpath='~/Library/Preferences/kitty/kitty.conf, ' if is_macos else '', appname=appname, config_help=CONFIG_HELP.format(conf_name=appname),
window_layout_choices=', '.join(all_layouts) window_layout_choices=', '.join(all_layouts)
) )
return options_spec.ans return options_spec.ans
@ -496,17 +500,6 @@ def parse_args(args=None, ospec=options_spec, usage=None, message=None, appname=
SYSTEM_CONF = '/etc/xdg/kitty/kitty.conf' SYSTEM_CONF = '/etc/xdg/kitty/kitty.conf'
def resolve_config(config_files_on_cmd_line):
if config_files_on_cmd_line:
if 'NONE' not in config_files_on_cmd_line:
yield SYSTEM_CONF
for cf in config_files_on_cmd_line:
yield cf
else:
yield SYSTEM_CONF
yield defconf
def print_shortcut(key, action): def print_shortcut(key, action):
if not getattr(print_shortcut, 'maps', None): if not getattr(print_shortcut, 'maps', None):
from kitty.keys import defines from kitty.keys import defines
@ -555,7 +548,7 @@ def compare_opts(opts):
def create_opts(args, debug_config=False): def create_opts(args, debug_config=False):
config = tuple(resolve_config(args.config)) config = tuple(resolve_config(SYSTEM_CONF, defconf, args.config))
if debug_config: if debug_config:
print(version(add_rev=True)) print(version(add_rev=True))
print(' '.join(os.uname())) print(' '.join(os.uname()))

View File

@ -123,6 +123,17 @@ def merge_dicts(defaults, newvals):
return ans return ans
def resolve_config(SYSTEM_CONF, defconf, config_files_on_cmd_line):
if config_files_on_cmd_line:
if 'NONE' not in config_files_on_cmd_line:
yield SYSTEM_CONF
for cf in config_files_on_cmd_line:
yield cf
else:
yield SYSTEM_CONF
yield defconf
def load_config(Options, defaults, parse_config, merge_configs, *paths, overrides=None): def load_config(Options, defaults, parse_config, merge_configs, *paths, overrides=None):
ans = defaults._asdict() ans = defaults._asdict()
for path in paths: for path in paths:

4
kitty/rgb.py generated
View File

@ -35,6 +35,10 @@ def color_as_int(x):
return x.red << 16 | x.green << 8 | x.blue return x.red << 16 | x.green << 8 | x.blue
def color_as_sharp(x):
return '#{:02x}{:02x}{:02x}'.format(*x)
def to_color(raw, validate=False): def to_color(raw, validate=False):
# See man XParseColor # See man XParseColor
x = raw.strip().lower() x = raw.strip().lower()