feature by customizing @code{find-file-wildcards}.
@cindex visiting files asynchronously
-@vindex find-file-asynchronously
+@vindex execute-file-commands-asynchronously
Sometimes, it is handy to visit a file asynchronously. This means,
while loading the file into its buffer Emacs keeps responsive, and you
can continue to edit other files, or call commands. This is
-controlled by the user option @code{find-file-asynchronously}. If
-this option is @code{nil} (the default), visiting a file is performed
-synchronously. A regexp value let files, which name matches the
-regexp, being visited asynchronously, and synchronously otherwise.
+controlled by the user option @code{execute-file-commands-asynchronously}.
+If this option is @code{nil} (the default), visiting a file is
+performed synchronously. A regexp value let files, which name matches
+the regexp, being visited asynchronously, and synchronously otherwise.
The value @code{t} forces asynchronous visiting of files
unconditionally.
@example
@group
(customize-set-variable
- 'find-file-asynchronously tramp-file-name-regexp
+ 'execute-file-commands-asynchronously tramp-file-name-regexp
"Visit remote files asynchronously")
@end group
@end example
- With a prefix argument @kbd{C-u}, the meaning of
-@code{find-file-asynchronously} will be reverted. If this user option
-is @code{nil}, visiting a file is performed asynchronously. Contrary,
-if this user option is non-@code{nil}, visiting a file is performed
-synchronously.
+ With the key sequence @kbd{C-x &} prior the file visiting command,
+the meaning of @code{execute-file-commands-asynchronously} will be
+reverted. If this user option is @code{nil}, visiting a file is
+performed asynchronously. Contrary, if this user option is
+non-@code{nil}, visiting a file is performed synchronously.
@kindex C-x C-v
@findex find-alternate-file
,@body)
(remove-hook 'minibuffer-setup-hook ,hook)))))
+(defun universal-async-argument (async)
+ "Execute an interactive command using the ASYNC argument.
+For file visiting and saving commands, this toggles the meaning
+of `execute-file-commands-asynchronously'."
+ (interactive
+ (list (and (featurep 'threads) (not execute-file-commands-asynchronously))))
+ (let* ((execute-file-commands-asynchronously async)
+ (keyseq (read-key-sequence nil))
+ (cmd (key-binding keyseq))
+ prefix)
+ ;; `read-key-sequence' ignores quit, so make an explicit check.
+ (if (equal last-input-event (nth 3 (current-input-mode)))
+ (keyboard-quit))
+ (when (memq cmd '(universal-argument digit-argument))
+ (call-interactively cmd)
+
+ ;; Process keys bound in `universal-argument-map'.
+ (while (progn
+ (setq keyseq (read-key-sequence nil t)
+ cmd (key-binding keyseq t))
+ (not (eq cmd 'universal-argument-other-key)))
+ (let ((current-prefix-arg prefix-arg)
+ ;; Have to bind `last-command-event' here so that
+ ;; `digit-argument', for instance, can compute the
+ ;; `prefix-arg'.
+ (last-command-event (aref keyseq 0)))
+ (call-interactively cmd)))
+
+ ;; This is the final call to `universal-argument-other-key', which
+ ;; sets the final `prefix-arg'.
+ (let ((current-prefix-arg prefix-arg))
+ (call-interactively cmd))
+
+ ;; Read the command to execute with the given `prefix-arg'.
+ (setq prefix prefix-arg
+ keyseq (read-key-sequence nil t)
+ cmd (key-binding keyseq)))
+
+ (let ((current-prefix-arg prefix))
+ (message "")
+ (call-interactively cmd))))
+
+(define-key ctl-x-map "&" 'universal-async-argument)
+
(defun find-file-read-args (prompt mustmatch &optional wildcards)
"Return the interactive spec (<filename> <async>).
If WILDCARDS is non-nil, return the spec (<filename> t <async>)."
(let ((filename (read-file-name prompt nil default-directory mustmatch))
- (async (and (xor find-file-asynchronously current-prefix-arg)
- (featurep 'threads))))
- (when (and async (stringp find-file-asynchronously))
- (setq async (string-match-p find-file-asynchronously filename)))
+ (async (and (featurep 'threads) execute-file-commands-asynchronously)))
+ (when (stringp async) (setq async (string-match-p async filename)))
(if wildcards `(,filename t ,async) `(,filename ,async))))
(defmacro find-file-with-threads (filename async &rest body)
suppress wildcard expansion by setting `find-file-wildcards' to nil.
If ASYNC is non-nil, the file will be loaded into the buffer
-asynchronously. Interactively, this is indicated by either
-setting `find-file-asynchronously' to non-nil, or by a prefix
-argument.
+asynchronously. Interactively, this is indicated by setting
+`execute-file-commands-asynchronously' to a proper non-nil value.
+This behavior can be toggled by the key sequence \\[universal-async-argument]
+prior the command invocation.
To visit a file without any kind of conversion and without
automatically choosing a major mode, use \\[find-file-literally]."
expand wildcards (if any) and visit multiple files.
If ASYNC is non-nil, the file will be loaded into the buffer
-asynchronously. Interactively, this is indicated by either
-setting `find-file-asynchronously' to non-nil, or by a prefix
-argument."
+asynchronously. Interactively, this is indicated by setting
+`execute-file-commands-asynchronously' to a proper non-nil value.
+This behavior can be toggled by the key sequence \\[universal-async-argument]
+prior the command invocation."
(interactive
(find-file-read-args "Find file in other window: "
(confirm-nonexistent-file-or-buffer) t))
expand wildcards (if any) and visit multiple files.
If ASYNC is non-nil, the file will be loaded into the buffer
-asynchronously. Interactively, this is indicated by either
-setting `find-file-asynchronously' to non-nil, or by a prefix
-argument."
+asynchronously. Interactively, this is indicated by setting
+`execute-file-commands-asynchronously' to a proper non-nil value.
+This behavior can be toggled by the key sequence \\[universal-async-argument]
+prior the command invocation."
(interactive
(find-file-read-args "Find file in other frame: "
(confirm-nonexistent-file-or-buffer) t))
file names with wildcards.
If ASYNC is non-nil, the file will be loaded into the buffer
-asynchronously. Interactively, this is indicated by either
-setting `find-file-asynchronously' to non-nil, or by a prefix
-argument."
+asynchronously. Interactively, this is indicated by setting
+`execute-file-commands-asynchronously' to a proper non-nil value.
+This behavior can be toggled by the key sequence \\[universal-async-argument]
+prior the command invocation."
(interactive
(find-file-read-args "Find existing file: " t))
(if (and (not (called-interactively-p 'interactive))
expand wildcards (if any) and replace the file with multiple files.
If ASYNC is non-nil, the file will be loaded into the buffer
-asynchronously. Interactively, this is indicated by either
-setting `find-file-asynchronously' to non-nil, or by a prefix
-argument."
+asynchronously. Interactively, this is indicated by setting
+`execute-file-commands-asynchronously' to a proper non-nil value.
+This behavior can be toggled by the key sequence \\[universal-async-argument]
+prior the command invocation."
(interactive
(save-selected-window
(other-window 1)
(list (read-file-name
"Find alternate file: " file-dir nil
(confirm-nonexistent-file-or-buffer) file-name)
- t (and (xor find-file-asynchronously current-prefix-arg)
- (featurep 'threads))))))
+ t
+ (and (featurep 'threads) execute-file-commands-asynchronously)))))
+ (when (stringp async) (setq async (string-match-p async filename)))
(if (one-window-p)
(find-file-other-window filename wildcards async)
(save-selected-window
expand wildcards (if any) and replace the file with multiple files.
If ASYNC is non-nil, the file will be loaded into the buffer
-asynchronously. Interactively, this is indicated by either
-setting `find-file-asynchronously' to non-nil, or by a prefix
-argument.
+asynchronously. Interactively, this is indicated by setting
+`execute-file-commands-asynchronously' to a proper non-nil value.
+This behavior can be toggled by the key sequence \\[universal-async-argument]
+prior the command invocation.
If the current buffer is an indirect buffer, or the base buffer
for one or more indirect buffers, the other buffer(s) are not
(list (read-file-name
"Find alternate file: " file-dir nil
(confirm-nonexistent-file-or-buffer) file-name)
- t (and (xor find-file-asynchronously current-prefix-arg)
- (featurep 'threads)))))
+ t (and (featurep 'threads) execute-file-commands-asynchronously))))
+ (when (stringp async) (setq async (string-match-p async filename)))
(unless (run-hook-with-args-until-failure 'kill-buffer-query-functions)
(user-error "Aborted"))
(and (buffer-modified-p) buffer-file-name
:version "21.1"
:type 'boolean)
-(defcustom find-file-asynchronously nil
+(defcustom execute-file-commands-asynchronously nil
"Non-nil means visit file asynchronously when called interactively.
If it is a regular expression, it must match the file name to be
-visited. This behavior is toggled by a prefix argument to the
-interactive call."
- :group 'files
+visited. This behavior is toggled by the key sequence \\[universal-async-argument]
+prior the command invocation."
+:group 'files
:version "27.1"
:type '(choice boolean regexp))
this command asks you whether to visit it literally instead.
If ASYNC is non-nil, the file will be loaded into the buffer
-asynchronously. Interactively, this is indicated by either
-setting `find-file-asynchronously' to non-nil, or by a prefix
-argument.
+asynchronously. Interactively, this is indicated by setting
+`execute-file-commands-asynchronously' to a proper non-nil value.
+This behavior can be toggled by the key sequence \\[universal-async-argument]
+prior the command invocation.
In non-interactive use, the value is the buffer where the file is
visited literally. If the file was visited in a buffer before