コマンドラインでの選択的インターフェイスについて考える

  • 99
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

はじめに

ここで言う選択的インターフェイスというのは、EmacsでのAnything的なツールのことを言います。この点については、イメージ画像を見たほうが分かりやすいでしょう。

このようなツールは、様々な応用可能性があります。

選択的インターフェイスでは、パイプで繋ぐことにより、出力結果を選択できるようになります。そして、選択されたものが最終的に出力されることになります。

この出力を使うことによって、様々なツールの仲介を任せたり、値を取得したりすることができます。

percol

pythonで書かれた選択的インターフェイスツールです。

https://github.com/mooz/percol

percolのインストール

$ sudo pip install percol

または、

$ git clone https://github.com/mooz/percol

$ cd !$:t

$ sudo python setup.py install

percolの基本的な使い方

$ ls | percol

最初から特定の文字列にマッチさせます。

$ ls ~ | percol --query="s"

プロンプトの左をカスタマイズする。

$ ls | percol --right-prompt=prompt1

percolのキーバインド

percolでは、設定ファイルを作ることでキーバインドを設定することもできます。

$ mkdir ~/.percol.d

$ vim ~/.percol.d/rc.py
~/.percol.d/rc.py
# https://gist.github.com/mitukiii/4234173
import sys, commands
from percol.command import SelectorCommand
from percol.key import SPECIAL_KEYS
from percol.finder import FinderMultiQueryMigemo, FinderMultiQueryRegex

## prompt
# Case Insensitive / Match Method に応じてプロンプトに表示
def dynamic_prompt():
    prompt = ur""
    if percol.model.finder.__class__ == FinderMultiQueryMigemo:
        prompt += "[Migemo]"
    elif percol.model.finder.__class__ == FinderMultiQueryRegex:
        prompt += "[Regexp]"
    else:
        prompt += "[String]"
    if percol.model.finder.case_insensitive:
        prompt += "[a]"
    else:
        prompt += "[A]"
    prompt += "> %q"
    return prompt

percol.view.__class__.PROMPT = property(lambda self: dynamic_prompt())

## migemo
# Mac と Ubuntu で辞書のパスを変える
if sys.platform == "darwin":
    FinderMultiQueryMigemo.dictionary_path = "/usr/local/Cellar/cmigemo/20110227/share/migemo/utf-8/migemo-dict"
else:
    FinderMultiQueryMigemo.dictionary_path = "/usr/local/share/migemo/utf-8/migemo-dict"

## kill
# Mac の場合は kill(yank)をクリップボードと共有する
if sys.platform == "darwin":
    def copy_end_of_line_as_kill(self):
        commands.getoutput("echo " + self.model.query[self.model.caret:] + " | pbcopy")
        self.model.query  = self.model.query[:self.model.caret]

    def paste_as_yank(self):
        self.model.insert_string(commands.getoutput("pbpaste"))

    SelectorCommand.kill_end_of_line = copy_end_of_line_as_kill
    SelectorCommand.yank = paste_as_yank

## keymap
# Mac で delete(backspace)が効くようにする
SPECIAL_KEYS.update({
    127: '<backspace>'
})
percol.import_keymap({
    "C-a" : lambda percol: percol.command.beginning_of_line(),
    "C-e" : lambda percol: percol.command.end_of_line(),
    "C-b" : lambda percol: percol.command.backward_char(),
    "C-f" : lambda percol: percol.command.forward_char(),
    "C-d" : lambda percol: percol.command.delete_forward_char(),
    "C-h" : lambda percol: percol.command.delete_backward_char(),
    "C-k" : lambda percol: percol.command.kill_end_of_line(),
    "C-y" : lambda percol: percol.command.yank(),
    "C-n" : lambda percol: percol.command.select_next(),
    "C-p" : lambda percol: percol.command.select_previous(),
    "C-v" : lambda percol: percol.command.select_next_page(),
    "M-v" : lambda percol: percol.command.select_previous_page(),
    "M-<" : lambda percol: percol.command.select_top(),
    "M->" : lambda percol: percol.command.select_bottom(),
    "C-m" : lambda percol: percol.finish(),
    "C-j" : lambda percol: percol.finish(),
    "C-g" : lambda percol: percol.cancel(),
    "M-c" : lambda percol: percol.command.toggle_case_sensitive(),
    "M-m" : lambda percol: percol.command.toggle_finder(FinderMultiQueryMigemo),
    "M-r" : lambda percol: percol.command.toggle_finder(FinderMultiQueryRegex)
})

