今なんでもと書かれていたのでShell Script Advent Calendar 2017 - Qiita5日目ですが普段の記事です。
使い方
ブラウザと異なり/
は多用するので@/
をトリガーに変更。
@/thoge
でタグ検索。@/khoge
でキーワード検索です。
現状トリガーそのまま流す方法を用意していないので使わなさそうなのを。
Ajaxのような非同期通信は無理なので、エンターの実行で初めて通信・選択し、コマンド編集中に戻ってきます。
使いみちは特に無いです。
wall
コマンドで君の好きな名言を叫ぼう!
自鯖立ててスニペットをタグ付きで登録していくなんて使い方もできるかな。
zshの設定ファイルの共有で十分かな。
bash版も作れそうだけど力尽きたー!
コード
autoload -Uz add-zsh-hook
add-zsh-hook preexec -isone
-isone () {
local cmd="${1}"
local root_url='https://kotoha-server.herokuapp.com'
local tag_pattern='@/t(\S+)'
local keyword_pattern='@/k(\S+)'
local query
local replace_pattern
#setopt BASH_REMATCH; を使えば$matchは無し。動きが微妙に違うので注意
if [[ $cmd =~ $tag_pattern ]]; then
query='?tag='$match[1]
replace_pattern=$tag_pattern
elif [[ $cmd =~ $keyword_pattern ]]; then
query='?text='$match[1]
replace_pattern=$keyword_pattern
else
return 0
fi
# ""を外すならjqに-rオプション
local words=`wget -q -O - "${root_url}/api/phrases.json${query}" | jq '.[].text'`
if [ -z $words ]; then
echo "${fg[red]}No Results : $match[1]${reset_color}"
else
local word=`echo $words | peco`
if [ -z $word ]; then
echo "${fg[red]}Abort peco${reset_color}"
else
cmd=`echo ${cmd} | sed -r "s#${replace_pattern}#${word}#"`
fi
fi
print -z $cmd
kill -INT 0
}
読み込み
ファイルを置いて読み込みか直接書く。
読み込みの場合はshebangが必要な場合があるかもしれません。
. (path)~/isone.zsh
dependencies
-
peco/peco: Simplistic interactive filtering tool
バカの一つ覚えといいますか、他に1行選択できるやりかたを知らないので、他に良いのがあれば。1
参考
見たものを無秩序に列挙
-
いかに危険なコマンド実行間違いを防ぐか。そのためにExeCopを書いてみた - Copy/Cut/Paste/Hatena
k1LoW/execop: ExeCop is a checker that check commands and environment variables before execute command.
preexecタイミングでコマンドを検知・実行阻止できるかの実例。神。これ自体現場で使えそう。 -
bash で特定のコマンドを実行前にキャンセルする - tkuchikiの日記
(はてブ的に)↑の元ネタのようなもの(さらにtrapの元コードのようなものはStack Overflowに) -
zsh5.0.8に存在するローカル変数のパーサバグ - Qiita
yumで入れたzsh(5.0.2)でExeCop動かない問題。 -
CentOS 6.4にzsh最新版をソースから入れる - /dev/null
なくなくソースから。 -
konifar/kotoha: Kotoha is useful chrome extension that help you to quote a good phrase.
アニメの名言を簡単に引用できるChrome extension『Kotoha』作りました - Konifar's WIP
偉大なるどらえもん。ギークではない自分には中身を見る気になる程度の表面の面白みは重要。 -
heavenshell/vim-kotoha: vim-kotoha is useful Vim plugin that help you to quote a good phrase!
サードパーティがあるだけで実現可能性が見えてきて助かる。当然コードも大助かり。 -
zshにオプションや引数を補完できるキーバインドを設定しよう - Qiita
使えそうなzsh変数の解説。 -
jq コマンドを使う日常のご紹介 - Qiita
kotohaからのJSONレスポンスをそのまま使えてpecoで食べられる形へ整形。 -
test と [ と [[ コマンドの違い - 拡張 POSIX シェルスクリプト Advent Calendar 2013 - ダメ出し Blog
シェルスクリプトでの正規表現マッチ - Qiita
正規表現おさらい。 -
HTML特殊文字コード表
Markdownに[あると崩れる問題。普段は消すけど上記リンクは消すと意味不明なので。 -
Bash 正規表現マッチした部分文字列を再利用する方法 · DQNEO起業日記
後方参照。 -
zsh でシェルスクリプトを書くいくつかの理由
書き方からして$BASH_REMATCH
相当の$match
の存在を匂わす。 -
Regular Expressions
zshでのBASH_REMATCH
の使い方 -
regex - BASH_REMATCH doesn't capture - Stack Overflow
やはり$match
で。 - シェルスクリプトで空文字列かどうか調べる。 - masa.edw the ハバネロブリーダー
-
pecoでzshのコマンド履歴検索を超快適にする! - Qiita
zshでのpecoを使ったコマンドライン操作の確認と確証に。 -
逆順出力 tac と tail -r - Qiita
上のコマンド履歴検索CentOSで動かないぞ問題の調査。 -
bash/zsh のヒストリを peco で便利にする - Qiita
zsh と peco でヒストリ補完 - わ
ヒストリ検索で調べようとする自分が悪いし参考にはなるんですけど、zle前提になるのが。 -
zleを使わないでコマンドラインに値を入力した状態にする - Qiita
神。ショートカット始動でなければBUFFER
操作できないのかと挫折しかけたときに。
余話:そもそも
タイプ精度が悪すぎてコマンドの同じtypoをしたり、よく使うパスが頻出したりしていた…。
コマンドのtypo自体はこれで実行後に補正されるけれど、ちょっと遅い。
alias
はalias自体を忘れかねず、また求めていたのはコマンドの修正だったので、ちょっと違う。
abbr:fish流別名!入力後に展開される短縮コマンドを定義
がtypoコマンド修正の意図通りで、かなりGoodなんですが、文字列リテラルには非対応のあくまでコマンド限定。
両方書き換えたいという貪欲な欲求に、そう言えばコマンド実行前イベントがあってこれでコマンドの設定方法も知れたので、
あとは実行前に実行中断できればコマンド全体を好きに置換することができるなと調査しました。
結果ExeCopを見つけるものの、fishではkill -INT 0
が効かず断念。
zshで実現するかと入れているとき、常用しないもので実用的なものを作っても仕方ないと思い、同時期にちょうどFx版作りたいなと思っていたKotohaを動かすことに。こっちの方が面白いので。
だから本来はfishでやりたかったので、ご存じの方は中断方法を教えていただけるとうれしいです…
Bash版(挫折)
月曜日に投稿しようとしたらshellscriptのアドベントカレンダーを見つけたので空いた火曜日に投稿することにしました。
空いた月曜でbash移植しようとおもったのですが…
そもそものExeCopが正常に動かない(denyがループに陥る)
という状況で困った…
プリントデバッグではkill -INT 0
で中断しようとしているコマンドで再度trapが呼び出されるようで、(confirm no or denyの間)無限ループに。kill
の次の行に行かない。
手動で打つecho $$
とtrap内でのecho $$
のPIDの値が同じなので、まるごとkillからの復帰→コマンド継続とかになっている…?
ただ、ExeCopのアイデアもとになったスクリプトも同じ現象なので、異なる人が成功している時点でこちらの環境・バージョン依存濃厚です。
GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)
yumに更新があったので(4.2.46-29.el7_4
)上げて
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
もループしました。うーん…。
それでも移植するだけしてみたら、kill
による中断は出来るが、なぜかtrap
が一度しか反応せず、以後キーワードを入れても無視される現象に変わる。
そもそもprint -z
の代替が見つからないということで、ギブアップ。
-isone () {
local cmd="${1}"
local root_url='https://kotoha-server.herokuapp.com'
local tag_pattern='@/t(\S+)'
local keyword_pattern='@/k(\S+)'
local query
local replace_pattern
if [[ $cmd =~ $tag_pattern ]]; then
query='?tag='${BASH_REMATCH[1]}
replace_pattern=$tag_pattern
elif [[ $cmd =~ $keyword_pattern ]]; then
query='?text='${BASH_REMATCH[1]}
replace_pattern=$keyword_pattern
else
return 0
fi
# ""を外すならjqに-rオプション
local words="`wget -q -O - "${root_url}/api/phrases.json${query}" | jq '.[].text'`"
if [ -z "$words" ]; then
echo -e "\e[31mNo Results : $match[1]\e[m"
else
# 改行残して出力するため""追加
local word=`echo "$words" | peco --layout top-down`
if [ -z "$word" ]; then
echo -e "\e[31mAbort peco\e[m"
else
cmd=`echo ${cmd} | sed -r "s#${replace_pattern}#${word}#"`
fi
fi
#挿入方法不明
COMP_LINE=$cmd
READLINE_LINE="$cmd"
kill -INT 0
}
# ここExeCopそのまま拝借
isone () {
[ -n "$COMP_LINE" ] && return
[ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return
local cmd=''
cmd=$(HISTTIMEFORMAT='' history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//");
-isone "${cmd}"
}
# クォートしても最初に-があるとオプションとみなされもよう
trap 'isone' DEBUG
マネジメントとなぜかITエンジニア論がしばしば出てくるSHIROBAKO Advent Calendarは(なんと!)2017年も開催中!です!
-
不満は無いのですが、他を知らないので選んだ感がほしい。 ↩