psqlのページャーにovを！

この記事は、[2024年Advent Calendar](https://qiita.com/advent-calendar/2024/postgresql)の12月6日の記事その2です。
MySQLShell版も書きました。[MySQL Advent Calendar 2024](https://qiita.com/noborus/items/e4b2d5437c4b1888f4b0)もご参照下さい。

## lessページャー

psqlではSQLを実行して結果が画面に収まらない場合、ページャーが起動して結果を表示します。
起動するページャーは、環境変数`PAGER`に設定されているコマンドです。多くの場合は`less`が使用されます。

`less`は昔からあり、安定していて、完成して機能追加もされていない...と思っていませんか？
実は、`less`は今も開発が進んでいて、新しい機能が追加されています。`less`のバージョンを確認して、603以上であれば、大きな機能追加がされています。

```console
less --version
less 671x (GNU regular expressions)
```

※ ここでは開発版の671xを使用しています。603以上であれば使えるはずですが、多少動作は違うかもしれません。

psqlを起動して、`SELECT * FROM pg_class;`を実行してみましょう。

![通常のless](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18555/d3442a41-eb9a-f32b-6444-c464c44d2a2e.png)

画面に収まらないので、カラム名と区切り線と最初の方のデータしか表示されていません。ここで表示をとどめておいて、スクロールして表示できるようにしているのがページャーです。
そして、通常はスクロールしていくと、カラム名や区切り線もスクロールで消えていきデータだけが表示されます。
ページャーとは表示する中身に関係なく、１画面分を表示するためのもの...だったのは昔の話です。

その画面のまま`--header`と打ってみましょう。これは`less`のオプションを起動後に指定して切り替えています。

`Header lines:`とプロンプトが出るので、2と入力してEnterを押してください。

折返し表示がなくなり横スクロールするマークが表示されるようになっています。
これで上の2行（カラム名と区切り線）はヘッダーとして常に表示されるようになります。

![ヘッダー付きless](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18555/d07ec2c8-ab09-3870-d1c9-2eef9602cef8.png)

![ヘッダー付きless2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18555/58d6ac07-55eb-3890-2a7f-a04bc78f538a.png)

今までたくさんのカラムを表示していたときには\xを使用するといった方法がありましたが、ページャーの機能により見やすくなることがわかりました。

もっと便利にしたいですか？それならば[ov](https://github.com/noborus/ov)をおすすめします。

## その前にpspg

psqlの結果表示を改善するために、`pspg`を使うこともできます。
[pspg](https://github.com/okbob/pspg)

`pspg`はカラム名の固定やカラムを固定して表示することができます。もともとPostgreSQL用として作られたようですが、表形式のデータを表示するために便利に使えます。

psqlを使用していてページャーを`pspg`にしている方も多いです。

## ovページャー

[ov](https://github.com/noborus/ov)は、私がGo言語で作成しているページャーです。

`pspg`と同じように`psql`のページャーとして使えるように開発を開始しましたが、当初から汎用のページャーとしても使えるように設計しています。

そのため、表形式に対応した機能を備えつつも、オプションによる切り替えによって実現しています。

### インストール

Go言語がサポートしている環境であれば動作します。

まず、`ov`をインストールします。以下のコマンドを実行してください。[リリースページ](https://github.com/noborus/ov/releases)から各種パッケージやバイナリがダウンロードできます。Go言語で作られているのでバイナリもダウンロードしてパスのあるところに置くだけで使えます。

また、Go言語がインストールされている環境であれば、以下のコマンドでインストールできます。

```sh
go install github.com/noborus/ov@latest
```

### 設定

`ov`は汎用のページャーとして使えるようになっていので、環境変数`PAGER`に設定することで様々な場面で使えます。

psql用のページャーとして使用したい場合は、環境変数`PSQL_PAGER`に設定するか、`~/.psqlrc`に設定するとよいでしょう。

`~/.psqlrc`に以下の設定を追加してください。

```rc
\setenv PSQL_PAGER 'ov オプション'
```

オプションは好みによりますが、この後解説していきます。

推奨例は以下のようになります。

```rc
\setenv PSQL_PAGER 'ov -F -C -d "|" -H1 --column-rainbow --column-mode --align'
```

### オプション

`-F`または`--quit-if-one-screen`は、`less`と同じで1画面に収まる場合はページャー画面を表示せずに（実際には受け取った分を出力だけして）すぐに終了します。

ここでは、あらかじめ設定しておけるようにオプションの説明をしますが、`ov`は基本的に実行後にオプションの機能を切り替えることができます。
この後の説明は、`less`との対比で折り返し表示のイメージを示していますが、`ov`では折り返さずに横スクロールしての表示も可能です。

### ヘッダー機能

まずはヘッダー機能です。`less`の`--header`と同じようにヘッダーを固定表示できます。オプションは`--header 数値`または`-H 数値`です。
`ov`では、ヘッダーを指定しても折り返して表示できます。
区切り線まで含めて`-H 2`としても良いですが、`ov`ではヘッダーのスタイルを変更できるので、背景色を変えると`-H 1`でも十分にわかりやすくなります。

![ovヘッダー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18555/2dbda902-f927-7d81-7a78-96ec56a1a358.png)

### 交互に色を変える

たくさんの行と列がある場合は、パット見でどの行かがわかりにくくなるため、交互に背景色を変えて表示している表はよくあります。それを実現するオプションが`--alternate-rows`または`-C`です。

![ov交互に色を変える](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18555/fe4b9dcc-e714-a96a-8c81-66e97ee01958.png)

### カラムモード

「行」がわかったとしても、カラムが多い場合は折返し表示になり、カラム名が表示されていたとしても、どのカラムかわかりにくくなるため、カラムを選択するモードがあります。これはカラムの区切り文字を指定して、カラムを特定し、そのカラムだけをハイライト表示するモードです。
まず、カラムの区切り文字を指定するオプションが`--column-delimiter "|"`または`-d "|"`です。
そして、カラムモードを指定するオプションが`--column-mode`または`-c`です。

これによりカーソルを動かすことで、どの行のどのカラムかがわかりやすくなります。

![ovカラムモード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18555/e29bd5f5-eb1a-8d4b-36b9-d2008ef3856d.png)

### カラムレインボー

カラムモードはカーソルを動かしてハイライト表示する必要がありますが、カラムレインボーはあらかじめカラム毎に色を割り当てて表示します。これにより、さらにカラムを特定しやすくなります。
オプションは`--column-rainbow`です。

![ovカラムレインボー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18555/652e376c-b97b-8449-f30f-d6afbbe8e8e7.png)

### カラムの幅を揃える

`psql`では通常カラムの幅を揃えて出力しています。そのためページャー側で揃える必要はありませんが、`psql`では幅を揃えない出力(`\a`)にすることもできます。

![ov幅を揃えない](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18555/fc0a59b7-c148-d6ef-feaf-24e4491975f3.png)

その場合でも`ov`のカラムモードは列を把握することができますが、幅を揃えてみたいときには、再度(`\a`)してからクエリを再実行する必要がありました。
`ov`では、`--align`オプションを指定することで、カラムの幅を揃えて表示することができます。そして、この幅を揃えるモードは`alt+shift+f'でトグルに切り替えることができます。

![ovカラムの幅を揃える](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18555/2398d1ec-c21e-9d92-23cb-d260345f03b7.png)

### カラムの縮小表示

そして、このカラムの幅を揃えるモードにしているときには、選択したカラム上で`s`キーを押すと縮小表示と通常表示を切り替えることができます。
これにより長いカラムが邪魔になったときにもクエリを再実行することなく、一覧表示できます。

![ovカラムの縮小表示](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18555/265292e2-7571-4e29-c219-4cd1d157d37a.png)

### まとめ

`ov`はもともと`psql`の結果表示を改善するために開発を開始しました。そのため、`psql`のページャーとして便利な機能を揃えています。
また、汎用ページャーとしての機能も豊富に備えているため、様々な場面で使えるページャーとして使えるようになっています。