12

I can't make Emacs remember the history for *ielm* buffers between sessions. As far as I can tell, such history is recorded in the buffer-local variable comint-input-ring. Therefore I have added the following expression to my init file:

(setq desktop-locals-to-save
    (append desktop-locals-to-save
            '((comint-input-ring . 50))))

It doesn't work. I know that the desktop package is working because Emacs remembers the global variables that I have added to desktop-globals-to-save in my init file.

--

EDIT: savehist does not work either. I suppose that is because comint-input-ring is a buffer-local variable.

Eleno
  • 1,448
  • 11
  • 17
  • 1
    No time now to check why it might not work for desktop. But you can try using savehist.el and adding this variable to the list of vars to save. – Drew Dec 08 '14 at 14:50
  • Thanks, Drew, but I had thought about savehist already (sorry for not mentioning it). As far as I could see, it was for global variables only, whilst comint-input-ring is buffer-local. Now, I have tried it anyway, without success. – Eleno Dec 08 '14 at 15:11
  • WARNING: The following solution is blasphemy!!!! Comment out inside comint.el the following two lines of code: (put 'comint-input-ring 'permanent-local t) and (make-local-variable 'comint-input-ring). Then, add comint-input-ring to desktop-locals-to-save. Finally, re-byte-compile the applicable files, restart Emacs and enjoy living life to the fullest. – lawlist Dec 03 '17 at 02:50

1 Answers1

9

You can save the buffer-local value of comint-input-ring in a global variable when an *ielm* buffer is killed and restore it in inferior-emacs-lisp-mode-hook:

;; global copy of the buffer-local variable
(defvar ielm-comint-input-ring nil)

(defun set-ielm-comint-input-ring ()
  ;; create a buffer-local binding of kill-buffer-hook
  (make-local-variable 'kill-buffer-hook)
  ;; save the value of comint-input-ring when this buffer is killed
  (add-hook 'kill-buffer-hook #'save-ielm-comint-input-ring)
  ;; restore saved value (if available)
  (when ielm-comint-input-ring
    (message "Restoring comint-input-ring...")
    (setq comint-input-ring ielm-comint-input-ring)))

(defun save-ielm-comint-input-ring ()
  (message "Saving comint-input-ring...")
  (setq ielm-comint-input-ring comint-input-ring))

(require 'ielm)
(add-hook 'inferior-emacs-lisp-mode-hook #'set-ielm-comint-input-ring)

Now you should be able to add ielm-comint-input-ring to savehist-additional-variables to get the behavior you want. (I tested this approach; you should be able to use desktop-locals-to-save too, though.)

Constantine
  • 9,122
  • 1
  • 35
  • 50
  • 3
    You should use the LOCAL argument to add-hook, rather than manually calling make-local-variable on kill-buffer-hook. The latter could cause problems when subsequently trying to add callbacks to the hook globally. – phils Mar 02 '15 at 01:20
  • 1
    I was very pleased to find that this worked for inf-mongo as well (or, presumably, any other mode that uses comint)

    That is so helpful, and also taught me a little more elisp... thanks!

    – Blake Miller Sep 11 '16 at 22:15
  • Add (add-hook 'savehist-save-hook (lambda () (and (get-buffer "*ielm*") (kill-buffer "*ielm*")))) to make it save the latest history in your *ielm* buffer in case you don't explicitly kill that buffer before exiting emacs. – Peter Slotko Apr 01 '22 at 05:08