Last active
March 17, 2026 16:55
-
-
Save oleg-koval/77ff6d4332ee3c382ab24003f519afca to your computer and use it in GitHub Desktop.
Kitty terminal config — migrated from iTerm2 by Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import os | |
| import subprocess | |
| import sys | |
| import tty | |
| import termios | |
| def main(args): | |
| # Input prompt | |
| sys.stdout.write('\033[1;34m╭─ Kitty AI Shell\033[0m\n') | |
| sys.stdout.write('\033[1;34m╰─\033[0m Describe the command you need: ') | |
| sys.stdout.flush() | |
| description = sys.stdin.readline().strip() | |
| if not description: | |
| return None | |
| sys.stdout.write('\033[2mThinking...\033[0m\n') | |
| sys.stdout.flush() | |
| # Call claude | |
| try: | |
| result = subprocess.run( | |
| [ | |
| '/Users/olegkoval/.local/bin/claude', '-p', | |
| 'Output only a raw shell command with no explanation, ' | |
| 'no markdown, no backticks: ' + description, | |
| ], | |
| capture_output=True, | |
| text=True, | |
| timeout=30, | |
| ) | |
| raw = result.stdout.strip() | |
| except FileNotFoundError: | |
| sys.stdout.write('\033[31mError: claude CLI not found in PATH\033[0m\n') | |
| sys.stdout.flush() | |
| input('Press Enter to close...') | |
| return None | |
| except subprocess.TimeoutExpired: | |
| sys.stdout.write('\033[31mError: timed out waiting for claude\033[0m\n') | |
| sys.stdout.flush() | |
| input('Press Enter to close...') | |
| return None | |
| # Strip code fences and backticks | |
| lines = raw.splitlines() | |
| clean = [ | |
| l.strip().strip('`') | |
| for l in lines | |
| if l.strip() and not l.strip().startswith('```') | |
| ] | |
| command = clean[0] if clean else '' | |
| if not command: | |
| sys.stdout.write('\033[31mNo command returned.\033[0m\n') | |
| sys.stdout.flush() | |
| input('Press Enter to close...') | |
| return None | |
| # Confirmation | |
| sys.stdout.write(f'\n\033[1mRun this?\033[0m\n') | |
| sys.stdout.write(f' \033[1;32m{command}\033[0m\n\n') | |
| sys.stdout.write('[Enter] paste [Esc/q] cancel: ') | |
| sys.stdout.flush() | |
| fd = sys.stdin.fileno() | |
| old = termios.tcgetattr(fd) | |
| try: | |
| tty.setraw(fd) | |
| ch = sys.stdin.read(1) | |
| finally: | |
| termios.tcsetattr(fd, termios.TCSADRAIN, old) | |
| sys.stdout.write('\n') | |
| sys.stdout.flush() | |
| if ch in ('\r', '\n'): | |
| return command | |
| return None | |
| def handle_result(args, answer, target_window_id, boss): | |
| # Uses boss API (more reliable than kitten @ subprocess inside handle_result). | |
| # If boss.window_id_map is unavailable in this Kitty version, fall back to: | |
| # subprocess.run(['kitten', '@', '--to', 'unix:/tmp/kitty-socket', | |
| # 'send-text', '--match', f'id:{target_window_id}', answer]) | |
| if answer: | |
| w = boss.window_id_map.get(target_window_id) | |
| if w: | |
| w.paste_text(answer) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Kitty Configuration — matching iTerm2 setup | |
| # ============================================= | |
| # ===== Font ===== | |
| font_family Monaco | |
| font_size 12.0 | |
| bold_font auto | |
| italic_font auto | |
| bold_italic_font auto | |
| # ===== Window / Layout ===== | |
| remember_window_size no | |
| initial_window_width 80c | |
| initial_window_height 25c | |
| # Layouts: enable splits (like iTerm2 panes) | |
| # tall = vertical splits, fat = horizontal, splits = arbitrary, stack = fullscreen toggle | |
| enabled_layouts splits,tall,fat,stack | |
| # Window padding (pixels) | |
| window_padding_width 4 | |
| # Draw a thin border between splits (like iTerm2 pane dividers) | |
| window_border_width 1pt | |
| # active_border_color #4488ff | |
| # inactive_border_color #cccccc | |
| # Dim inactive panes (iTerm2 has SplitPaneDimmingAmount) | |
| inactive_text_alpha 0.7 | |
| # ===== Tabs ===== | |
| tab_bar_style powerline | |
| tab_bar_edge bottom | |
| tab_powerline_style slanted | |
| tab_title_template "{index}: {title}" | |
| active_tab_font_style bold | |
| inactive_tab_font_style normal | |
| # ===== Scrollback ===== | |
| scrollback_lines 1000 | |
| # Scrollback pager (like iTerm2's "show scrollback in new window") | |
| scrollback_pager less --chop-long-lines --RAW-CONTROL-CHARS +INPUT_LINE_NUMBER | |
| # ===== Shell ===== | |
| shell /bin/zsh | |
| # ===== Transparency ===== | |
| background_opacity 1.0 | |
| # ===== Cursor ===== | |
| cursor_shape block | |
| cursor_blink_interval 0 | |
| # ===== Bell (matching iTerm2: visual bell on, audio off) ===== | |
| enable_audio_bell no | |
| visual_bell_duration 0.15 | |
| # visual_bell_color #444444 | |
| window_alert_on_bell yes | |
| bell_on_tab "🔔 " | |
| # ===== Mouse ===== | |
| mouse_hide_wait 3.0 | |
| copy_on_select clipboard | |
| strip_trailing_spaces smart | |
| # URL handling (like iTerm2 Semantic History — cmd+click opens URLs) | |
| url_style curly | |
| open_url_with default | |
| detect_urls yes | |
| url_prefixes file ftp ftps gemini git gopher http https irc ircs kitty mailto news sftp ssh | |
| # ===== macOS Specific ===== | |
| macos_option_as_alt no | |
| # macos_titlebar_color background | |
| macos_quit_when_last_window_closed yes | |
| macos_traditional_fullscreen yes | |
| macos_show_window_title_in window | |
| # ===== Clipboard ===== | |
| clipboard_control write-clipboard write-primary read-clipboard read-primary | |
| clipboard_max_size 512 | |
| # ===== Notifications ===== | |
| # Kitty sends native macOS notifications on bell (replaces iTerm2 Growl) | |
| # ===== Advanced ===== | |
| allow_remote_control yes | |
| listen_on unix:/tmp/kitty-socket | |
| shell_integration enabled no-keyboard | |
| modify_keyboard_shortcuts no | |
| confirm_os_window_close 1 | |
| update_check_interval 24 | |
| # ============================================================= | |
| # KEY MAPPINGS — iTerm2 equivalents | |
| # ============================================================= | |
| # -- Shift+Enter → literal newline (matching your iTerm2 global key map) -- | |
| map shift+enter send_text all \n | |
| # -- Tabs (like iTerm2) -- | |
| map cmd+t new_tab_with_cwd | |
| map cmd+w close_tab | |
| map cmd+1 goto_tab 1 | |
| map cmd+2 goto_tab 2 | |
| map cmd+3 goto_tab 3 | |
| map cmd+4 goto_tab 4 | |
| map cmd+5 goto_tab 5 | |
| map cmd+6 goto_tab 6 | |
| map cmd+7 goto_tab 7 | |
| map cmd+8 goto_tab 8 | |
| map cmd+9 goto_tab 9 | |
| map cmd+shift+] next_tab | |
| map cmd+shift+[ previous_tab | |
| # -- Splits / Panes (like iTerm2 Cmd+D / Cmd+Shift+D) -- | |
| map cmd+d combine : goto_layout splits : launch --cwd=current --location=vsplit | |
| map cmd+shift+d combine : goto_layout splits : launch --cwd=current --location=hsplit | |
| map cmd+shift+w close_window | |
| # -- Navigate between panes (like iTerm2 Cmd+Alt+Arrow) -- | |
| map cmd+alt+left neighboring_window left | |
| map cmd+alt+right neighboring_window right | |
| map cmd+alt+up neighboring_window up | |
| map cmd+alt+down neighboring_window down | |
| # -- Resize panes -- | |
| map cmd+shift+left resize_window narrower 2 | |
| map cmd+shift+right resize_window wider 2 | |
| map cmd+shift+up resize_window taller 2 | |
| map cmd+shift+down resize_window shorter 2 | |
| # -- Toggle pane zoom (like iTerm2 Cmd+Shift+Enter to maximize pane) -- | |
| map cmd+shift+enter toggle_layout stack | |
| # -- Font size (like iTerm2 Cmd+/Cmd-) -- | |
| map cmd+equal change_font_size all +1.0 | |
| map cmd+minus change_font_size all -1.0 | |
| map cmd+0 change_font_size all 0 | |
| # -- Scrollback -- | |
| map cmd+k clear_terminal scrollback active | |
| map cmd+shift+k clear_terminal scroll active | |
| map cmd+f show_scrollback | |
| # -- Broadcast input to all panes (like iTerm2 broadcast input) -- | |
| # No built-in; use kitten for this (see broadcast kitten below) | |
| # -- Open scrollback in editor (like iTerm2 "Open in Editor") -- | |
| map cmd+shift+g launch --stdin-source=@screen_scrollback --type=overlay $EDITOR | |
| # -- Reload config -- | |
| map cmd+shift+r load_config_file | |
| # -- Hints kitten — keyboard-select anything on screen -- | |
| map ctrl+shift+p kitten hints | |
| map ctrl+shift+f kitten hints --type path --program - | |
| map ctrl+shift+n kitten hints --type linenum --linenum-action launch --action-alias linenum=cursor --goto-line {line} {file} | |
| # -- Dynamic theme switching -- | |
| map cmd+shift+t kitten themes --reload-in=all | |
| # -- Project switcher -- | |
| map cmd+p kitten /Users/olegkoval/.config/kitty/project_switcher.py | |
| # -- AI-to-shell kitten -- | |
| map ctrl+shift+a kitten /Users/olegkoval/.config/kitty/ai_shell.py | |
| # ============================================================= | |
| # STARTUP SESSION (equivalent to iTerm2 "WORK SETUP" arrangement) | |
| # ============================================================= | |
| # Create ~/.config/kitty/sessions/work.conf to define your layout: | |
| # kitty --session ~/.config/kitty/sessions/work.conf | |
| # See: https://sw.kovidgoyal.net/kitty/overview/#startup-sessions | |
| # ===== Colors (matching iTerm2 light theme) ===== | |
| # Default colors | |
| # foreground #101010 | |
| # background #fafafa | |
| # Cursor | |
| # cursor #000000 | |
| # Selection | |
| # selection_foreground #000000 | |
| # selection_background #b3d7ff | |
| # Black | |
| # color0 #141e1e | |
| # color8 #686868 | |
| # Red | |
| # color1 #b43c29 | |
| # color9 #dd7975 | |
| # Green | |
| # color2 #00c200 | |
| # color10 #58e772 | |
| # Yellow | |
| # color3 #c7c400 | |
| # color11 #ece100 | |
| # Blue | |
| # color4 #2743c8 | |
| # color12 #a7abc8 | |
| # Magenta | |
| # color5 #c040be | |
| # color13 #e17ee1 | |
| # Cyan | |
| # color6 #00c5c7 | |
| # color14 #60fefe | |
| # White | |
| # color7 #c7c7c7 | |
| # color15 #ffffff | |
| # BEGIN_KITTY_THEME | |
| # Base2Tone Heath Dark | |
| include current-theme.conf | |
| # END_KITTY_THEME |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import os | |
| import subprocess | |
| import sys | |
| def main(args): | |
| projects_file = os.path.expanduser('~/.config/kitty/projects.txt') | |
| try: | |
| with open(projects_file) as f: | |
| projects = [l.strip() for l in f if l.strip()] | |
| except FileNotFoundError: | |
| print(f'projects.txt not found at {projects_file}', file=sys.stderr) | |
| return None | |
| # fzf reads list from stdin (pipe). We route its UI explicitly to /dev/tty | |
| # so it can render its interactive interface in the kitten overlay window. | |
| # Selection comes back on stdout (captured via PIPE). | |
| with open('/dev/tty', 'wb') as tty: | |
| proc = subprocess.Popen( | |
| ['/opt/homebrew/opt/fzf/bin/fzf', '--prompt', 'Project > ', '--height', '40%'], | |
| stdin=subprocess.PIPE, | |
| stdout=subprocess.PIPE, | |
| stderr=tty, | |
| ) | |
| stdout, _ = proc.communicate('\n'.join(projects).encode()) | |
| if proc.returncode != 0: | |
| return None | |
| return stdout.decode().strip() or None | |
| def handle_result(args, answer, target_window_id, boss): | |
| if answer: | |
| path = os.path.expanduser(answer) | |
| name = os.path.basename(path) | |
| boss.new_tab(cwd=path, tab_title=name) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment