読者です 読者をやめる 読者になる 読者になる

zshの履歴検索にanything.elを使う(ターミナル版)

zsh emacs

anything.elを使ってzshの履歴検索をする - http://rubikitch.com/に移転しましたを参考に, ポップアップせずにターミナル内で動くようにしてみた.

デモ


使い方

  1. anything.el一式をインストールする
  2. shell-history.elをインストールする
  3. 下記のanything-zsh-history.elを.emacsで読み込むようにする
  4. 下記のanything-history.zshrcを.zshrcで読み込むようにする
  5. emacszshを終了
  6. zshを実行
  7. emacs --daemonしておく
  8. C-rでanything.elによる履歴検索

細かな差異

ターミナル内で動く以外に以下の点を修正:

  • anything.elでの選択が完了したらコマンドを自動的に実行する
    • ANYTHING_HISTORY_DONT_EXECに値があれば, 選択したコマンド文字列が挿入されるだけ
  • zshemacsの間で選択したコマンドを受け渡すための一時的なファイル
  • すでになにか入力されていればanything.elに渡す

anything-zsh-history.el

(require 'anything-complete)

(defun anything-zsh-history-from-zle (file &optional input)
  (interactive)
  (let ((anything-samewindow t)
        (anything-display-function 'anything-default-display-buffer))
    (azh/set-command
     (anything
      `(((name . "History")
         (action
          ("Paste" . identity)
          ("Edit" . azh/edit-command))
         ,@anything-c-source-complete-shell-history))
      input
      nil nil nil
      "*anything zsh history*")
     file)))

(defun azh/set-command (line file)
  (write-region (or line "") nil file)
  (delete-frame))

(defun azh/edit-command (line)
  (switch-to-buffer "*zsh command edit*")
  (erase-buffer)
  (setq buffer-undo-list nil)
  (azh/edit-mode)
  (insert line)
  (recursive-edit)
  (buffer-string))

(define-derived-mode azh/edit-mode fundamental-mode
  "Press C-c C-c to exit!"
  "Edit zsh command line"
  (define-key azh/edit-mode-map "\C-c\C-c" 'azh/edit-exit))

(defun azh/edit-exit ()
  (interactive)
  (exit-recursive-edit))

anything-history.zshrc

function anything-history() {
    local tmpfile
    tmpfile=`mktemp`
    emacsclient -nw --eval \
        "(anything-zsh-history-from-zle \"$tmpfile\" \"$BUFFER\")"
    if [[ -n "$STY" ]]; then
        # screen 4.0.3 has a bug that altscreen doesn't work for emacs          
        (( `screen -v | cut -f 3 -d ' ' | cut -f 2 -d.` < 1 )) && zle -I
    fi
    zle -R -c
    if [[ -n "$ANYTHING_HISTORY_DONT_EXEC" ]]; then
        zle -U "`cat $tmpfile`"
    else
        BUFFER="`cat $tmpfile`"
        [[ -n "$BUFFER" ]] && zle accept-line
    fi
    rm $tmpfile
}
zle -N anything-history
bindkey "^R" anything-history
広告を非表示にする