16

When I run shell-command in a new session I do not have access to the history of commands from the last session. How can I have that?

RasmusWL
  • 267
  • 2
  • 7
  • 1
    do you have `(savehist-mode)` enabled? – waymondo Mar 11 '15 at 05:10
  • If you are talking about `M-!`, the history variable it reads/writes from is `shell-command-history`, which is covered with `(savehist-mode)`. If the request is about keeping a persistent history of the `comint-input-ring` in shell buffers, I can assist with that too, but from how i'm interpreting the question, this would accomplish it. – waymondo Mar 11 '15 at 16:30
  • @waymondo no, I did not. solves my problem. Please make an answer so I can accept it. – RasmusWL Mar 11 '15 at 17:14

3 Answers3

15

The short answer is enable (savehist-mode) in your .emacs. This will save all minibuffer history rings by default, which includes shell-command-history which is used by M-! / (shell-command).


While I'm at it, I figure I'll also explain how to load/save command histories from shell-mode prompts and other modes that derive from comint-mode.

Note: this is for my setup with bash and OSX, but the guts of this should work in most environments.

  • First you need to copy your bash shell history into your emacs' environment. By default this is stored in a variable called "HISTFILE". I do this with the (exec-path-from-shell) package like so:

    (exec-path-from-shell-initialize)
    (exec-path-from-shell-copy-env "HISTFILE")
    
  • Then you need to call (turn-on-comint-history) in your appropriate mode hooks, i.e.

    (defun turn-on-comint-history (history-file)
              (setq comint-input-ring-file-name history-file)
              (comint-read-input-ring 'silent))
    
    (add-hook 'shell-mode-hook
              (lambda ()
                (turn-on-comint-history (getenv "HISTFILE"))))
    
    (add-hook 'inf-ruby-mode-hook
              (lambda ()
                (turn-on-comint-history ".pry_history")))
    

For interactive ruby modes, you can see I'm using a local .pry_history file on a per-project basis.

  • Then you need to make sure you save your comint history files when killing buffers and emacs:

    (add-hook 'kill-buffer-hook #'comint-write-input-ring)
    (add-hook 'kill-emacs-hook
              (lambda ()
                (--each (buffer-list)
                  (with-current-buffer it (comint-write-input-ring)))))
    

Note I am using dash.el for the succinct (--each) formatting.

This will make your minibuffer shell command history persistent as well as your bash prompt command history between emacs and other terms.

drets
  • 213
  • 1
  • 10
waymondo
  • 1,384
  • 11
  • 16
2

I'm sure that savehist can manage this, here is my setup:

;; Save sessions history
(setq savehist-save-minibuffer-history 1)
(setq savehist-additional-variables
      '(kill-ring search-ring regexp-search-ring compile-history log-edit-comment-ring)
      savehist-file "~/.emacs.d/savehist")
(savehist-mode t)
yPhil
  • 963
  • 5
  • 22
0

I think you can advice shell-command to save history and remap some related key bindings, e.g., M-n/p, for invoking that history, or even write your own shell-command by using read-from-minibuffer if you like.

xuchunyang
  • 14,302
  • 1
  • 18
  • 39