参考:
percol 入れて zsh と組み合わせたら超便利

ターミナル版anything的なpercolをzawの代わりに試してみた

percolの応用的な使い方

percolで複数行選択する

複数行を選択する場合は、percol.command.toggle_mark_and_next()を使います。デフォルトでは、C-Sに設定されているようです。

$ ps ax | percol | awk '{ print $1 }' | xargs kill

私の場合は、以下の設定ファイルを書いています。複数行マークとマークの解除です。

~/.percol.d/rc.py
    "C-n" : lambda percol: percol.command.toggle_mark_and_next(),
    "C-p" : lambda percol: percol.command.unmark_all(),

また、区切り文字を設定するには、以下のコマンドで行けます。

$ ls | percol | tr '\n' ';'

percolのzsh補完

GitHubからcloneする場合は、最初から用意されているみたいです。

https://github.com/mooz/percol/blob/master/tools/zsh/_percol

$ curl -o ~/.zsh/functions/_percol https://raw.githubusercontent.com/mooz/percol/master/tools/zsh/_percol

$ exec $SHELL

percolでcdする

cdrができれば、以下の方法で移動を簡単にできるようです。

~/.zshrc
# http://piyopiyoducky.net/blog/2013/08/17/cdr-with-percol/
### search a destination from cdr list
function percol-get-destination-from-cdr() {
    cdr -l | \
        sed -e 's/^[[:digit:]]*[[:blank:]]*//' | \
        percol --match-method migemo --query "$LBUFFER"
}

### search a destination from cdr list and cd the destination
function percol-cdr() {
    local destination="$(percol-get-destination-from-cdr)"
    if [ -n "$destination" ]; then
        BUFFER="cd $destination"
        zle accept-line
    else
        zle reset-prompt
    fi
}
zle -N percol-cdr
bindkey '^xb' percol-cdr

それ以外はこちら。

~/.zshrc
# https://github.com/shibayu36/config-file/blob/master/.zsh/percol-sources/cdr.zsh
function percol-cdr () {
    local selected_dir=$(cdr -l | awk '{ print $2 }' | percol)
    if [ -n "$selected_dir" ]; then
        BUFFER="cd ${selected_dir}"
        zle accept-line
    fi
    zle clear-screen
}
zle -N percol-cdr
bindkey '^@' percol-cdr

参考:

percolで最近行ったdirectoryにcdするやつを書きました

Zshのcdrとpercolで最近移動したディレクトリにAnythingライクに移動する - PiyoPiyoDucky

autojumpからpercolベースのディレクトリジャンプに移行する | Web scratch

percolとghq

自身のディレクトリ構造を使いやすくします。

$ go get github.com/motemen/ghq

詳しくは以下の記事で紹介されています。

ghq + percol + docc | SOTA

ghqを使ったローカルリポジトリの統一的・効率的な管理について - delirious thoughts

ghq コマンドの zsh 補完ファイルを修正したので、その過程を解説する - Qiita

percolとgit

gitコマンドを使いやすくするためにもpercolは大活躍です。

詳しくは以下の記事で紹介されています。

git-issue + git-flow + percol

percolとgit-issueを使って、redmineのチケットをブランチに切って作業するのが捗る設定 | Technology-Gym

percolを使って、gitのコミットハッシュ値をクリップボードにコピーする - Qiita

Git - プルリクエストを自動補完してcheckoutする - Qiita

peco

percolを元にgolangで書かれた選択的インターフェイスツールです。

https://github.com/lestrrat/peco

設定ファイルは以下の様な感じに編集できます。

~/.peco/config.json
{
    "Keymap": {
        "C-p": "peco.SelectPrevious",
        "C-n": "peco.SelectNext",
        "C-c": "peco.Cancel"
    }
}

詳しくは以下の記事で紹介されています。

Windows のコマンドプロンプトを10倍便利にするコマンド「peco」

pecoを導入してzshのhistoryに使うようにした - さよならインターネット