Bash
Peco

Mac で bash でも peco-history を使いたい

More than 3 years have passed since last update.

こんな感じで上手くいくようです。

.bashrc
export HISTCONTROL="ignoredups"
peco-history() {
  local NUM=$(history | wc -l)
  local FIRST=$((-1*(NUM-1)))

  if [ $FIRST -eq 0 ] ; then
    # Remove the last entry, "peco-history"
    history -d $((HISTCMD-1))
    echo "No history" >&2
    return
  fi

  local CMD=$(fc -l $FIRST | sort -k 2 -k 1nr | uniq -f 1 | sort -nr | sed -E 's/^[0-9]+[[:blank:]]+//' | peco | head -n 1)

  if [ -n "$CMD" ] ; then
    # Replace the last entry, "peco-history", with $CMD
    history -s $CMD

    if type osascript > /dev/null 2>&1 ; then
      # Send UP keystroke to console
      (osascript -e 'tell application "System Events" to keystroke (ASCII character 30)' &)
    fi

    # Uncomment below to execute it here directly
    # echo $CMD >&2
    # eval $CMD
  else
    # Remove the last entry, "peco-history"
    history -d $((HISTCMD-1))
  fi
}
bind '"\C-x\C-r":"peco-history\n"'
また、以下のように直接標準のものと差し替えても問題無いようです。 bash は eval を使ってヒストリの実行は出来ますが、zsh とは違い、コマンドラインに書き戻すことが出来ないので、以下の設定はしない方が良さそうです。
bind '"\C-r":"peco-history\n"'

追記:
コメント欄にも書きましたが、最新の修正で確実に履歴の最後に選択されたコマンドが追加されるので、peco 終了後、直接 eval で実行するよりも ↑で履歴を手繰った方が安全でかつ、修正も出来るという結論に達しました。
なので、"\C-r" を差し替えても問題無いですね。

追記:
(osascript -e 'tell application "System Events" to keystroke (ASCII character 30)' &)
で ↑ をコンソールに送るようにしたので、目標の動作に達した感じです。