[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 3a7abc7e497: Add option eshell-history-append

From: Sean Whitton
Subject: master 3a7abc7e497: Add option eshell-history-append
Date: Thu, 7 Dec 2023 06:32:52 -0500 (EST)

branch: master
commit 3a7abc7e497e77ba9bc5a71f3836636675dffe6b
Author: Liu Hui <liuhui1610@gmail.com>
Commit: Sean Whitton <spwhitton@spwhitton.name>

    Add option eshell-history-append
    * lisp/eshell/em-hist.el (eshell-history-append): New option.
    (eshell--save-history): New function.
    (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 
                         "Save input history for Eshell buffer `%s'? "
                         (buffer-name buf)))))
-             (eshell-write-history)))))
+             (eshell--save-history)))))
 (defun eshell/history (&rest args)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]