diff options
| author | Stefan Monnier | 2019-01-23 12:30:54 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2019-01-23 12:30:54 -0500 |
| commit | 42732e2f8d963f0ce97caf6172d146b0119f5e06 (patch) | |
| tree | 777db42bbe0dc3878fe0a9230fcd2aeb750f66b2 | |
| parent | b3dfcf3e9f217919903f3469323fcd1386a16893 (diff) | |
| download | emacs-42732e2f8d963f0ce97caf6172d146b0119f5e06.tar.gz emacs-42732e2f8d963f0ce97caf6172d146b0119f5e06.zip | |
Rework last commit to icomplete and minibuffer.el.
Rather than let minibuffer-force-complete set up cycling and then undoing it,
better tell it directly not to setup cycling. Also be a bit more careful
to remove the transient map.
Additionally to bug#34077 and bug#34116, this also relates to bug#25644.
* lisp/minibuffer.el (completion--flush-all-sorted-completions):
Also take down the transient cycling map if applicable.
(minibuffer-force-complete): New arg dont-cycle.
Set completion-cycling to the actual function that takes down the
transient map rather than just t.
(minibuffer-force-complete-and-exit):
* lisp/icomplete.el (icomplete-force-complete): Use new dont-cycle arg.
| -rw-r--r-- | lisp/icomplete.el | 13 | ||||
| -rw-r--r-- | lisp/minibuffer.el | 92 |
2 files changed, 50 insertions, 55 deletions
diff --git a/lisp/icomplete.el b/lisp/icomplete.el index 128fe6688bf..10fd3a698c5 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el | |||
| @@ -165,17 +165,8 @@ the default otherwise." | |||
| 165 | (defun icomplete-force-complete () | 165 | (defun icomplete-force-complete () |
| 166 | "Complete the icomplete minibuffer." | 166 | "Complete the icomplete minibuffer." |
| 167 | (interactive) | 167 | (interactive) |
| 168 | (let ((retval (minibuffer-force-complete))) | 168 | ;; We're not at all interested in cycling here (bug#34077). |
| 169 | ;; FIXME: What's this, you ask? To deal with a cycling corner | 169 | (minibuffer-force-complete nil nil 'dont-cycle)) |
| 170 | ;; case, `minibuffer-force-complete' will transiently replace the | ||
| 171 | ;; keybinding that this command was called with, but at least | ||
| 172 | ;; returns a function which we can call to disable that, since | ||
| 173 | ;; we're not at all interested in cycling here (bug#34077). | ||
| 174 | (when (and completion-cycling (functionp retval)) (funcall retval))) | ||
| 175 | ;; Again, since we're not interested in cycling, we don't want | ||
| 176 | ;; prospects to be recalculted from a cache of rotated completions. | ||
| 177 | (setq completion-cycling nil) | ||
| 178 | (setq completion-all-sorted-completions nil)) | ||
| 179 | 170 | ||
| 180 | (defun icomplete-forward-completions () | 171 | (defun icomplete-forward-completions () |
| 181 | "Step forward completions by one entry. | 172 | "Step forward completions by one entry. |
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 99cb66926bb..c8b84b0e947 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el | |||
| @@ -676,9 +676,9 @@ for use at QPOS." | |||
| 676 | ;; (defmacro complete-in-turn (a b) `(completion-table-in-turn ,a ,b)) | 676 | ;; (defmacro complete-in-turn (a b) `(completion-table-in-turn ,a ,b)) |
| 677 | ;; (defmacro dynamic-completion-table (fun) `(completion-table-dynamic ,fun)) | 677 | ;; (defmacro dynamic-completion-table (fun) `(completion-table-dynamic ,fun)) |
| 678 | (define-obsolete-function-alias | 678 | (define-obsolete-function-alias |
| 679 | 'complete-in-turn 'completion-table-in-turn "23.1") | 679 | 'complete-in-turn #'completion-table-in-turn "23.1") |
| 680 | (define-obsolete-function-alias | 680 | (define-obsolete-function-alias |
| 681 | 'dynamic-completion-table 'completion-table-dynamic "23.1") | 681 | 'dynamic-completion-table #'completion-table-dynamic "23.1") |
| 682 | 682 | ||
| 683 | ;;; Minibuffer completion | 683 | ;;; Minibuffer completion |
| 684 | 684 | ||
| @@ -696,7 +696,7 @@ If ARGS are provided, then pass MESSAGE through `format-message'." | |||
| 696 | (if (not (minibufferp (current-buffer))) | 696 | (if (not (minibufferp (current-buffer))) |
| 697 | (progn | 697 | (progn |
| 698 | (if args | 698 | (if args |
| 699 | (apply 'message message args) | 699 | (apply #'message message args) |
| 700 | (message "%s" message)) | 700 | (message "%s" message)) |
| 701 | (prog1 (sit-for (or minibuffer-message-timeout 1000000)) | 701 | (prog1 (sit-for (or minibuffer-message-timeout 1000000)) |
| 702 | (message nil))) | 702 | (message nil))) |
| @@ -1003,7 +1003,7 @@ completion candidates than this number." | |||
| 1003 | 1003 | ||
| 1004 | (defvar-local completion-all-sorted-completions nil) | 1004 | (defvar-local completion-all-sorted-completions nil) |
| 1005 | (defvar-local completion--all-sorted-completions-location nil) | 1005 | (defvar-local completion--all-sorted-completions-location nil) |
| 1006 | (defvar completion-cycling nil) | 1006 | (defvar completion-cycling nil) ;Function that takes down the cycling map. |
| 1007 | 1007 | ||
| 1008 | (defvar completion-fail-discreetly nil | 1008 | (defvar completion-fail-discreetly nil |
| 1009 | "If non-nil, stay quiet when there is no match.") | 1009 | "If non-nil, stay quiet when there is no match.") |
| @@ -1035,7 +1035,7 @@ when the buffer's text is already an exact match." | |||
| 1035 | (let* ((string (buffer-substring beg end)) | 1035 | (let* ((string (buffer-substring beg end)) |
| 1036 | (md (completion--field-metadata beg)) | 1036 | (md (completion--field-metadata beg)) |
| 1037 | (comp (funcall (or try-completion-function | 1037 | (comp (funcall (or try-completion-function |
| 1038 | 'completion-try-completion) | 1038 | #'completion-try-completion) |
| 1039 | string | 1039 | string |
| 1040 | minibuffer-completion-table | 1040 | minibuffer-completion-table |
| 1041 | minibuffer-completion-predicate | 1041 | minibuffer-completion-predicate |
| @@ -1188,7 +1188,7 @@ scroll the window of possible completions." | |||
| 1188 | 1188 | ||
| 1189 | (defun completion--cache-all-sorted-completions (beg end comps) | 1189 | (defun completion--cache-all-sorted-completions (beg end comps) |
| 1190 | (add-hook 'after-change-functions | 1190 | (add-hook 'after-change-functions |
| 1191 | 'completion--flush-all-sorted-completions nil t) | 1191 | #'completion--flush-all-sorted-completions nil t) |
| 1192 | (setq completion--all-sorted-completions-location | 1192 | (setq completion--all-sorted-completions-location |
| 1193 | (cons (copy-marker beg) (copy-marker end))) | 1193 | (cons (copy-marker beg) (copy-marker end))) |
| 1194 | (setq completion-all-sorted-completions comps)) | 1194 | (setq completion-all-sorted-completions comps)) |
| @@ -1198,8 +1198,10 @@ scroll the window of possible completions." | |||
| 1198 | (or (> start (cdr completion--all-sorted-completions-location)) | 1198 | (or (> start (cdr completion--all-sorted-completions-location)) |
| 1199 | (< end (car completion--all-sorted-completions-location)))) | 1199 | (< end (car completion--all-sorted-completions-location)))) |
| 1200 | (remove-hook 'after-change-functions | 1200 | (remove-hook 'after-change-functions |
| 1201 | 'completion--flush-all-sorted-completions t) | 1201 | #'completion--flush-all-sorted-completions t) |
| 1202 | (setq completion-cycling nil) | 1202 | ;; Remove the transient map if applicable. |
| 1203 | (when completion-cycling | ||
| 1204 | (funcall (prog1 completion-cycling (setq completion-cycling nil)))) | ||
| 1203 | (setq completion-all-sorted-completions nil))) | 1205 | (setq completion-all-sorted-completions nil))) |
| 1204 | 1206 | ||
| 1205 | (defun completion--metadata (string base md-at-point table pred) | 1207 | (defun completion--metadata (string base md-at-point table pred) |
| @@ -1263,16 +1265,17 @@ scroll the window of possible completions." | |||
| 1263 | ;; unnecessary call would mess up the final result value | 1265 | ;; unnecessary call would mess up the final result value |
| 1264 | ;; (bug#34116). | 1266 | ;; (bug#34116). |
| 1265 | (unless completion-cycling | 1267 | (unless completion-cycling |
| 1266 | (minibuffer-force-complete)) | 1268 | (minibuffer-force-complete nil nil 'dont-cycle)) |
| 1267 | (completion--complete-and-exit | 1269 | (completion--complete-and-exit |
| 1268 | (minibuffer-prompt-end) (point-max) #'exit-minibuffer | 1270 | (minibuffer-prompt-end) (point-max) #'exit-minibuffer |
| 1269 | ;; If the previous completion completed to an element which fails | 1271 | ;; If the previous completion completed to an element which fails |
| 1270 | ;; test-completion, then we shouldn't exit, but that should be rare. | 1272 | ;; test-completion, then we shouldn't exit, but that should be rare. |
| 1271 | (lambda () (minibuffer-message "Incomplete")))) | 1273 | (lambda () (minibuffer-message "Incomplete")))) |
| 1272 | 1274 | ||
| 1273 | (defun minibuffer-force-complete (&optional start end) | 1275 | (defun minibuffer-force-complete (&optional start end dont-cycle) |
| 1274 | "Complete the minibuffer to an exact match. | 1276 | "Complete the minibuffer to an exact match. |
| 1275 | Repeated uses step through the possible completions." | 1277 | Repeated uses step through the possible completions. |
| 1278 | DONT-CYCLE tells the function not to setup cycling." | ||
| 1276 | (interactive) | 1279 | (interactive) |
| 1277 | (setq minibuffer-scroll-window nil) | 1280 | (setq minibuffer-scroll-window nil) |
| 1278 | ;; FIXME: Need to deal with the extra-size issue here as well. | 1281 | ;; FIXME: Need to deal with the extra-size issue here as well. |
| @@ -1285,7 +1288,7 @@ Repeated uses step through the possible completions." | |||
| 1285 | (base (+ start (or (cdr (last all)) 0)))) | 1288 | (base (+ start (or (cdr (last all)) 0)))) |
| 1286 | (cond | 1289 | (cond |
| 1287 | ((not (consp all)) | 1290 | ((not (consp all)) |
| 1288 | (completion--message | 1291 | (completion--message |
| 1289 | (if all "No more completions" "No completions"))) | 1292 | (if all "No more completions" "No completions"))) |
| 1290 | ((not (consp (cdr all))) | 1293 | ((not (consp (cdr all))) |
| 1291 | (let ((done (equal (car all) (buffer-substring-no-properties base end)))) | 1294 | (let ((done (equal (car all) (buffer-substring-no-properties base end)))) |
| @@ -1296,33 +1299,34 @@ Repeated uses step through the possible completions." | |||
| 1296 | (completion--replace base end (car all)) | 1299 | (completion--replace base end (car all)) |
| 1297 | (setq end (+ base (length (car all)))) | 1300 | (setq end (+ base (length (car all)))) |
| 1298 | (completion--done (buffer-substring-no-properties start (point)) 'sole) | 1301 | (completion--done (buffer-substring-no-properties start (point)) 'sole) |
| 1299 | ;; Set cycling after modifying the buffer since the flush hook resets it. | ||
| 1300 | (setq completion-cycling t) | ||
| 1301 | (setq this-command 'completion-at-point) ;For completion-in-region. | 1302 | (setq this-command 'completion-at-point) ;For completion-in-region. |
| 1302 | ;; If completing file names, (car all) may be a directory, so we'd now | 1303 | ;; Set cycling after modifying the buffer since the flush hook resets it. |
| 1303 | ;; have a new set of possible completions and might want to reset | 1304 | (unless dont-cycle |
| 1304 | ;; completion-all-sorted-completions to nil, but we prefer not to, | 1305 | ;; If completing file names, (car all) may be a directory, so we'd now |
| 1305 | ;; so that repeated calls minibuffer-force-complete still cycle | 1306 | ;; have a new set of possible completions and might want to reset |
| 1306 | ;; through the previous possible completions. | 1307 | ;; completion-all-sorted-completions to nil, but we prefer not to, |
| 1307 | (let ((last (last all))) | 1308 | ;; so that repeated calls minibuffer-force-complete still cycle |
| 1308 | (setcdr last (cons (car all) (cdr last))) | 1309 | ;; through the previous possible completions. |
| 1309 | (completion--cache-all-sorted-completions start end (cdr all))) | 1310 | (let ((last (last all))) |
| 1310 | ;; Make sure repeated uses cycle, even though completion--done might | 1311 | (setcdr last (cons (car all) (cdr last))) |
| 1311 | ;; have added a space or something that moved us outside of the field. | 1312 | (completion--cache-all-sorted-completions start end (cdr all))) |
| 1312 | ;; (bug#12221). | 1313 | ;; Make sure repeated uses cycle, even though completion--done might |
| 1313 | (let* ((table minibuffer-completion-table) | 1314 | ;; have added a space or something that moved us outside of the field. |
| 1314 | (pred minibuffer-completion-predicate) | 1315 | ;; (bug#12221). |
| 1315 | (extra-prop completion-extra-properties) | 1316 | (let* ((table minibuffer-completion-table) |
| 1316 | (cmd | 1317 | (pred minibuffer-completion-predicate) |
| 1317 | (lambda () "Cycle through the possible completions." | 1318 | (extra-prop completion-extra-properties) |
| 1318 | (interactive) | 1319 | (cmd |
| 1319 | (let ((completion-extra-properties extra-prop)) | 1320 | (lambda () "Cycle through the possible completions." |
| 1320 | (completion-in-region start (point) table pred))))) | 1321 | (interactive) |
| 1321 | (set-transient-map | 1322 | (let ((completion-extra-properties extra-prop)) |
| 1322 | (let ((map (make-sparse-keymap))) | 1323 | (completion-in-region start (point) table pred))))) |
| 1323 | (define-key map [remap completion-at-point] cmd) | 1324 | (setq completion-cycling |
| 1324 | (define-key map (vector last-command-event) cmd) | 1325 | (set-transient-map |
| 1325 | map))))))) | 1326 | (let ((map (make-sparse-keymap))) |
| 1327 | (define-key map [remap completion-at-point] cmd) | ||
| 1328 | (define-key map (vector last-command-event) cmd) | ||
| 1329 | map))))))))) | ||
| 1326 | 1330 | ||
| 1327 | (defvar minibuffer-confirm-exit-commands | 1331 | (defvar minibuffer-confirm-exit-commands |
| 1328 | '(completion-at-point minibuffer-complete | 1332 | '(completion-at-point minibuffer-complete |
| @@ -1540,7 +1544,7 @@ horizontally in alphabetical order, rather than down the screen." | |||
| 1540 | Uses columns to keep the listing readable but compact. | 1544 | Uses columns to keep the listing readable but compact. |
| 1541 | It also eliminates runs of equal strings." | 1545 | It also eliminates runs of equal strings." |
| 1542 | (when (consp strings) | 1546 | (when (consp strings) |
| 1543 | (let* ((length (apply 'max | 1547 | (let* ((length (apply #'max |
| 1544 | (mapcar (lambda (s) | 1548 | (mapcar (lambda (s) |
| 1545 | (if (consp s) | 1549 | (if (consp s) |
| 1546 | (+ (string-width (car s)) | 1550 | (+ (string-width (car s)) |
| @@ -2329,7 +2333,7 @@ same as `substitute-in-file-name'." | |||
| 2329 | (match-beginning 0))))))) | 2333 | (match-beginning 0))))))) |
| 2330 | (t | 2334 | (t |
| 2331 | (if (eq (aref string (1- beg)) ?{) | 2335 | (if (eq (aref string (1- beg)) ?{) |
| 2332 | (setq table (apply-partially 'completion-table-with-terminator | 2336 | (setq table (apply-partially #'completion-table-with-terminator |
| 2333 | "}" table))) | 2337 | "}" table))) |
| 2334 | ;; Even if file-name completion is case-insensitive, we want | 2338 | ;; Even if file-name completion is case-insensitive, we want |
| 2335 | ;; envvar completion to be case-sensitive. | 2339 | ;; envvar completion to be case-sensitive. |
| @@ -2463,7 +2467,7 @@ except that it passes the file name through `substitute-in-file-name'.") | |||
| 2463 | #'completion--file-name-table) | 2467 | #'completion--file-name-table) |
| 2464 | "Internal subroutine for `read-file-name'. Do not call this.") | 2468 | "Internal subroutine for `read-file-name'. Do not call this.") |
| 2465 | 2469 | ||
| 2466 | (defvar read-file-name-function 'read-file-name-default | 2470 | (defvar read-file-name-function #'read-file-name-default |
| 2467 | "The function called by `read-file-name' to do its work. | 2471 | "The function called by `read-file-name' to do its work. |
| 2468 | It should accept the same arguments as `read-file-name'.") | 2472 | It should accept the same arguments as `read-file-name'.") |
| 2469 | 2473 | ||
| @@ -2738,8 +2742,8 @@ See `read-file-name' for the meaning of the arguments." | |||
| 2738 | BUFFER nil or omitted means use the current buffer. | 2742 | BUFFER nil or omitted means use the current buffer. |
| 2739 | Like `internal-complete-buffer', but removes BUFFER from the completion list." | 2743 | Like `internal-complete-buffer', but removes BUFFER from the completion list." |
| 2740 | (let ((except (if (stringp buffer) buffer (buffer-name buffer)))) | 2744 | (let ((except (if (stringp buffer) buffer (buffer-name buffer)))) |
| 2741 | (apply-partially 'completion-table-with-predicate | 2745 | (apply-partially #'completion-table-with-predicate |
| 2742 | 'internal-complete-buffer | 2746 | #'internal-complete-buffer |
| 2743 | (lambda (name) | 2747 | (lambda (name) |
| 2744 | (not (equal (if (consp name) (car name) name) except))) | 2748 | (not (equal (if (consp name) (car name) name) except))) |
| 2745 | nil))) | 2749 | nil))) |
| @@ -3409,7 +3413,7 @@ the same set of elements." | |||
| 3409 | (when newstr | 3413 | (when newstr |
| 3410 | (completion-pcm-try-completion newstr table pred (length newstr))))) | 3414 | (completion-pcm-try-completion newstr table pred (length newstr))))) |
| 3411 | 3415 | ||
| 3412 | (defvar completing-read-function 'completing-read-default | 3416 | (defvar completing-read-function #'completing-read-default |
| 3413 | "The function called by `completing-read' to do its work. | 3417 | "The function called by `completing-read' to do its work. |
| 3414 | It should accept the same arguments as `completing-read'.") | 3418 | It should accept the same arguments as `completing-read'.") |
| 3415 | 3419 | ||