Zshのコマンド対象履歴をEmacsで使えるように、あとEscキーとか

zsh

おはようございます。福山です。

VPSでサーバーとのやり取りにssh,zshを頻繁に使うようになったので、メモります。

環境はMacOSXLionのEmacs23.4で、multi-termを使用しています。

コマンドに対する履歴を出す。

cd と入力して、ここでcdだけの履歴を出したい... それを実現する方法です。

ターミナルなどからは ~/.zshenv にM-n,M-pキーバインドを指定するだけで使えます。(キーバインド一覧はzshから bindkey コマンドを実行するとずらーと出ます。)

autoload history-search-end
zle -N history-beginning-search-backward-end history-search-end
zle -N history-beginning-search-forward-end history-search-end
bindkey "ep" history-beginning-search-backward-end
bindkey "en" history-beginning-search-forward-end

これで、EmacsでもM-n,M-pが使えるかと思いきや通常の履歴移動になりました。Emacs multi-termでzshにしっかりコマンドを渡すには、以下のように~/emacs.d/init.el or emacs.elに記述します。

(add-hook 'term-mode-hook
     (lambda ()
        (define-key term-raw-map (kbd "M-p")
          (lambda ()
            "history-beginning-search-backward-end"
            (interactive)
            (term-send-raw-string "ep")))
        (define-key term-raw-map (kbd "M-n")
          (lambda ()
            "history-beginning-search-forward-end"
            (interactive)
            (term-send-raw-string "en")))
        ))

ESCキー対策

viを使ったら最後、インサートモードから抜けられなくなるという、Emacsのやきもちです。

これは困るということで

(add-hook 'term-mode-hook
     (lambda ()
        ;; ESC2回でtermのESC1回分、
        (define-key term-raw-map (kbd "ESC ESC")
          (lambda ()
            "ESCを渡す"
            (interactive)
            (term-send-raw-string "e")))
        ))

苦し紛れにEscキーを2回押すと、シェル上ではEscキーを一度押したと見なしてくれるようになります。

少しだけ編集したいときには便利です。Escキーを1回で渡すにはメタキー(M-)が犠牲になりますからね。

参考