3

While I develop some Emacs-Lisp code, I often test it in the *scratch* buffer, just to make sure that what I just wrote behaves like I believe it does.

But sometimes evaluating an expression takes several minutes and it is too bad that Emacs is frozen during this time. I'd love it if *scratch* behaved like the *shell* buffer with an interactive sub-shell. From the manual:

While the subshell is waiting or running a command, you can switch windows or buffers and perform other editing in Emacs. Emacs inserts the output from the subshell into the Shell buffer whenever it has time to process it (e.g., while waiting for keyboard input).

Is there a package that provides such an interactive Emacs-Lisp eval-loop running asynchronously?

I understand that there are technical difficulties. E.g., I always assume that the environment Emacs is maintaining (defined functions, global variable values, ..) is the same for editing and for Lisp-interaction. If the evaluation of my code in *scratch* reveals a bug, I'll amend the code, eval-defun it, and try it again. So I expect that the eval-loop with which I am communicating in the *scratch* buffer is aware of the new definition.

phs
  • 1,095
  • 6
  • 13

1 Answers1

3

Try the async package (M-x package-install, if you don't already have it).

See the functions async-start and async-inject-variables. The given example is:

(async-start
   `(lambda ()
      (require 'smtpmail)
      (with-temp-buffer
        (insert ,(buffer-substring-no-properties (point-min) (point-max)))
        ;; Pass in the variable environment for smtpmail
        ,(async-inject-variables \"\\`\\(smtpmail\\|\\(user-\\)?mail\\)-\")
        (smtpmail-send-it)))
   'ignore)

Aside from that helper for variables, the code being evaluated would probably need to load any necessary libraries or otherwise include function definitions, as async is handing off to a completely independent emacs process.


With recent GNU Emacs versions you could also consider whether your code might be able to use threads to avoid blocking for so long in the first place. See C-hig (elisp)Threads

phils
  • 48,657
  • 3
  • 76
  • 115
  • Can we run `ielm` using async? Having a CLI and not blocking too - or is that too much to ask? – NickD Jun 07 '20 at 15:08
  • You mean run a version of `ielm` in the parent instance where every evaluation took place in a persistent inferior Emacs process? I'm not sure `async` is the right tool for that. It sounds do-able, though -- that's exactly how every other external REPL process with an Emacs front-end works, after all. Obviously it wouldn't have access to your local environment, though. – phils Jun 07 '20 at 21:57