Example #1
0
def merge_configs(defaults: Dict, vals: Dict) -> Dict:
    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: Iterable[str], check_keys: bool = False) -> Dict[str, Any]:
    return parse_config(lines, check_keys)


x = _init_config(config_lines(all_options), parse_defaults)
Options: Type[DiffOptions] = x[0]
defaults = x[1]


def load_config(*paths: str, overrides: Optional[Iterable[str]] = None) -> DiffOptions:
    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: DiffCLIOptions) -> DiffOptions:
    config = tuple(resolve_config(SYSTEM_CONF, defconf, args.config))
    overrides = (a.replace('=', ' ', 1) for a in args.override or ())
Example #2
0
def parse_opts() -> Options:
    all_options = {}  # type: OptionDefs
    o, k, g, _all_groups = option_func(
        all_options, {
            'shortcuts': ['Keyboard shortcuts'],
            'colors': ['Colors'],
            'behavior': ['Behavior']
        })

    g('shortcuts')
    k('quit', 'q', 'quit')
    k('quit', 'esc', 'quit')
    k('confirm', 'enter', 'confirm')
    k('left', 'left', 'move left')
    k('right', 'right', 'move right')
    k('up', 'up', 'move up')
    k('down', 'down', 'move down')
    k('page up', 'page_up', 'move page up')
    k('page down', 'page_down', 'move page down')
    k('start of line', 'home', 'move first')
    k('first non-whitespace', 'a', 'move first nonwhite')
    k('last non-whitespace', 'end', 'move last nonwhite')
    k('end of line', 'e', 'move last')
    k('start of buffer', 'ctrl+home', 'move top')
    k('end of buffer', 'ctrl+end', 'move bottom')
    k('word left', 'ctrl+left', 'move word left')
    k('word right', 'ctrl+right', 'move word right')
    k('scroll up', 'ctrl+up', 'scroll up')
    k('scroll down', 'ctrl+down', 'scroll down')
    k('select left', 'shift+left', 'select stream left')
    k('select right', 'shift+right', 'select stream right')
    k('select up', 'shift+up', 'select stream up')
    k('select down', 'shift+down', 'select stream down')
    k('select page up', 'shift+page_up', 'select stream page up')
    k('select page down', 'shift+page_down', 'select stream page down')
    k('select to start of line', 'shift+home', 'select stream first')
    k('select to first non-whitespace', 'A', 'select stream first nonwhite')
    k('select to last non-whitespace', 'shift+end',
      'select stream last nonwhite')
    k('select to end of line', 'E', 'select stream last')
    k('select to start of buffer', 'shift+ctrl+home', 'select stream top')
    k('select to end of buffer', 'shift+ctrl+end', 'select stream bottom')
    k('select word left', 'shift+ctrl+left', 'select stream word left')
    k('select word right', 'shift+ctrl+right', 'select stream word right')
    k('column select left', 'alt+left', 'select columnar left')
    k('column select right', 'alt+right', 'select columnar right')
    k('column select up', 'alt+up', 'select columnar up')
    k('column select down', 'alt+down', 'select columnar down')
    k('column select page up', 'alt+page_up', 'select columnar page up')
    k('column select page down', 'alt+page_down', 'select columnar page down')
    k('column select to start of line', 'alt+home', 'select columnar first')
    k('column select to first non-whitespace', 'alt+A',
      'select columnar first nonwhite')
    k('column select to last non-whitespace', 'alt+end',
      'select columnar last nonwhite')
    k('column select to end of line', 'alt+E', 'select columnar last')
    k('column select to start of buffer', 'alt+ctrl+home',
      'select columnar top')
    k('column select to end of buffer', 'alt+ctrl+end',
      'select columnar bottom')
    k('column select word left', 'alt+ctrl+left', 'select columnar word left')
    k('column select word right', 'alt+ctrl+right',
      'select columnar word right')

    g('colors')
    o('selection_foreground', '#FFFFFF', option_type=to_color)
    o('selection_background', '#5294E2', option_type=to_color)

    g('behavior')
    o('select_by_word_characters',
      json.loads(os.getenv('KITTY_COMMON_OPTS'))['select_by_word_characters'],
      option_type=str)

    type_map = TypeConvert({
        o.name: o.option_type
        for o in all_options.values() if hasattr(o, 'option_type')
    })

    defaults = None

    # Parsers/validators for key binding directives
    func_with_args, args_funcs = key_func()

    def parse_region_type(region_type: str) -> str:
        result = region_type.lower()
        assert result in ['stream', 'columnar']
        return result

    def parse_direction(direction: str) -> str:
        direction_lc = direction.lower()
        assert direction_lc in [
            'left', 'right', 'up', 'down', 'page up', 'page down', 'first',
            'first nonwhite', 'last nonwhite', 'last', 'top', 'bottom',
            'word left', 'word right'
        ]
        return direction_lc.replace(' ', '_')

    def parse_scroll_direction(direction: str) -> str:
        result = direction.lower()
        assert result in ['up', 'down']
        return result

    @func_with_args('move')
    def move(func: Callable, direction: str) -> Tuple[Callable, str]:
        return func, parse_direction(direction)

    @func_with_args('scroll')
    def scroll(func: Callable, direction: str) -> Tuple[Callable, str]:
        return func, parse_scroll_direction(direction)

    @func_with_args('select')
    def select(func: Callable, args: str) -> Tuple[Callable, Tuple[str, str]]:
        region_type, direction = args.split(' ', 1)
        return func, (parse_region_type(region_type),
                      parse_direction(direction))

    def parse_kittens_key(
        val: str, args_funcs: Dict[str, Callable]
    ) -> Optional[Tuple[Tuple[ActionName, ActionArgs], KeyName, ShortcutMods,
                        bool]]:
        parsed_key = _parse_kittens_key(val, args_funcs)
        if parsed_key is None:
            return None
        if len(parsed_key) == 2:  # kitty ≥ 0.17.0
            action, (key, mods, is_text) = parsed_key
        else:  # kitty < 0.17.0
            action, key, mods, is_text = parsed_key
        return (action, key, mods, is_text
                and (0 == (mods or 0) & (kk.CTRL | kk.ALT | kk.SUPER)))

    # Configuration reader helpers
    def special_handling(key: OptionName, val: str,
                         result: OptionValues) -> bool:
        if key == 'map':
            action, *key_def = parse_kittens_key(val, args_funcs)
            result['key_definitions'][tuple(key_def)] = action
            return True
        return False

    def parse_config(lines: List[str],
                     check_keys: bool = True) -> OptionValues:
        result = {'key_definitions': {}}  # type: OptionValues
        parse_config_base(lines,
                          defaults,
                          type_map,
                          special_handling,
                          result,
                          check_keys=check_keys)
        return result

    def merge_configs(defaults: OptionValues,
                      vals: OptionValues) -> OptionValues:
        return {
            k: (merge_dicts(v, vals.get(k, {}))
                if isinstance(v, dict) else vals.get(k, v))
            for k, v in defaults.items()
        }

    Options, defaults = init_config(config_lines(all_options), parse_config)
    configs = list(
        resolve_config('/etc/xdg/kitty/grab.conf',
                       os.path.join(config_dir, 'grab.conf'),
                       config_files_on_cmd_line=None))
    return load_config(Options, defaults, parse_config, merge_configs,
                       *configs)