EshellHistory

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


CategoryEshell