何度も同じコマンド調べ直すのやめませんか？

タイトルに煽りが足りない！と指摘を受けたので頑張って変えてみました。
`pet` というツールを作ったら公開して3日でStarを1000も頂きました。本当に感謝です。

<img src="https://qiita-image-store.s3.amazonaws.com/0/56222/9735e282-b9b3-1ce7-5080-fbd141840d57.png" width="150">


# 対象の方
「あーあのコマンド何だっけ。前も調べたけど忘れちゃったからまた調べよう...」
となる人

# 対象じゃない方
「Ctrl-rで検索すればすぐ見つかるし、よく使うコマンドはaliasに登録してるから全然問題ない」
という人

# デモ
色々と書く前に動画を見てもらえれば雰囲気がつかめると思います。
詳細は以下のREADMEに書いてあります。ちなみにDescriptionは日本語でも動きます。
https://github.com/knqyf263/pet

<img src="https://qiita-image-store.s3.amazonaws.com/0/56222/cca27935-d925-1d4e-362c-53f5bc044736.gif" width="700">


# 概要

僕はいつも「あのコマンドなんだっけ...」となってしまいます。
もちろんpecoとか利用させていただいているのでコマンド履歴からの検索はしやすくなっているのですが、以下のような時にうまく探せなくて困っていました。

1. 似たコマンドが履歴に大量にある場合
1. そもそもコマンド名が思い出せない場合

よく打つコマンドとかはaliasに登録するのですが、たまにしか打たないコマンド（オプションも凄い長いやつとか）はaliasに登録するほどでもなくて、1ヶ月後ぐらいに忘れてまた調べ直しちゃいます。あとaliasに登録しても名前思い出せなくて `.bashrc` とかから探してます。

## 似たコマンドが履歴に大量にある場合

例えばawkのコマンドを探す時に、以下のようなコマンドが複数ある中から一番上を探したい場合、履歴から引っ張るにも苦労してしまいます（awkで検索しても大量にヒットする）。
こういうので困ってない人は多分このツールは要らないと思います。

- `$ awk -F, 'NR <=2 {print $0}; NR >= 5 && NR <= 10 {print $0}' company.csv (What I am looking for)`
- `$ awk -F, '$0 !~ "DNS|Protocol" {print $0}' packet.csv`
- `$ awk -F, '{print $0} {if((NR-1) % 5 == 0) {print "----------"}}' test.csv`


## そもそもコマンド名が思い出せない場合

例えば2つのファイルのうち、共通する行を取り出したいとします。
こういう時に最適なコマンドがあった気がするけど思い出せない...
Google検索で「共通　コマンド」とか調べても意外と出てこない。
何回か調べたのに再度調べるのに何分か使ってしまいます。

結局僕が探していたのは `comm` コマンドだったのですが、なかなか思い出せず辛い気持ちになりました（更にそこからオプションの意味を勘違いしてさらに時間を無駄にしました）。

こういう時にコマンドと自分で書いた説明を一緒に登録しておいて検索できたらなーと思い作ることにしました。

# 作ったもの

[pet](https://github.com/knqyf263/pet) というツールを作りました。
デモ見てもらえれば分かるのですが、コマンドのスニペットを簡単に登録出来るツールです。

[memo](https://github.com/mattn/memo) というツールを見て[peco](https://github.com/peco/peco) を使って検索できたら良さそうだなーと思い、ほぼ似たような構成で作りました。
`memo`っぽく作ろうということで仕様が決まっていたので数時間で作れました。

機能としては以下のような感じです

- スニペットの簡単な登録
- インタラクティブな検索
- スニペットの直接の実行
- スニペットの簡単な編集（ただのテキストファイルです）
- Gist経由での同期

スニペットはSQLiteで管理しようとしていたのですが、好きなエディタで簡単に編集できるしGistとかで管理しやすいしテキストファイルのほうがいいかなーと思ってTOMLファイルを採用しました。

スニペットを中央のサーバに登録してみんなで利用したりするものもありますが、そこまで大掛かりなものは必要なくて簡単に自分のスニペットを管理したかったので、Goの勉強も兼ねて作りました。


# サンプル
このツール単体で使うというよりは `.bashrc` とか `.zshrc` にfunctionとか書くと便利になると思います。

## 直前のコマンドを簡単に登録する
`.zshrc` に以下のように書いておけば、簡単に登録できるようになります（zsh力が低いのでもっと綺麗に直せる方は教えてください...）

```sh
$ cat .zshrc
function prev() {
  PREV=$(fc -lrn | head -n 1)
  sh -c "pet new `printf %q "$PREV"`"
}
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/56222/9ab6ea40-2f41-e418-9427-0693717b69f8.gif" width="700">



## コマンドライン上にスニペットを表示する
コマンド履歴から検索する感じで、見つけたコマンドをコマンドライン上に表示して、編集してから実行できるようにします。

```sh
$ cat .zshrc
function pet-select() {
  BUFFER=$(pet search --query "$LBUFFER")
  CURSOR=$#BUFFER
  zle redisplay
}
zle -N pet-select
bindkey '^s' pet-select
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/56222/d3a73841-3a97-999e-f165-356ca45c47a7.gif" width="700">

# インストール
Macであればhomebrewでインストールできます。

```sh
$ brew install knqyf263/pet/pet
```

homebrewじゃなくてもGoで書いてあるので、バイナリをダウンロードすればすぐ実行可能です。
https://github.com/knqyf263/pet/releases

Go環境が入っている人は自分でビルドしてもOKです。

```sh
$ go get github.com/knqyf263/pet
```


# まとめ
自分がたまにしか打たないコマンドを忘れて困ってたので自作しました。
既存の方法でこんな風にやってるよ！とかこういう機能があればもっと便利！とかはどんどん教えていただきたいです。