From 3a7abc7e497e77ba9bc5a71f3836636675dffe6b Mon Sep 17 00:00:00 2001 From: Liu Hui Date: Thu, 16 Nov 2023 11:45:28 +0800 Subject: [PATCH] Add option eshell-history-append * 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) --- doc/misc/eshell.texi | 19 ++++++++++++++----- etc/NEWS | 6 ++++++ lisp/eshell/em-hist.el | 16 +++++++++++++--- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index e8aa8cdc6a3..99a1491f1c3 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -1237,11 +1237,20 @@ command containing @code{foo}. The n-th argument of the last command 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 diff --git a/etc/NEWS b/etc/NEWS index c55719416d3..e14ab4aed27 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -617,6 +617,12 @@ calling external rgrep. +++ *** 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'. diff --git a/lisp/eshell/em-hist.el b/lisp/eshell/em-hist.el index cf03f8399a6..79336204847 100644 --- a/lisp/eshell/em-hist.el +++ b/lisp/eshell/em-hist.el @@ -116,6 +116,12 @@ If set to t, history will always be saved, silently." (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 @@ -294,17 +300,21 @@ Returns nil if INPUT is prepended by blank space, otherwise non-nil." (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)) @@ -318,7 +328,7 @@ Returns nil if INPUT is prepended by blank space, otherwise non-nil." (format-message "Save input history for Eshell buffer `%s'? " (buffer-name buf))))) - (eshell-write-history))))) + (eshell--save-history))))) t) (defun eshell/history (&rest args) -- 2.39.2