🐵

terminal pagerをclient/server化してtmuxを組み合わせたら最強のSQLクライアントになった

2021/01/08に公開

ターミナルページャー ovの紹介ovパッケージを使用して別のCLIとしてターミナルページャーをclient/server化したovcsを作りました。

ターミナルページャーをclient/server化したと言っても開いた1つのファイルを複数人で見るという用途ではありません。
クライアントは渡された入力をそのままサーバーに渡して終了し、サーバーで「見る」というものです。

「Unix domain socket」で通信するようになっていて、サーバーをあらかじめ起動しておき、

ovcs server

クライアント側にパイプで渡すとサーバー側でページャーが表示します。

echo "Hello World"| ovcs client

どう使うのか?

psqlなどの結果をページャーに渡しているCLIアプリケーションでページャーをovcs clientにすることで、psqlの入力欄はページャーに隠れることが無くなり、ovcs serverを起動した側に表示されます。
tmuxを使用してpaneを分割することで、1つの端末でpsqlの入力欄と結果表示を分離することが出来ます。

ここでは、tmuxを起動して、paneを2つに分割し、下側を結果表示用にサーバーを起動してます。

tmux
tmux split-window -v
ovcs server  # さらに -C 等 ov のオプションが使用できます。

クライアント側は PAGERovcs clientを指定すればページャーを使用する結果表示は下側で表示されます。

export PAGER='ovcs client'
psql

ovcs.gif

※(tmux用に交互表示の背景色スタイルをdarkblueにしています)

単純に送るだけなら、間に仲介(proxy)するソフトを使用すればlessでも可能ですが、ovcsでは ov のパッケージを使用することで、別プロセスでなく自前でサーバー化しています。

ovでは、複数ファイルに対応しているため、ページャーを閉じることなく、別のドキュメントを開くことができます。上記の動画でもページャーを閉じることなく[]で結果表示を切り替えています。
lessも複数ファイルに対応していますが、「標準入力は一つ」のため複数のファイルを接合してしか受け入れることが出来ません。

ovcsサーバーでは、クライアントから新しく接続されたら、そこからの入力をドキュメントとして受け入れ、最後尾に追加して、さらに表示をそのドキュメントに切り替えます。

ドキュメントの切り替えはデフォルトのキーバインドで[で前に、]で後ろに移動でき、さらに不要になったらctrl+kで閉じることができます(ドキュメントは必ず一つは残っている必要があります)。

さらにGUIっぽく

GUIのSQLクライアントツールでは、左側にテーブル一覧等があり、右上にSQLの入力欄、右下に結果表示欄というのがよくある構成です。tmuxでpaneを分割すれば、表示欄は確保できます。
そこで別セッションとしてpsqlを起動しても良いですが、ovcsでは-p ソケットファイル名 でソケットを指定して起動することが可能です。クライアント側も-p ソケットファイル名を使用すれば、そのサーバーに接続にいきます。

そこで、左側の情報表示用のページャーサーバーを起動して、テーブル一覧等をそちらに表示し、SQLを打つときには結果表示用のページャーに表示すると、あたかもGUIの様な画面構成が出来上がります。

tmuxではコマンドにより操作が出来るので、シェルスクリプトとして用意しておくとコマンド一発で用意することも可能です。

例えば https://github.com/noborus/ovcs/blob/main/psql.sh にも以下のスクリプトが置いてあります。

psqlでは接続後も \setenv PAGERによりページャーを指定できるので "\?"のヘルプと"\d"のテーブル一覧をあらかじめ表示しています。

#!/bin/bash

SESSION="psql"
HELPSOCK="/tmp/ov-psql-help.sock"
OVSOCK="/tmp/ov-psql.sock"

SESSIONEXISTS=$(tmux list-sessions | grep $SESSION)
if [ "$SESSIONEXISTS" = "" ]
then
    tmux new-session -d -s $SESSION # 新しくセッションを開始
    tmux split-window -h -t $SESSION:0 # 左右に分割
    tmux resize-pane -L 50 # サイズ調整(左側の情報欄を狭めるため左に移動)
    tmux split-window -v -t $SESSION:0 # 右のpaneをさらに上下に分割
    tmux resize-pane -U 10 # サイズ調整(結果表示欄を広げるため上に移動)
    # 左側のpaneにページャーサーバー起動
    tmux send-keys -t $SESSION:0.0 "ovcs server -w=f -p $HELPSOCK" C-m 
    # 右下のpaneにページャーサーバー起動
    tmux send-keys -t $SESSION:0.2 "ovcs server -H2 -C -d'|' -p $OVSOCK" C-m
    # サーバー起動を待つ
    while [ ! -S $HELPSOCK ]
    do
	sleep 1
    done
    # シェルスクリプトのオプションを全てpsqlに渡す
    tmux send-keys -t $SESSION:0.1 "psql $*" C-m  
    # 左側のpaneのページャーに切り替え
    tmux send-keys -t $SESSION:0.1 "\setenv PAGER 'ovcs client -p $HELPSOCK'" C-m 
    # helpの表示
    tmux send-keys -t $SESSION:0.1 "\?" C-m
    # テーブル一覧  
    tmux send-keys -t $SESSION:0.1 "\d" C-m
     # 右下のpaneのページャーに切り替え
    tmux send-keys -t $SESSION:0.1 "\setenv PAGER 'ovcs client  -p $OVSOCK'" C-m 
    tmux select-pane -t $SESSION:0.1
fi

tmux attach-session -t $SESSION:0

このスクリプトを起動すると以下のようになります。

sh psql.sh sample # sampleデータベースに接続

ovcs-psql.gif

ヘルプやテーブル名や前に実行したSQLの結果を閲覧しながらSQLを打てるので、初心者にも優しい環境になります。

tmuxを使用していると結果表示だけを表示[prefix + z]、元に戻す[prefix + z]、セッションの切り離し[prefix + d]やセッションの再接続tmux aが出来るので、キーボードだけで操作がしやすい上級者にも優しい環境になります。

MySQLでも

ovovcsはpsql専用ではないので、MySQLでも同様にSQLクライアント環境を用意できます。

https://github.com/noborus/ovcs/blob/main/mysql.sh にあるスクリプトを使用すると以下のようになります。

ovcs-mysql.gif

最後に

作ってみて、まだ数日といったところなので、まだ荒いところがあります。
tmuxのセッションをkillしたりした場合は、プロセス(kill)とソケットファイルの後始末(rm /tmp/ov-*)しないとならなくなったりします。

Discussion