Keys like M-p, M-n function just as in shell — they can be used to access history (see MinibufferHistory).
There are additional modes within eshell (see eshell-startup help) which allow you to configure eshell such that commands like <arrow-up> and <arrow-down> can be used to access history just as in zsh or bash.
Imagine i am running lisp or some other application inside eshell. In that application, I type a hairy expression:
(some:hairy/function\ (+ (if dkjhjhdfkhfd kjdfhkjhdfkj) 33))).
Now, on the next line, you want to write the same expression but modify the 33 to 34. How do you do that? A simple M-p <and some editing> right? No. eshell-hist stops working within applications. A way around is to use shellhist.el — http://www.gnufans.net/~deego/emacspub/lisp-mine/shellhist/ which allows eshell-history to work across applications.
I came up with another way to enable the eshell history from within applications. It involves patching the elisp source however. I am fairly new to elisp and not intimately familiar with the eshell source, so use this at your own risk.
Download the following patch file: http://www.gazingus.org/misc/esh-mode.patch
This file contains the following lines:
--- esh-mode.el Fri Aug 13 22:43:12 2004
+++ esh-mode.my Fri Aug 13 22:43:13 2004
@@ -710,7 +710,8 @@
(process-send-string (eshell-interactive-process) "\n"))
(process-send-region (eshell-interactive-process)
eshell-last-input-start
- eshell-last-input-end)))
+ eshell-last-input-end)
+ (run-hooks 'eshell-input-filter-functions)))
(if (= eshell-last-output-end (point))
(run-hooks 'eshell-post-command-hook)
(let (input)From the directory where you saved the patch file, run this command:
cat esh-mode.patch | patch -b -d /path/to/eshell/directory
This will patch esh-mode.el and create a backup of the original named esh-mode.el.orig. Byte-compile the patched file (M-x byte-compile-file RET).
You will then need to tell eshell how to recognize the prompts in the various applications you will be using. Set the eshell-prompt-regexp variable in your .emacs file to something like this:
(setq eshell-prompt-regexp
(mapconcat
'(lambda (str) (concat "\\(" str "\\)"))
'("^[^#$\n]* [#$] " ; default
"^\\(mysql\\|[ ]\\{4\\}[-\"'`]\\)> "
"^>>> " ; python
"^ftp> "
)
"\\|"))Restart emacs, invoke eshell, and run an application (say, mysql). You should now be able to use M-p, M-n, and the up/down arrow keys to cycle through the eshell history within the application!
The downsides to this method are:
In eshell currently (24.3.1) you can’t use !$ to refer to the last component of the previous command. (I use this all the time in other shells). Anyway, here’s a quick fix:
;; Fix eshell history completion to allow !$ ;; This is done by advising eshell-history-reference to expand !$ ;; into !!:$ which works... (defadvice eshell-history-reference (before ben-fix-eshell-history) "Fixes eshell history to allow !$ as abbreviation for !!:$" (if (string= (ad-get-arg 0) "!$") (ad-set-arg 0 "!!:$"))) (ad-activate 'eshell-history-reference)
--Ben Moseley
I just retrained myself to use $_, which works in both eshell and bash.
– JoeE
I use eshell mode quite extensively for my daily work. To have quick access to eshells history, I prefer to use ido-completing-read. Have a look at a code snippet from my init.el.
(add-hook 'eshell-mode-hook
(lambda ()
(local-set-key (kbd "C-c h")
(lambda ()
(interactive)
(insert
(ido-completing-read "Eshell history: "
(delete-dups
(ring-elements eshell-history-ring))))))
(local-set-key (kbd "C-c C-h") 'eshell-list-history)))– Markus P