🐈

GPUベースのターミナルソフトKittyの使い方

8 min read

はじめに

GPUベースのターミナルソフトといえば、Rustで作られたAlacrittyが有名かと思いますが、
他にもKittyというC/Pythonで作られたターミナルソフトを見つけました。

https://github.com/kovidgoyal/kitty

マニュアルから適当に抜き出してきたKittyの特徴は下記の通りです。
今回は下記の内、いくつかの機能をピックアップして紹介していきたいと思います。

  • GPUによる高速なレンダリング
  • Unicode/True color等、様々な端末機能をサポート
  • tmuxのように異なるレイアウトで複数のターミナル表示をサポート
  • ssh越しでもscriptによりKittyをコントロール可能
  • Kittensと呼ばれる拡張機能をサポート
  • startup sessionを細かく設定可能
  • クロスプラットフォーム対応(macOS/Linux)
  • スクロールバッファを外部プログラムから確認可能
  • vimのようなmultiple copy/paste bufferをサポート

インストール方法

Kittyは、macOS/Linuxをサポートしており、下記コマンドでインストール可能です。
macOSの場合は/Applications/kitty.app、Linuxの場合は~/.local/kitty.appにインストールされます。

curl -L https://sw.kovidgoyal.net/kitty/installer.sh | sh /dev/stdin

また、様々なパッケージマネージャにも対応しており、

You can also use your favorite package manager to install the kitty package. kitty packages are available for: macOS with Homebrew (Cask), macOS and Linux with Nix, Ubuntu, Debian, openSUSE, Arch Linux, Gentoo, Fedora, Void Linux, and Solus.

macOSの場合はHomebrewでもインストール可能です。

brew install kitty

設定方法

Kittyの設定は~/.config/kitty/kitty.confを変更する事で可能です。
設定ファイルが存在しない状態で設定ファイルを開く(ctrl+shift+F2)と、設定例がコメントアウトされたファイルが作られるようなので、それを参考にすると簡単に設定できるかと思います。

macOSの場合、ctrl+F2が別のショートカットに割り当てられており、設定ファイルを開く事ができません。
システム環境設定->キーボード->ショートカットにてメニューバーを操作対象にするを無効化するか、Kitty側のショートカットキーを変更して下さい。

その他詳細な内容は、設定マニュアルを確認してみて下さい。

基本操作

デフォルトで様々なショートカットキーが準備されており、今後説明するショートカットキーは全て設定ファイルで自由に操作可能となっています。基本的にはMod+何かのキー押して操作を実行でき、Modは、ctrl+shiftがデフォルトで設定されています。

OSで制御している個々のウィンドウをOSウィンドウと記載しています。

Action Shortcut
新しいOSウィンドウを作成 Mod+n
OSウィンドウをフルスクリーン化 Mod+F11
OSウィンドウを最大化 Mod+F10
選択した内容をクリップボードへコピー Mod+c
クリップボードからペースト Mod+v
スクロールアップ Mod+k
スクロールダウン Mod+j
スクロールバッファを開く Mod+h
設定ファイルを開く Mod+F2
フォントサイズを拡大 Mod+equal
フォントサイズの縮小 Mod+minus
フォントサイズのリセット Mod+backspace
背景を不透明度を増加 Mod+a > m
背景の不透明度を減少 Mod+a > l
背景の不透明度をリセット Mod+a > d

背景の不透明度の操作は、dynamic_background_opacityの設定をyesにする必要があります。

Modやショートカットキーは、下記設定にて自由に指定する事ができます。

# Modの設定
kitty_mod ctrl+shift

# 設定ファイルを開くショートカットキーの設定
map kitty_mod+f2 edit_config_file

# 背景の不透明度をリセットするショートカットキーの設定
map kitty_mod+a>d set_background_opacity default

# 背景の不透明度の操作を有効化
dynamic_background_opacity yes

また、下記設定で全てのショートカットキーを無効化する事ができ、その後必要なショートカットキーのみを登録していくという設定方法も可能です。

clear_all_shortcuts no

タブ/ウィンドウの操作

tmuxのような機能が実装されており、Kitty内でタブ(tmuxでいうwindow)を複数作ったり、ウィンドウ(tmuxでいうpane)により画面内に複数のターミナルを動作させる事ができます。

