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.

3
  • 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 8, 2014 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 8, 2014 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 3, 2017 at 2:50

1 Answer 1

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.)

3
  • 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 2, 2015 at 1: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! Sep 11, 2016 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. Apr 1, 2022 at 5:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.