emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A UI approach for making synchronous commands asynchronous


From: Helmut Eller
Subject: Re: A UI approach for making synchronous commands asynchronous
Date: Tue, 01 Aug 2023 18:53:12 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

On Tue, Aug 01 2023, Spencer Baugh wrote:

> I think my "backgrounding" approach would be a perfect solution to this:
> start out blocking the UI waiting for the diff, but let the user hit a
> key to "background" it, to immediately create the window which will
> receive the diff asynchronously.  That works great both in fast and slow
> diff-generation scenarios.

I was wondering what would happen if Emacs would adopt a
one-thread-per-command strategy, i.e. every command starts out in a new
background thread.

Just for fun I came up with the patch from below.

Surprisingly, quite a few things worked. Like moving around in a
buffer, switching buffers, M-x list-threads. Even C-x C-c. Not
surprisingly, many things don't work. Like killing buffers.

Anyway, just wanted to share this idea, in case somebody wants to write
some actual code to give us some form of "background commands". It might
not even require a total rewrite of Emacs.

Helmut

diff --git a/lisp/simple.el b/lisp/simple.el
index 6dc08ff0eb0..de3152fde2d 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2752,6 +2752,7 @@ command-completion--command-for-this-buffer-function
   (let ((if (cconv--interactive-helper--if f)))
     `(interactive ,(if (functionp if) `(funcall ',if) if))))
 
+(defvar background-thread nil)
 (defun command-execute (cmd &optional record-flag keys special)
   ;; BEWARE: Called directly from the C code.
   "Execute CMD as an editor command.
@@ -2803,7 +2804,17 @@ command-execute
           (execute-kbd-macro final prefixarg))
          (t
           ;; Pass `cmd' rather than `final', for the backtrace's sake.
-          (prog1 (call-interactively cmd record-flag keys)
+          (prog1
+              (let ((f (lambda () (call-interactively cmd record-flag keys))))
+                (cond ((or background-thread t)
+                       (funcall f))
+                      (t
+                       (thread-join
+                        (make-thread
+                         (lambda ()
+                           (let ((background-thread (current-thread)))
+                             (funcall f)))
+                         (format "command: %S" cmd))))))
             (when-let ((info
                         (and (symbolp cmd)
                              (not (get cmd 'command-execute-obsolete-warned))

reply via email to

[Prev in Thread] Current Thread [Next in Thread]