普段使うターミナルはAlacrittyを使っていた。 速度や機能など特に不満はなかったが、面白そうなのでkittyに移行している。
kittyとは
Alacrittyと同じGPUベースのターミナルで、独自の機能としてターミナルプロトコルの拡張がされていたり、kittenと呼ばれるPythonスクリプトにより機能が拡張できることが挙げられる。 具体的な例として、ターミナルの中で画像が表示できたりする。
画像を表示するためにターミナルに制御文字を送るためのコマンド、↑の例でいうところの kitty +kitten icat
がkittenである。
そして、このkittenから送られる制御文字を解釈できるのがターミナルプロトコルの拡張である。
これらがめちゃくちゃ便利かどうかは使用者によるとおもうが、私は面白い!っと思ったのでkittyを使い始めたのであった。
ハマりどころ
kittyはよくできていて前述した機能拡張や独自機能だけにとどまらずかなり細かくカスタマイズが可能である。 しかしながら、私が利用するうえでうーん🤔となった部分があるのでそれをメモ代わりに書いておく。
使用できるフォントがかなり限られる
最初に驚くというかハマるのは使用できるフォントがかなり限られていることだと思う。 非対応フォントを使うこともできるのだが、ものすごく間延びした感じに表示されてしまう。 font_sizeを12にしても↓のようになる。
対応したフォントを使うと↓のようにきれいに表示できる。
これはどうもkittyが等幅フォントのみを扱うように設計している*1からのようだ。
ただ、どうも等幅であって日本語のフォントではうまくいかないことが多いようだ…。
例えば私が使っていたCicaフォントは使用できなかった。
また、TakaoやIPA、M+なんかも kitty + list-fonts --psname
で使えるとでてくるのだが正しく表示できなかった。
色々試してみたが正しく表示できるのはUbuntu MonoとNoto MonoとFira Codeの3つだった。
この中でイタリックもボールドも使えるのはUbuntu Monoだけだったので今は結局Ubuntu Monoを使っている。
Ubuntu Monoで私は特に気になっていないが、見慣れたフォントを使いたいという人に取ってはつらいかもしれない。
TERM=xterm-kittyが強制される
kittyには独自拡張があるため独自のterminfoを持っている。 これがxterm-kittyとして宣言されている。 ローカルで使う場合はkitty起動時に環境変数で$TERMINFOが設定されkittyに内蔵されているterminfoを使うので問題は起きないのだが、sshするときに困る。 リモート先にはもちろんxterm-kittyが定義されたterminfoが存在しないので意図しない動作をする。 具体的にはBackspaceが効かないなどなど…。
これを解決するために kitty +kitten ssh
というコマンドが用意されている。
このコマンドはxterm-kitty用のterminfoファイルをssh先にコピーしてから通常のsshにフォールバックするという挙動になっている。
terminfoのコピー先は、sshユーザのHOME配下になるのでシステムは汚さないのだが…変にファイルを送ったりするのはどうも好きになれず、一旦 alias ssh="TERM=xterm /usr/bin/ssh"
してしまった…。
マウスクリックでWindowのフォーカスが変わってしまう
kittyではWindowと呼ばれる単位で画面を分割できる(tmuxのWindowと同じ)。 その状態で例えば、ブラウザからkittyにマウスクリックで切り替えたとする。 その時にマウスクリックされたときのWindowがフォーカスされてしまうという仕様がある。 もともと下のWindowで作業していたのに、マウスクリックしたら別のWindowになってしまうので私にとって不便である…。 どうにかしてフォーカスが切り替わらないようにしたいが…どうもそういう設定することができないので悩んでいる…。
tmuxを使うのをやめた
今までタブの機能やスクロールバッファの管理をすべてtmuxで行っていた。 ここらへんをtmuxに集約することでターミナルや環境が変わっても、tmuxがあれば同じ操作感で作業できるというメリットがあると考えていた。 実際そういう機会も少しあったが、tmuxを使うことでkittyの機能の恩恵が受けられなくなるため、この際tmuxをやめよう!っとなった。
kittyの標準的な機能でほとんど十分だったのだが、tmuxのコピーモードに相当する機能がなくここだけ自作した。 具体的にはkitty-pagerというコマンドを作り、Ctrl+Shift+hでこのコマンドを呼び出し、スクロールバッファを編集できるようにした。 ↓みたいな感じ。
kitty-pagerのvimのラッパーになっている。 kittyから標準入力経由でスクロールバッファが流れてくるので、端末を操作できるようにfd:63にコピーしてゴニョゴニョしている。 また、$KITTY_PIPE_DATAで今のカーソルやスクロール位置を取得できるのでvim上のカーソル位置をよしなにしている。
❯ cat ~/.local/bin/kitty-pager #!/bin/bash if [ -n "$KITTY_PIPE_DATA" ]; then set - $(echo "$KITTY_PIPE_DATA" | tr ':,' ' ') kitty_scrolled_by=$1 cursor_x=$2 cursor_y=$3 lines=$4 columns=$5 delta_x=$(expr $cursor_x - 1) delta_y=$(expr $lines - $cursor_y - 1) CURSOR_COMMAND=":normal G" if [ $kitty_scrolled_by -eq 0 ]; then [ $delta_y -gt 0 ] && CURSOR_COMMAND="${CURSOR_COMMAND}${delta_y}k" [ $delta_x -gt 0 ] && CURSOR_COMMAND="${CURSOR_COMMAND}${delta_x}l" else CURSOR_COMMAND=":exe \"${CURSOR_COMMAND}${kitty_scrolled_by}\\<C-y>M\"" fi fi exec vim 63<&0 0</dev/null \ -N \ -u ~/.config/kitty/pager.conf \ -c ':set termguicolors clipboard=unnamedplus' \ -c ':nmap <silent> <Space> v' \ -c ':nmap <silent> q :qa!<CR>' \ -c ':nmap <silent> ZZ :qa!<CR>' \ -c ':vmap <silent> q <ESC>' \ -c ':vmap <silent> <Space> qv' \ -c ':vmap <silent> v yq' \ -c ':r!cat 0<&63' \ -c "$CURSOR_COMMAND" \ -
kitty.confの設定はこんな感じ。 scrollback_pagerで指定する方法もあるのだが、こちらではエスケープシーケンスがそのまま流れてきてしまい、vimではうまく解釈できないのでそのまま編集することになる。 さすがにそれはつらいので、launchアクションで呼び出している。
map kitty_mod+h launch --type=overlay --stdin-source=@screen_scrollback kitty-pager @input-line-number @cursor-x
日付を挿入するkitten
kittenも作ってみたく日付を挿入するという単純なものを作ってみた。
地味に便利で作業ディレクトリを作るときなどに今日の日付をYYYYMMDD形式で挿入してくれるというもの。
ポイントとしては @result_handler(no_ui=True)
属性をつけ、画面がちらつかないようにしている。
❯ cat ~/.config/kitty/datetime.py from datetime import datetime from kittens.tui.handler import result_handler from kitty.boss import Boss def main(args): pass @result_handler(no_ui=True) def handle_result(args, answer, target_window_id, boss): w = boss.window_id_map.get(target_window_id) if w is not None: w.paste(datetime.now().strftime("%Y%m%d"))
kitty.conf
最後にkitty.confを貼っておく。 まだ、手探り状態で今後変わるかもしれない。
❯ cat ~/.config/kitty/kitty.conf # vim:fileencoding=utf-8 allow_remote_control yes font_family Ubuntu mono bold_font auto italic_font auto bold_italic_font auto font_size 12 hide_window_decorations yes #inactive_text_alpha 0.5 confirm_os_window_close 2 tab_bar_edge top tab_bar_style powerline tab_bar_min_tabs 1 foreground #ffffff background #2C001E #background_opacity 0.8 dynamic_background_opacity yes selection_foreground #000000 selection_background #ffffff shell /usr/bin/fish shell_integration enabled clipboard_control write-clipboard write-primary read-clipboard-ask read-primary-ask map shift+insert paste_from_clipboard map kitty_mod+alt+space move_window_to_top map kitty_mod+n next_window map kitty_mod+m previous_window scrollback_lines 100000 map kitty_mod+u scroll_page_up map kitty_mod+d scroll_page_down map kitty_mod+h launch --type=overlay --stdin-source=@screen_scrollback kitty-pager @input-line-number @cursor-x map kitty_mod+p scroll_to_prompt -1 enabled_layouts fat,vertical,stack map kitty_mod+l>kitty_mod+l toggle_layout fat map kitty_mod+l>kitty_mod+v toggle_layout vertical map kitty_mod+space toggle_layout stack mouse_map left click ungrabbed mouse_handle_click selection prompt map kitty_mod+o kitten hints --alphabet=asdfghjkl --ascending map kitty_mod+alt+d kitten datetime.py