All, When I in the emacs shell (run by M-x shell) and press M-r, it only search a very limited command history and doesn't search the bash_history file. But it is said Emacs shell will read my bash's history file to initialize it's history (https://www.gnu.org/software/emacs/manual/html_node/emacs/Shell-Ring.html). How can I make M-r in shell to search the bash_history?

  • When you start the shell, its history file is imported into comint-input-ring which is limited by C-h v comint-input-ring-size. If that value is smaller than the number of lines in your history file, then you can try setting a higher value (and then starting a new shell) to see if you get better results. – phils Jun 27 '19 at 7:09
  • @phils, thanks. But it seems doesn't load all bash_history. I've set comint-input-ring-size to 5000, and my bash_history is 2000. But the input history in the shell is 1199. However, it is larger than the previous 500 size. I'll report more what I find later. – zwy Jul 4 '19 at 10:37
  • Not sure if it fits your use case, but I've found that multi-term behaves much more reasonably than shell, plus you can have multiple terminals open. – Silfheed Jul 30 '19 at 22:02
  • @Silfheed thanks. But I prefer "M-x shell" for it behaves more like an emacs buffer. I've tried ansi-term before and turn back to "M-x shell" now. – zwy Jul 31 '19 at 4:40
  • @zwy fwiw, while multi-term is based on term.el (and therefore ansi-term), it is significantly different for the better in regards to behaving like any other emacs buffer. I've used shell, eshell and ansi-term but never managed to move to regularly using a terminal in emacs until I started using multi-term. – Silfheed Jul 31 '19 at 22:41

I find a solution from here: http://wikemacs.org/wiki/Shell#Usage

By default a shell session inside emacs via shell-mode won't persist accross sessions and won't read your shell's history.

(add-hook 'shell-mode-hook 'my-shell-mode-hook)
(defun my-shell-mode-hook ()
(setq comint-input-ring-file-name "~/.zsh_history")  ;; or bash_history
(comint-read-input-ring t))

If you want to support remote file, here it is:

(defun my-shell-mode-hook ()
  (setq comint-input-ring-file-name
    (if (file-remote-p default-directory)
        (with-parsed-tramp-file-name default-directory nil
           (tramp-file-name-method v)
           (tramp-file-name-user v)
           (tramp-file-name-domain v)
           (tramp-file-name-host v)
           (tramp-file-name-port v)
 (comint-read-input-ring t))
| improve this answer | |

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.