Action Shortcut
新規タブを開く Mod+t
タブを閉じる Mod+q
次のタブに移動 Mod+right
前のタブに移動 Mod+left
タブを奥に移動 Mod+.
タブを手前に移動 Mod+,
新規ウィンドウを開く Mod+enter
ウィンドウを閉じる Mod+w
次のウィンドウに移動 Mod+]
前のウィンドウに移動 Mod+[
ウィンドウを奥に移動 Mod+f
ウィンドウを手前に移動 Mod+b
ウィンドウをリサイズ Mod+r
ウィンドウのレイアウト変更 Mod+l

ウィンドウのレイアウトは、下記の7種類用意されています。

  • Fat -- One (or optionally more) windows are shown full width on the top, the rest of the windows are shown side-by-side on the bottom
  • Grid -- All windows are shown in a grid
  • Horizontal -- All windows are shown side-by-side
  • Splits -- Windows arranged in arbitrary patterns created using horizontal and vertical splits
  • Stack -- Only a single maximized window is shown at a time
  • Tall -- One (or optionally more) windows are shown full height on the left, the rest of the windows are shown one below the other on the right
  • Vertical -- All windows are shown one below the other

下記設定にて使用するレイアウトを指定する事ができ、先頭に指定したレイアウトが初期レイアウトになります。

# 全てのレイアウトを使用
enabled_layouts *

# Vertical,Tallのみを使用し、初期レイアウトはVerticalを使用
enabled_layouts Vertical,Tall

Kittens

Kittyは、Kittensというフレームワーク(pluginのようなもの?)を持っており、それを利用して機能拡張が可能になります。マニュアルを見ると、Kittensはpythonで作成する事ができるようです。
また、Kittensはデフォルトで複数用意されており、そのうちのいくつかを紹介していきたいと思います。

icat

ターミナル上でイメージファイルを表示する機能になります。
ImageMagickというソフトウェアを利用しているため、事前にImageMagickのインストールが必要となります(macOSの場合は下記でインストールできます)。

brew install imagemagick

icatの使用方法は、kitty +kitten icat <イメージファイル>となります。
icat

Unicode Input

文字コード番号/名前/履歴/お気に入りからUnicodeを選んで、ターミナルに入力する事ができる機能となります。
unicode input

Unicode Inputの使用方法は、kitty +kitten unicode_inputとなりますが、デフォルトでMod+uにショートカットキーが割り当てられており、下記のように設定されています。

map kitty_mod+u kitten unicode_input

Hints

現在ターミナルに表示されているテキストからマウスを使わずにURL/文字列等を取得して、取得したURLをブラウザで開いたり、取得した文字列をプロンプトにペーストできる機能となります。

Hintsを実行すると、選択可能な文字列にそれぞれコードが割り当てられます。
選択したい文字列に割り当てられたコードを入力する事で、アクションを行う事ができます。
文章で説明するよりも実際に見た方がわかりやすいと思うので、下記の使用方法と動作イメージを見てもらえればと思います。

  • Mod+eを入力するとURLを選択し、ブラウザで開く事ができます。

  • Mod+p > shift+fを入力するとパス/ファイル名を選択し、OSで指定されているデフォルトアプリケーションで開きます。

  • Mod+p > hを入力するとhash(gitのcommit hash等)を選択し、プロンプトにペーストできます。

他にも下記のような設定がデフォルトで準備されています。

  • Mod+p > fを入力するとパス/ファイル名を選択し、プロンプトにペーストできます。
  • Mod+p > wを入力すると単語を選択し、プロンプトにペーストできます。
  • Mod+p > lを入力すると行を選択し、プロンプトにペーストできます。
  • Mod+p > nを入力すると"ファイル名:行数"を選択し、vimで指定された行番号から開く事ができます。
  • Mod+p > yを入力するとハイパーリンクを選択し、ブラウザで開く事ができます。

デフォルトの設定は下記のようになっており、kitten hintsのオプションを変更する事により、何を選択しどんなアクションを実行するのかを自由にカスタマイズしたショートカットを作る事ができます。

# URLを選択し、ブラウザで開く設定
map kitty_mod+e kitten hints

# パス/ファイル名を選択し、OSで指定されているデフォルトアプリケーションで開く設定
map kitty_mod+p>shift+f kitten hints --type path

# hash(gitのcommit hash等)を選択し、プロンプトにペーストする設定
map kitty_mod+p>h kitten hints --type hash --program -

また、python scriptを記述する事により、より細かく動作をカスタマイズする事ができるようです。
マニュアルにある設定例(F1を押した時に単語を選択し、google検索を行う)を下記に記載しています。
下記をkitty.confに設定

kitty -o 'map f1 kitten hints --customize-processing custom-hints.py'

下記pythonファイルをcustom-hints.pyとして~/.config/kitty/配下に保存

import re

def mark(text, args, Mark, extra_cli_args, *a):
    # This function is responsible for finding all
    # matching text. extra_cli_args are any extra arguments
    # passed on the command line when invoking the kitten.
    # We mark all individual word for potential selection
    for idx, m in enumerate(re.finditer(r'\w+', text)):
        start, end = m.span()
        mark_text = text[start:end].replace('\n', '').replace('\0', '')
        # The empty dictionary below will be available as groupdicts
        # in handle_result() and can contain arbitrary data.
        yield Mark(idx, start, end, mark_text, {})


def handle_result(args, data, target_window_id, boss, extra_cli_args, *a):
    # This function is responsible for performing some
    # action on the selected text.
    # matches is a list of the selected entries and groupdicts contains
    # the arbitrary data associated with each entry in mark() above
    matches, groupdicts = [], []
    for m, g in zip(data['match'], data['groupdicts']):
        if m:
            matches.append(m), groupdicts.append(g)
    for word, match_data in zip(matches, groupdicts):
        # Lookup the word in a dictionary, the open_url function
        # will open the provided url in the system browser
        boss.open_url(f'https://www.google.com/search?q=define:{word}')

あとがき

ここまで、Kittyの機能をいくつか見てきましたが、Hints機能が特に便利だなと思いました。
他にもpythonで色々と拡張できるようなので、時間があれば色々見ていきたいと思います。

説明できてなかった機能もたくさんありますので、気になった方は下記を確認してみて下さい。

https://sw.kovidgoyal.net/kitty/#

Discussion

ログインするとコメントできます