From: Michael Albinus Date: Mon, 6 Aug 2018 10:26:43 +0000 (+0200) Subject: Generalize universal-async-argument X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=b823346b6581fe21abf671f9bdcb5346a8afd63f;p=emacs.git Generalize universal-async-argument * doc/lispref/files.texi (Visiting Functions): Mention universal-async-argument. Add @kindex and @findex. * etc/NEWS: Mention 'universal-async-argument'. * lisp/files.el (universal-async-argument): Move it to simple.el. (find-file-read-args, find-alternate-file-other-window) (find-alternate-file): Check for `universal-async-argument' variable. * lisp/simple.el (universal-async-argument): New variable. (universal-async-argument): Move function from files.el. Don't use an argument. Toggle `universal-async-argument' variable. --- diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 2bbef8d5984..dddc1b8cc60 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -119,7 +119,8 @@ interactive call, then @code{find-file} expands wildcard characters in If @var{async} is non-@code{nil}, the file will be loaded into the buffer asynchronously. Interactively, this is indicated by either setting user option @code{execute-file-commands-asynchronously} to -non-@code{nil}, or by the key sequence @kbd{C-x &} prior the command. +non-@code{nil}, or by the key sequence @kbd{C-x &} +(@code{universal-async-argument}) prior the command. When @code{find-file} is called interactively, it prompts for @var{filename} in the minibuffer. @@ -228,12 +229,15 @@ the @code{find-file} commands ignore their @var{wildcards} argument and never treat wildcard characters specially. @end defopt +@kindex C-x & +@findex universal-async-argument @defopt execute-file-commands-asynchronously If this variable is non-@code{nil}, a file will be visited asynchronously when called interactively. If it is a regular expression, it must match the file name to be visited. This behavior -is toggled by the key sequence @kbd{C-x &} prior to the interactive -call of the file visiting command. +is toggled by the key sequence @kbd{C-x &} +(@code{universal-async-argument}) prior to the interactive call of the +file visiting command. @end defopt @defopt find-file-hook diff --git a/etc/NEWS b/etc/NEWS index 36bee818517..c27c79bf336 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -997,6 +997,13 @@ where there's no better alternative. We believe that the incorrect uses of this function all but disappeared by now, so we are un-obsoleting it. +--- (Needs better documentation) +** There is a new command 'universal-async-argument', bound to 'C-x &'. +If this command precedes another command, the value of variable +'universal-async-argument' will be toggled. This indicates, that the +following command shall be executed asynchronously. For example, +file visiting commands would load files into buffers asynchronously. + * Changes in Emacs 27.1 on Non-Free Operating Systems diff --git a/lisp/files.el b/lisp/files.el index 0cb99d36165..6ac7e436aec 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -1576,55 +1576,13 @@ rather than FUN itself, to `minibuffer-setup-hook'." ,@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 ( ). If WILDCARDS is non-nil, return the spec ( t )." (let ((filename (read-file-name prompt nil default-directory mustmatch)) - (async (and (featurep 'threads) execute-file-commands-asynchronously))) + (async (and (featurep 'threads) + (xor universal-async-argument + execute-file-commands-asynchronously)))) (when (stringp async) (setq async (string-match-p async filename))) (if wildcards `(,filename t ,async) `(,filename ,async)))) @@ -1841,8 +1799,9 @@ prior the command invocation." (list (read-file-name "Find alternate file: " file-dir nil (confirm-nonexistent-file-or-buffer) file-name) - t - (and (featurep 'threads) execute-file-commands-asynchronously))))) + t (and (featurep 'threads) + (xor universal-async-argument + 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) @@ -1888,7 +1847,9 @@ killed." (list (read-file-name "Find alternate file: " file-dir nil (confirm-nonexistent-file-or-buffer) file-name) - t (and (featurep 'threads) execute-file-commands-asynchronously)))) + t (and (featurep 'threads) + (xor universal-async-argument + 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")) diff --git a/lisp/simple.el b/lisp/simple.el index 8d770478aa9..14153009d16 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -4214,6 +4214,52 @@ These commands include \\[set-mark-command] and \\[start-kbd-macro]." (t digit)))) (universal-argument--mode)) + +(defvar universal-async-argument nil + "Non-nil indicates a command to run asynchronously when called interactively. +The semantics depend on the command. This variable should not be +set globally, it should be used in let-bindings only.") + +(defun universal-async-argument () + "Execute an interactive command asynchronously." + (interactive) + (let* ((universal-async-argument (not universal-async-argument)) + (keyseq (read-key-sequence nil t)) + (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) (defvar filter-buffer-substring-functions nil