Eshell に zsh の history-beginning-search-forward (backward) を移植した.
三日坊主ってレベルじゃないけど気にしない!
Eshell は Emacs 上に実装されたシェルで,Emacs lisp で自由に拡張することが可能です.
が,デフォルトだと zsh などの他のシェルと比較して機能が少なく,そのまま使うには結構不便です.
機能がないなら実装すればいいじゃない!
というわけで,他のシェルの素敵機能を Eshell 上に実装していくことにしました.
history-beginning-search-forward (backward) って何?
これは zsh で使える素敵機能です (bash 等でも使えるのかは知りません).
例えば,プロンプトに以下を入力したとします(_ は現在のカーソル位置).
$ sudo _
この状態で history-beginning-search-forward や history-beginning-search-backward を使うことで,履歴の中から "sudo " で始まるものだけをたどることができます.
超便利です.この機能を使っていない人は,今すぐ .zshrc に
bindkey '^P' history-beginning-search-backward bindkey '^N' history-beginning-search-forward
を追加しましょう.
今回はこの機能を Eshell に移植しました.
以下を .emacs.el などにコピーすることで使えるようになります.
(require 'em-hist) (defun eshell-history-beginning-search-backward (arg) "arg で始まる履歴を検索して補完する. zsh の history-beginning-search-backward にあたる機能." (interactive "p") (if (equal eshell-history-index (1- (ring-length eshell-history-ring))) (progn (eshell-bol) (delete-region (point) (point-max))) (let ((cur (point))) (eshell-previous-matching-input-from-input arg) (delete-region (point) (point-max)) (goto-char cur) (setq this-command 'eshell-previous-matching-input-from-input)))) (defun eshell-history-beginning-search-forward (arg) "arg で始まる履歴を検索して補完する. zsh の history-beginning-search-forward にあたる機能." (interactive "p") (if (or (null eshell-history-index) (zerop eshell-history-index)) (progn (eshell-bol) (delete-region (point) (point-max))) (let ((cur (point))) (eshell-next-matching-input-from-input arg) (delete-region (point) (point-max)) (goto-char cur) (setq this-command 'eshell-next-matching-input-from-input)))) (add-hook 'eshell-mode-hook (lambda () (local-set-key [?\C-p] 'eshell-history-beginning-search-backward) (local-set-key [?\C-n] 'eshell-history-beginning-search-forward)))