12

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?

  • 1
    do you have (savehist-mode) enabled? – waymondo Mar 11 '15 at 5: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
10

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.

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)
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.