ターミナルで複数アプリケーションをまとめるツール

現代のフロントエンド開発はとかく忙しいです。(フロントエンドに限ったことではないですが)
Lintや型チェック、テストと見るものがたくさんあります。
[lint-staged](https://github.com/okonet/lint-staged)等を使ってcommit前に各種チェックをしたり、git pushしてからCIサーバでするといった方法もあるかと思いますが、私はコードを書いたらすぐにチェック結果を教えてくれる方が好きです。
しかし[npm-watch](https://github.com/M-Zuber/npm-watch)([nodemon](https://github.com/remy/nodemon))と各種ツールを組み合わせて使うとログが混ざり見にくくなります。そのためターミナルでペイン分割して左ペインでlint([eslint-watch](https://www.npmjs.com/package/eslint-watch))、右上ペインでflow([flow-watch](https://github.com/jedwards1211/flow-watch))・・・というようにやっていました。
がOSS等で複数プロジェクトを頻繁に行き来していると、それも面倒です。

前置きが長くなりましたが、そんなわけで設定ファイルから↓のような感じにしてくれる[pw98](https://github.com/y-takey/pw98)というシンプルなツールを作りました。

![basic](https://raw.githubusercontent.com/y-takey/pw98/master/demo/ss1-basic.png)

↓ペインを選択して最大化することもできます。

![maximum](https://raw.githubusercontent.com/y-takey/pw98/master/demo/ss2-maximum.png)

APIサーバやwebpackサーバ,storybookサーバをまとめたりといった用途にも使えます。


# インストール

```
yarn global add pw98
# or
npm install -g pw98
```

globalに入れずに、プロジェクトローカルに入れても大丈夫です。

# 使用方法

`{ "direction": "row", "procs": [{ name: "hoge", command: "echo foo" }] }`のような設定ファイル(詳しくは後述)を書いておき、

```
pw98 ./config.json
```

とファイルパスを指定して実行するだけです。パスは相対パス・絶対パスのどちらでもOKです。 

## 操作

<kbd>←</kbd> , <kbd>→</kbd> または <kbd>1</kbd> 〜 <kbd>9</kbd> でペインを選択し以下の操作ができます。

| key | 内容 |
| --- | --- |
| <kbd>m</kbd> | 選択ペインの最大化・最小化 |
| <kbd>c</kbd> | 選択ペインの出力内容(ログ)をクリア。ペインが選択されていない場合は全ペインが対象 |
| <kbd>r</kbd> | 選択ペインのcommandを再実行。ペインが選択されていない場合は全ペインが対象 |

ちなみに方向キーでの選択は[未選択]→[ペイン1]→[ペイン2]→...→[未選択]というようにループします。また、<kbd>0</kbd>でも未選択にできます。

# 設定ファイル

JSONまたはJS(CommonJSスタイル)で書けます。

## 項目

### Pane

| キー         | 型                          | 説明                    |
| ----------- | ----------------------------- | ----------------------- |
| `direction` | "row" または "column"         | ペイン分割の方向です。 |
| `procs`     | PaneまたはProcの配列 | Pane, Procは混在可能で、ネストもできます。   |

### Proc

| キー       | 型   | 説明       |
| --------- | ------ | ------------- |
| `name`    | string | ペインのタイトルとして表示されます。      |
| `command` | string | `"yarn jest"`のようにシェルで実行できるものを指定します。 |

## 設定例

### 1. シンプルな例 (JSON)

```json
{
  "direction": "row",
  "procs": [
    { "name": "pane1", "command": "echo sample1-1" },
    { "name": "pane2", "command": "echo sample1-2" }
  ]
}
```

![example1](https://raw.githubusercontent.com/y-takey/pw98/master/demo/ss3-example1.png)

### 2. ちょっと複雑な例 (Node.js)

```js
const pane1 = { name: "pane1", command: "echo sample2-1" };
const pane2 = { name: "pane2", command: "echo sample2-2" };
const pane3 = { name: "pane3", command: "echo sample2-3" };
const pane4 = { name: "pane4", command: "echo sample2-4" };
const pane5 = { name: "pane5", command: "echo sample2-5" };

module.exports = {
  direction: "row",
  procs: [
    pane1,
    {
      direction: "column",
      procs: [
        {
          direction: "row",
          procs: [pane2, pane3]
        },
        pane4
      ]
    },
    pane5
  ]
};
```

![example2](https://raw.githubusercontent.com/y-takey/pw98/master/demo/ss4-example2.png)

外的要因に応じて内容を変えたい場合は環境変数を使うこともできます。

```
$ HOGE=foo pw98 any_config.js
```

```js
module.exports = {
  direction: "row",
  procs: [
    { name: "", command: process.env.HOGE === "foo" ? "echo a" : "echo b" }
  ]
};
```

### 3. おまけ (黄金長方形風)

ただし比率が合っていないので無限のエネルギーを得ることはできません。

![example2](https://raw.githubusercontent.com/y-takey/pw98/master/demo/ss5-golden-roll.png)

# 制限や注意事項

## ペインの幅・高さ

現状はペインの幅・高さを指定できません。配列の要素数でほぼ等分されます。

## ペイン数の上限

ペイン数の上限は設けていないので、ウィンドウサイズ・マシンスペックが許す限りいくつでも設定可能です。
しかし10以上のペインは数字キーによる直接選択はできないので左右キーで移動することになります。

## アプリケーションの出力内容の色

ターミナルで直接アプリケーションを実行すると出力に色がつくのに、pw98で実行すると色がつかない場合は対象アプリケーションが標準出力を自動判別して制御している可能性が高いです。
その場合は大抵当該アプリケーションにオプションが用意されていると思うので指定してください。
たとえば `eslint --color`, `jest --color`, `flow check --color always`です。詳細は当該アプリケーションのヘルプを参照してください。

## マウスでのテキスト選択

使用しているターミナルおよび設定によっては、マウスでテキスト選択できないかもしれません。
その場合は<kbd>option</kbd>キー(macの場合)を押しながらやってみてください。Windowsは未確認ですが同様に<kbd>Alt</kbd>でいけるかもしれません。

## Restartについて

Restartは単純にプロセスをkillし、またcommandを実行しているだけなので、専用のstop/restartコマンドが用意されているようなアプリケーションだと正常に再起動できないかもしれません。そういうのがあれば教えてください。

## 標準入力について

対話式コマンドのようにキー入力が必要となるものについては使えません。

## 前回実行結果のリセット

テスト系コマンドのwatchモード等でよくある、実行前に前回の出力内容をリセットし常に最新の実行結果が表示されている状態にする、という挙動はシミュレートが難しかったので実装していません。
その代わり、前回の出力から少し間があいた場合はセパレータを出力し、今回出力分をやや分かりやすくしています。

---

以下は蛇足です。

# pw98の名前の由来

ピンと来られた方も多いかと思いますが [pm2](http://pm2.keymetrics.io/) というプロセス マネージャから来ています。
pm2は基本的に本番環境での使用を想定しているのですが、開発用途でも使えないか試してみたところイマイチだったので欲しいものを作りました。
こじつけですが、 Process Windows の意図で `pw` 、また(MSの)windowsといえば95,98あたりの世代なのでpm2と足して100になる `98`を付けました。
まぁただの文字遊びなので深い意味はありません。