Subject: Re: bug#36034: [PATCH] Zsh extended_history shows up in comint input ring

From: Matthew Bauer <[email-masked]>
Date: Wed, 18 Mar 2020 11:05:09 -0400

Sorry for the late reply. Attached is the updated patch, using looking-at
and on top of latest Emacs master.

On Thu, Jul 4, 2019 at 9:37 AM Lars Ingebrigtsen <[email-masked]> wrote:

> Matthew Bauer <[email-masked]> writes:
>
> >                   (setq start
> >                         (if (re-search-backward
> comint-input-ring-separator
> >                                                 nil t)
> > -                           (match-end 0)
> > -                         (point-min)))
> > +                           (progn
> > +                             (when comint-input-ring-file-prefix
> > +                               ;; Skip zsh extended_history stamps
> > +                               (re-search-forward
> comint-input-ring-file-prefix
> > +                                                  nil t))
> > +                             (match-end 0))
>
> Hm...  I don't think this is right, either.  If the re-search-forward
> fails, then (match-end 0) will fail, too.  And since (if I understood
> correctly), the prefix will follow on directly from where point it,
> using looking-at would be better, anyway...
>
> >        ;; Bypass a bug in certain versions of bash.
> >        (when (string-equal shell "bash")
> >          (add-hook 'comint-preoutput-filter-functions
> > -                  'shell-filter-ctrl-a-ctrl-b nil t)))
> > +                  'shell-filter-ctrl-a-ctrl-b nil t))
> > +
> > +      ;; Skip extended history for zsh.
> > +      (when (string-equal shell "zsh")
> > +        (setq-local comint-input-ring-file-prefix ":
> [[:digit:]]+:[[:digit:]]+;")))
> >      (comint-read-input-ring t)))
>
> And this bit didn't apply.
>
> --
> (domestic pets only, the antidote for overdose, milk.)
>    bloggy blog: http://lars.ingebrigtsen.no
>
From 042754dfa875a1bd169b6ff2247ec94c75e1f789 Mon Sep 17 00:00:00 2001
From: Matthew Bauer <[email-masked]>
Date: Wed, 18 Mar 2020 10:59:45 -0400
Subject: [PATCH] Add zsh extended_history handling for comint.el input ring
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Adds handling of the Zsh extended_history to comint.el input
ring. This means that the timestamp doesn’t show up when reading
through history from other shells. The lines look like this:

: <beginning time>:<elapsed seconds>;<command>

This patch skips the part before <command> when the ‘shell’ is
zsh. This is done through the comint-input-ring-file-prefix
variable. When set, this will skip a prefix of the file when loading
into the input ring. This matches the behavior of Zsh. Zsh documents
it here:

http://zsh.sourceforge.net/Doc/Release/Options.html#History
---
 lisp/comint.el | 20 ++++++++++++++++++--
 lisp/shell.el  |  6 +++++-
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/lisp/comint.el b/lisp/comint.el
index ea06f8af87..03898c3027 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -249,6 +249,10 @@ to set this in a mode hook, rather than customize the default value."
 		 file)
   :group 'comint)
 
+(defvar comint-input-ring-file-prefix nil
+  "The prefix to skip when parsing the input ring file.
+This is useful in Zsh when the extended_history option is on.")
+
 (defcustom comint-scroll-to-bottom-on-input nil
   "Controls whether input to interpreter causes window to scroll.
 If nil, then do not scroll.  If t or `all', scroll all windows showing buffer.
@@ -987,8 +991,20 @@ See also `comint-input-ignoredups' and `comint-write-input-ring'."
                            (setq end (match-beginning 0)))
                  (setq start
                        (if (re-search-backward ring-separator nil t)
-                           (match-end 0)
-                         (point-min)))
+                           (progn
+                             (when (and comint-input-ring-file-prefix
+                                        (looking-at comint-input-ring-file-prefix))
+                               ;; Skip zsh extended_history stamps
+                               (re-search-forward comint-input-ring-file-prefix
+                                                  nil t))
+                             (match-end 0))
+                         (progn
+                           (goto-char (point-min))
+                           (when (and comint-input-ring-file-prefix
+                                      (looking-at comint-input-ring-file-prefix))
+                             (re-search-forward comint-input-ring-file-prefix
+                                                nil t))
+                           (point))))
                  (setq history (buffer-substring start end))
                  (goto-char start)
                  (when (and (not (string-match history-ignore history))
diff --git a/lisp/shell.el b/lisp/shell.el
index 1e2679f723..3a63949821 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -622,7 +622,11 @@ buffer."
       ;; Bypass a bug in certain versions of bash.
       (when (string-equal shell "bash")
         (add-hook 'comint-preoutput-filter-functions
-                  #'shell-filter-ctrl-a-ctrl-b nil t)))
+                  #'shell-filter-ctrl-a-ctrl-b nil t))
+
+      ;; Skip extended history for zsh.
+      (when (string-equal shell "zsh")
+        (setq-local comint-input-ring-file-prefix ": [[:digit:]]+:[[:digit:]]+;")))
     (comint-read-input-ring t)))
 
 (defun shell-apply-ansi-color (beg end face)
-- 
2.23.1