GNU bug report logs - #50815
28.0.50; Alternative method to persist Comint history

Previous Next

Package: emacs;

Reported by: Augusto Stoffel <arstoffel <at> gmail.com>

Date: Sun, 26 Sep 2021 12:14:02 UTC

Severity: normal

Found in version 28.0.50

To reply to this bug, email your comments to 50815 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#50815; Package emacs. (Sun, 26 Sep 2021 12:14:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Augusto Stoffel <arstoffel <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sun, 26 Sep 2021 12:14:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Augusto Stoffel <arstoffel <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 28.0.50; Alternative method to persist Comint history
Date: Sun, 26 Sep 2021 14:13:16 +0200
I was trying to make the Python shell persist its history and I couldn't
make it work well with the existing method (`comint-read-input-ring' and
`comint-write-input-ring'), for the following reasons:

- Some user commands (initialization, eval region, completion) send code
  to the inferior process behind the scenes, and this ends up recorded
  in the interpreter's history file.
- The Python interpreter is not as smart as bash when it comes to saving
  the history file.  It fails to do so if it's killed abruptly (e.g., by
  killing the comint buffer).  Somehow I couldn't make it work via a
  process sentinel either.
- The IPython interpreter, on the other hand, is overly smart and uses a
  database instead of a plain history file.

Now I found an alternative that works well for me.  It relies on the
savehist mechanism:

    (defvar-local comint-history-variable nil)

    (advice-add 'comint-add-to-input-history :after-while
                (lambda (cmd)
                  (when comint-history-variable
                    (add-to-history comint-history-variable
                                    (substring-no-properties cmd)))))

    (defun comint-history-setup ()
      (setq comint-history-variable (intern (concat (symbol-name major-mode)
                                                    "-history")))
      (unless (boundp comint-history-variable)
        (set comint-history-variable nil))
      (add-to-list 'savehist-minibuffer-history-variables comint-history-variable)
      (dolist (it (symbol-value comint-history-variable))
        (ring-insert-at-beginning comint-input-ring it)))

    (add-hook 'inferior-python-mode-hook 'comint-history-setup)

So the idea is to save each input to the comint twice: once in the
buffer-local `comint-input-ring' (for the purposes of `M-n', `M-p',
etc.), and once globally in the place pointed by
`comint-history-variable' (for the purposes of persistence).

This is a bit of a hack, but I think the only alternative would be to
make ring.el interact well with `savehist-mode', a much more drastic
change (but one that isearch might benefit from, for instance).

Note also that many Comints have their version of `M-!', and this funny
`comint-history-variable' could be used there as well---one more small
reason to say it's a desirable feature. :-)

Anyway, do you think this looks reasonable? Then I would format a patch
(without the various corner-cuts of the above, of course).  This
wouldn't change the regular shell, but would add this new feature to
comint.el and make the Python shell use it.




This bug report was last modified 2 years and 209 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.