Skip to content
C.D. MacEachern edited this page Mar 11, 2023 · 5 revisions

Kitty integration requires some Kitty configuration and two external Python files placed in the correct location. This works and was testing with Kitty 0.27.1 on macOS. Python version 3.4 or higher is required.

There are 3 steps:

  1. Add to your kitty conf the following:
allow_remote_control yes

# linux
listen_on unix:@mykitty

# macos
# listen_on unix:/tmp/mykitty
# macos_options_as_alt both

map alt+h kitten pass_keys.py neighboring_window left   alt+h
map alt+j kitten pass_keys.py neighboring_window bottom alt+j
map alt+k kitten pass_keys.py neighboring_window top    alt+k
map alt+l kitten pass_keys.py neighboring_window right  alt+l
map alt+p kitten pass_keys.py neighboring_window prev  alt+p
  1. Create a navigator.py file in your kitty conf directory that contains:
def main():
    pass


def handle_result(args, result, target_window_id, boss):
    if args[1] == "p":
        boss.active_tab.nth_window(-1)
    else:
        boss.active_tab.neighboring_window(args[1])


handle_result.no_ui = True
  1. Create a pass_keys.py file in your kitty conf directory that contains:
import re
from kittens.tui.handler import result_handler
from kitty.key_encoding import KeyEvent, parse_shortcut


def is_window_vim(window, vim_id):
    fp = window.child.foreground_processes
    return any(
        re.search(vim_id, p["cmdline"][0] if len(p["cmdline"]) else "", re.I)
        for p in fp
    )


def encode_key_mapping(window, key_mapping):
    mods, key = parse_shortcut(key_mapping)
    event = KeyEvent(
        mods=mods,
        key=key,
        shift=bool(mods & 1),
        alt=bool(mods & 2),
        ctrl=bool(mods & 4),
        super=bool(mods & 8),
        hyper=bool(mods & 16),
        meta=bool(mods & 32),
    ).as_window_system_event()

    return window.encoded_key(event)


def main(args):
    pass


@result_handler(no_ui=True)
def handle_result(args, result, target_window_id, boss):
    window = boss.window_id_map.get(target_window_id)
    direction = args[2]
    key_mapping = args[3]
    regex_to_match = "n?vim"

    if window is None:
        return

    if is_window_vim(window, regex_to_match):
        encoded = encode_key_mapping(window, key_mapping)
        window.write_to_child(encoded)
    else:
        if direction == "prev":
            boss.active_tab.nth_window(-1)
        else:
            boss.active_tab.neighboring_window(direction)

Restart Kitty, and enjoy!

Thanks to vim-kitty-navigator for the Python and inspiration.