Paper Plane xUI(PPx)のListFileとpecoの関係


pecoでは標準出力に一覧を選択して標準出力へ出す事ができ、対話的なフィルタ処理と言えます。
ここでは(それぞれを使って感じた僕なりの)用途の違いを解説したいと思います。

pecoの例

スクリプトで対話的な処理

例えば、何かスクリプトを実行中に対話的な処理を入れたいとなると、pecoの出番になります。
※動作確認はcygwinのmintty上でしており、pecoを動作させるためにwinptyをインストールしています。

peco_test.sh
#!/bin/sh

while : ;do
  echo Paper Plane xUIを使いますか?
  sleep 2
  select=`echo -e "Hai\nYes\nNo" | peco`

  case $select in
  Hai|Yes)
    echo Welcome Paper Plane xUI!
    break
    ;;
  *)
    echo そんな、ひどい
    sleep 1
    ;;
  esac
done

上記のように、とても手軽に選択肢を作る事ができます、しかも入力では無いのでコーナーケースの考慮もある程度しなくても良く、例えばYesの場合に"[Yy]([Ee][Ss])?"という入力チェックをしなくても良くなります、また、複数選択の時も*に行くようになっています。

上記の場合は選択肢の為、choコマンドの方が適切かと思いますが、一例として紹介します。

gitブランチを選択してcheckout

次はLinuxコマンドとの連携時にpecoを使う場合です、gitでcheckoutしたい時にブランチ一覧から選択したい時、

$ git checkout `git branch | peco`

とすると、ブランチ一覧から選択してcheckoutをする事ができます1、このコマンドをaliasにしていたり、グローバルaliasが使えるzshでブランチ選択部分だけをaliasにして汎用的にしている例を見かけます。

PPxの例

PPxでは後者の「gitで、選択したブランチをcheckout」のような部分に利用できます、前者のスクリプト内の対話的な処理はpeco(やcho)の方が良いでしょう。

PPxでgitブランチを選択してcheckout

まずは、単にコマンドの実行結果をListFileに吐き出すだけのコマンド群を用意します、これは単純ですが、汎用的です。

「Shift+s」でコマンド実行結果をListFile化する

ここでgit branchを実行

ブランチ一覧がエントリーとして表示されます。

この中からエントリーを選択してcheckoutをするために、Paper Plane xUI(PPx)をgitのフロントエンドとして使うで用意したcheckoutメニューを、カーソル上のエントリーが初期値となるように少し改造します。

「Shift+g, o」の初期値を変更

これで選択したエントリーへのcheckoutができます。

ツール構成

entry.js

選択した最初のエントリーを返します、%FC相当の事をやってるだけなんですが、%FCはListFile上だとフルパスを返すので、スクリプトとして用意します。

entry.js
//! script

for (var items = new Enumerator(PPx.Entry); !items.atEnd(); items.moveNext()) {
    PPx.Result = items.item().Name;
    break;
}

PPx設定

差分のみです2

※自身の設定が消えないように、適用前にバックアップを取るか、追加取り込みをしてください
※GitExtensionsやスクリプトのパスは自身の環境へと合わせて下さい

PPX.CFG
KC_main = { ; PPcメイン窓
\S  ,
    *set dummy='command実行'
    *set CIN_LSTFILE=%'temp'\cin2listfile.tmp
    *set CMD=%"コマンド?"%{command%}
    %Obsq %'CMD' | ruby %0\script\shell\tolistfile.rb | nkf -Lw -s > %'CIN_LSTFILE'
    *jumppath %'CIN_LSTFILE'
}

M_menuCustomGit2    = { ** comment **
git check&out <target>  = 
    *set ENTRY=%*script(%0\script\entry.js)
    *set ARG=%"git checkout <target>(入力1/2)"%{%'ENTRY'%}
    %"git checkout <target>(Enterで実行2/2)"%{%}
    %OB git checkout %'ARG'
}

終わりに

身も蓋もないですが、今回のように利用頻度の高い場合は専用メニューを用意してもよいかと思います、こちらの方がListFileを中継せず、1アクションで済むためスムーズです。

PPx.CFG
M_menuCustomGit2    = { ** comment **
git check&out <branch> <PECO>   = %OB git branch | peco | xargs git checkout
}

  1. カレントブランチに「* 」が残ってますが、僕の場合は候補外の目印として残すようにしてます 

  2. 「Shift+g」はエントリー以外の自分ルールがありますが「Shift+g, o」でエントリーを初期値にしています。これは初期値の「.」はすぐ入力出来るし、最初の一つだけしか使われないので「Ctrl+g」とは違う、なにより使い勝手が良く、という事でこうしました。