はじめに
awk
の使い方がうろ覚えで,あれってどうやるんだっけ? と検索し直すことが多かったので何とかしたい.
peco
で過去のawk
履歴を探すのもありだけど,fish
なので補完で解決できたらいいんじゃないかな? と思い立って補完書いてみました.
補完設定
補完設定は以下のようにしました.
function __complete_awk_is_quoted # 入力中の語は ' か?
test (commandline -tc) = \'
end
function __complete_awk_quoted_expr # awk '...' を履歴から探して ... の部分を返す
builtin history \
| string match -r "awk +'(?:\\'|[^'])+'" \
| awk '{$1=""; print $0}' \
| string trim \
| string trim -c\'
end
complete -xc awk -n __complete_awk_is_quoted -a '(__complete_awk_quoted_expr)'
# デフォルトの補完メッセージが長々しいので上書き
complete -c awk -s f -d 'awk program file'
complete -xc awk -s F -d 'input field separator'
complete -xc awk -s v -d 'var=value'
最後の4行は本題と関係ないのでお好みで.
これを定義した状態でawk '
と入力し,Tab
を押すと過去に使ったawkスクリプトが補完されます.
その他
Q. '
の入力は必須?
必須っぽいです.
本当はawk
まで打ってTab
を押したら補完できるようにしたかったのですが,補完候補に例えば'{print $0}'
を設定すると'
がエスケープされて\'{print\ \$0}\'
になってしまったため断念.
awk '
まで打っておく必要があります.
Q. peco
みたいな絞込みがしたいんだけど
fish
だと,Tab
の代わりにShift + Tab
で補完モードに入ると部分一致検索できます.
おわりに
awk
の部分をsed
にすればsed
も同様に補完できそうです.ただ,今回の補完関数ではダブルクォーテーションで渡された引数は拾ってないので改良が必要かも.
grep
の検索条件も補完できそうですが,grep
はオプションも指定されていることが多いので,履歴からコマンドを抽出する部分にも改良が必要ですね...
追記 (2017/08/18)
awk '{print
のように,途中までコマンドを打った状態からも補完が効くようにしました.string
コマンド大活躍.
function __complete_awk_is_quoted # 文字列の入力中か?
string match -- "'*" (commandline -tc)
end
function __complete_awk_quoted_expr # awk '...' を履歴から探して入力中の語を含む ... を返す
set -l input (string sub -s 2 (commandline -tc))
builtin history \
| string match -r "(?<=awk ) *'(?:\\'|[^'])+'" \
| string trim \
| string trim -c\' \
| string match "*$input*"
end
complete -xc awk -n __complete_awk_is_quoted -a '(__complete_awk_quoted_expr)'