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