* lisp/eshell/em-hist.el (eshell-history-append): New option.
(eshell--save-history): New function.
(eshell-hist-initialize):
(eshell-save-some-history): Replace eshell-write-history with
eshell--save-history, which respects the new option.
* doc/misc/eshell.texi (History): Document the change.
* etc/NEWS: Announce the change. (Bug#66700)
beginning with @code{foo} is accessible by @code{!foo:n}.
@vindex eshell-history-file-name
-The history ring is loaded from a file at the start of every session,
-and written back to the file at the end of every session. The file path
-is specified in @code{eshell-history-file-name}. Unlike other shells,
-such as Bash, Eshell can not be configured to keep a history ring of a
-different size than that of the history file.
+@vindex eshell-history-append
+The history is loaded to the history ring from the file
+@code{eshell-history-file-name} at the start of every session, and
+saved to that file at the end of every session. The default history
+saving behavior is to overwrite the history file with the whole
+history ring of the session. If @code{eshell-history-append} is
+non-@code{nil}, the history will instead be saved by appending new
+entries from the session to the history file, which could prevent
+potential history loss with multiple Eshell sessions. Unlike other
+shells, such as Bash, Eshell cannot currently be configured to control
+the size of the history file. In particular, when
+@code{eshell-history-append} is non-@code{nil}, the size of the file
+will keep increasing, and the recommended way to truncate the file is
+to run the @samp{history -w} command in an Eshell session.
Since the default buffer navigation and searching key-bindings are
still present in the Eshell buffer, the commands for history
+++
*** If a command exits abnormally, the Eshell prompt now shows its exit code.
++++
+*** New user option 'eshell-history-append'.
+If non-nil, each Eshell session will save history by appending new
+entries of that session to the history file rather than overwriting
+the file with the whole history of the session. The default is nil.
+
** Minibuffer and Completions
*** New commands 'previous-line-completion' and 'next-line-completion'.
(const :tag "Ask" ask)
(const :tag "Always save" t)))
+(defcustom eshell-history-append nil
+ "If non-nil, append new entries to the history file when saving history."
+ :type '(choice (const :tag "Overwrite history file" nil)
+ (const :tag "Append new entries to file" t))
+ :version "30.1")
+
(defcustom eshell-input-filter 'eshell-input-filter-default
"Predicate for filtering additions to input history.
Takes one argument, the input. If non-nil, the input may be saved on
(if eshell-history-file-name
(eshell-read-history nil t))
- (add-hook 'eshell-exit-hook #'eshell-write-history nil t))
+ (add-hook 'eshell-exit-hook #'eshell--save-history nil t))
(unless eshell-history-ring
(setq eshell-history-ring (make-ring eshell-history-size)))
- (add-hook 'eshell-exit-hook #'eshell-write-history nil t)
+ (add-hook 'eshell-exit-hook #'eshell--save-history nil t)
(add-hook 'kill-emacs-query-functions #'eshell-save-some-history)
(add-hook 'eshell-input-filter-functions #'eshell-add-to-history nil t))
+(defun eshell--save-history ()
+ "Save the history for current Eshell buffer."
+ (eshell-write-history nil eshell-history-append))
+
(defun eshell-save-some-history ()
"Save the history for any open Eshell buffers."
(dolist (buf (buffer-list))
(format-message
"Save input history for Eshell buffer `%s'? "
(buffer-name buf)))))
- (eshell-write-history)))))
+ (eshell--save-history)))))
t)
(defun eshell/history (&rest args)