\\<global-map>To visit a file without any kind of conversion and without
automatically choosing a major mode, use \\[find-file-literally]."
(interactive
- (minibuffer-with-setup-hook
- (lambda ()
- (setq-local minibuffer-completion-action
- (cons (lambda (file)
- (display-buffer (find-file-noselect file)))
- "find")))
- (find-file-read-args "Find file: "
- (confirm-nonexistent-file-or-buffer))))
+ (find-file-read-args "Find file: "
+ (confirm-nonexistent-file-or-buffer)))
(let ((value (find-file-noselect filename nil nil wildcards)))
(if (listp value)
(mapcar 'pop-to-buffer-same-window (nreverse value))
(pop-to-buffer-same-window value))))
+(put 'find-file 'minibuffer-action
+ (cons (lambda (file) (display-buffer (find-file-noselect file)))
+ "find"))
+
(defun find-file-other-window (filename &optional wildcards)
"Edit file FILENAME, in another window.
value)
(switch-to-buffer-other-window value))))
+(put 'find-file-other-window 'minibuffer-action 'find-file)
+
(defun find-file-other-frame (filename &optional wildcards)
"Edit file FILENAME, in another frame.
(find-file filename)
(current-buffer)))
+(put 'find-file-existing 'minibuffer-action 'find-file)
+
(defun find-file--read-only (fun filename wildcards)
(unless (or (and wildcards find-file-wildcards
(not (file-name-quoted-p filename))
;; We already ran these; don't run them again.
(let (kill-buffer-query-functions kill-buffer-hook)
(kill-buffer obuf))))))
+
+(put 'find-alternate-file 'minibuffer-action 'find-file)
+
\f
;; FIXME we really need to fold the uniquify stuff in here by default,
(defun create-file-buffer (filename)
((and delete-by-moving-to-trash trash) (move-file-to-trash filename))
(t (delete-file-internal filename)))))
+(put 'delete-file 'minibuffer-action "delete")
+
(defun delete-directory (directory &optional recursive trash)
"Delete the directory named DIRECTORY. Does not follow symlinks.
If RECURSIVE is non-nil, delete files in DIRECTORY as well, with
(princ string)))))
nil)
+(put 'where-is 'minibuffer-action
+ (cons (lambda (cmd) (where-is (intern cmd)))
+ "show keys"))
+
(defun help-key-description (key untranslated)
(let ((string (help--key-description-fontified key)))
(if (or (not untranslated)
"C-x C-v" #'minibuffer-sort-completions
"C-x n" 'minibuffer-narrow-completions-map
"C-x /" #'minibuffer-set-completion-styles
- "C-j" #'minibuffer-apply)
+ "C-j" #'minibuffer-apply
+ "C-p" #'minibuffer-previous-line-or-completion
+ "C-n" #'minibuffer-next-line-or-completion
+ "C-%" #'minibuffer-query-apply)
(defvar-keymap minibuffer-local-must-match-map
:doc "Local keymap for minibuffer input with completion, for exact match."
(interactive (let* ((input-prefix (minibuffer-current-input))
(input (car input-prefix))
(prefix (cdr input-prefix)))
- (list input prefix)))
+ (list input prefix))
+ minibuffer-mode)
(funcall
(or (car (minibuffer-completion-action))
(user-error "No applicable action"))
(add-face-text-property (prop-match-beginning pm) (point)
'completions-used-input)))))))
+(defun minibuffer-query-apply ()
+ "Suggest applying the minibuffer action to each completion candidate in turn."
+ (interactive nil minibuffer-mode)
+ (with-minibuffer-completions-window
+ (let ((prev (point))
+ all done)
+ (goto-char (point-min))
+ (when (get-text-property (point) 'first-completion)
+ (let ((inhibit-read-only t))
+ (remove-text-properties (point) (1+ (point)) '(first-completion))))
+ (while (not done)
+ (setq prev (point))
+ (with-current-buffer completion-reference-buffer
+ (minibuffer-next-completion))
+ (if (<= prev (point))
+ (pcase
+ (or all (car (read-multiple-choice
+ (format "Apply \"%s\" to input?"
+ (propertize (cdr completions-action)
+ 'face 'bold))
+ '((?y "yes" "Apply")
+ (?n "no" "Skip")
+ (?q "quit" "Quit")
+ (?! "all" "Apply to all")))))
+ (?y ; Apply.
+ (with-current-buffer completion-reference-buffer
+ (call-interactively #'minibuffer-apply)))
+ (?n) ; Skip.
+ (?q (setq done t)) ; Quit.
+ (?! (setq all ?y))) ; Apply to all.
+ ;; We're back at the first candidate, stop.
+ (setq done t)
+ (message "Done"))))))
+
;;; Old-style completion, used in Emacs-21 and Emacs-22.
(defun completion-emacs21-try-completion (string table pred _point)
(interactive "p")
(minibuffer-next-completion (- (or n 1)) t))
+(defun minibuffer-next-line-or-completion (&optional arg)
+ "Move cursor down ARG lines, or to the next completion candidate."
+ (interactive "^p")
+ (or arg (setq arg 1))
+ (minibuffer-next-line-or-call #'minibuffer-next-completion arg))
+
+(defun minibuffer-previous-line-or-completion (&optional arg)
+ "Move cursor up ARG lines, or to the previous completion candidate."
+ (interactive "^p")
+ (or arg (setq arg 1))
+ (minibuffer-previous-line-or-call #'minibuffer-previous-completion arg))
+
(defun minibuffer-choose-completion (&optional no-exit no-quit)
"Run `choose-completion' from the minibuffer in its completions window.
With prefix argument NO-EXIT, insert the completion candidate at point to
'face 'help-key-binding)))
(defun execute-extended-command (prefixarg &optional command-name typed)
- "Read a command name, then read the arguments and call the command.
-To pass a prefix argument to the command you are
-invoking, give a prefix argument to `execute-extended-command'.
+ "Read COMMAND-NAME and call that command interactively.
+To pass a prefix argument PREFIXARG to the command you are invoking,
+give a prefix argument to `execute-extended-command'.
This command provides completion when reading the command name.
Which completion candidates are shown can be controlled by
(list current-prefix-arg
(read-extended-command)
execute-extended-command--last-typed)))
- ;; Emacs<24 calling-convention was with a single `prefixarg' argument.
- (unless command-name
- (let ((current-prefix-arg prefixarg) ; for prompt
- (execute-extended-command--last-typed nil))
- (setq command-name (read-extended-command))
- (setq typed execute-extended-command--last-typed)))
(let* ((function (and (stringp command-name) (intern-soft command-name)))
(binding (and suggest-key-bindings
(not executing-kbd-macro)
suggest-key-bindings
2))))))))))))
+(put 'execute-extended-command 'minibuffer-action
+ (cons (lambda (cmd)
+ ;; TODO: Improve error handling.
+ (with-minibuffer-selected-window
+ (call-interactively (intern cmd))))
+ "execute"))
+
(defun execute-extended-command-for-buffer (prefixarg &optional
command-name typed)
"Query user for a command relevant for the current mode, and then execute it.
(or (zerop n)
(goto-history-element (+ minibuffer-history-position n))))
-(defun next-line-or-history-element (&optional arg)
- "Move cursor vertically down ARG lines, or to the next history element.
-When point moves over the bottom line of multi-line minibuffer, puts ARGth
-next element of the minibuffer history in the minibuffer."
+(defun minibuffer-next-line-or-call (fun arg)
+ "Move cursor vertically down ARG lines, or call function FUN."
(interactive "^p")
(or arg (setq arg 1))
(let* ((old-point (point))
;; Restore old position since `line-move-visual' moves point to
;; the end of the line when it fails to go to the next line.
(goto-char old-point)
- (next-history-element arg)
+ (funcall fun arg)
;; Reset `temporary-goal-column' because a correct value is not
;; calculated when `next-line' above fails by bumping against
;; the bottom of the minibuffer (bug#22544).
(current-column))))
(move-to-column old-column)))))))
-(defun previous-line-or-history-element (&optional arg)
- "Move cursor vertically up ARG lines, or to the previous history element.
-When point moves over the top line of multi-line minibuffer, puts ARGth
-previous element of the minibuffer history in the minibuffer."
+(defun next-line-or-history-element (&optional arg)
+ "Move cursor vertically down ARG lines, or to the next history element.
+When point moves over the bottom line of multi-line minibuffer, puts ARGth
+next element of the minibuffer history in the minibuffer."
+ (interactive "^p")
+ (or arg (setq arg 1))
+ (minibuffer-next-line-or-call #'next-history-element arg))
+
+(defun minibuffer-previous-line-or-call (fun arg)
+ "Move cursor vertically up ARG lines, or call function FUN."
(interactive "^p")
(or arg (setq arg 1))
(let* ((old-point (point))
;; Restore old position since `line-move-visual' moves point to
;; the beginning of the line when it fails to go to the previous line.
(goto-char old-point)
- (previous-history-element arg)
+ (funcall fun arg)
;; Reset `temporary-goal-column' because a correct value is not
;; calculated when `previous-line' above fails by bumping against
;; the top of the minibuffer (bug#22544).
;; of the first visual line (bug#22544).
(unless (eolp) (backward-char 1))))))))
+(defun previous-line-or-history-element (&optional arg)
+ "Move cursor vertically up ARG lines, or to the previous history element.
+When point moves over the top line of multi-line minibuffer, puts ARGth
+previous element of the minibuffer history in the minibuffer."
+ (interactive "^p")
+ (or arg (setq arg 1))
+ (minibuffer-previous-line-or-call #'previous-history-element arg))
+
(defun next-complete-history-element (n)
"Get next history element that completes the minibuffer before the point.
The contents of the minibuffer after the point are deleted and replaced
(completing-read
prompt
(completion-table-with-metadata
- completions '((display-sort-function . identity)))
+ completions '((sort-function . identity)))
nil nil nil
(if history-pos
(cons 'read-from-kill-ring-history
(fn-alist (mapcar
(lambda (x) (cons (with-output-to-string (prin1 x)) x))
(if local (symbol-value hook) (default-value hook))))
+ ;; TODO: Add minibuffer action.
(function (alist-get (completing-read
(format "%s hook to remove: "
(if local "Buffer-local" "Global"))
(message "No library %s in search path" library)))
file))
+(put 'locate-library 'minibuffer-action
+ (cons (lambda (lib) (locate-library lib nil nil t))
+ "locate"))
\f
;;;; Process stuff.