diff options
| author | Stefan Monnier | 2021-01-31 19:27:10 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2021-01-31 19:27:10 -0500 |
| commit | 82c76e3aeb2465d1d1e66eae5db13ba53e38ed84 (patch) | |
| tree | a9a59dd4dcd1a08b96c43192e0c3d3c2b419ad82 | |
| parent | 24b9515da0588aca38a1bce5f615e0cdf7891388 (diff) | |
| download | emacs-82c76e3aeb2465d1d1e66eae5db13ba53e38ed84.tar.gz emacs-82c76e3aeb2465d1d1e66eae5db13ba53e38ed84.zip | |
* lisp/eshell/em-cmpl.el: Try and fix bug#41423
(eshell--complete-commands-list): Rename from `eshell-complete-commands-list`.
Return a (dynamic) completion table rather than a list of completions.
Use `dolist` and `push`.
| -rw-r--r-- | lisp/eshell/em-cmpl.el | 118 |
1 files changed, 60 insertions, 58 deletions
diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el index 0200631da66..e0b3ab1ecf4 100644 --- a/lisp/eshell/em-cmpl.el +++ b/lisp/eshell/em-cmpl.el | |||
| @@ -211,7 +211,7 @@ to writing a completion function." | |||
| 211 | 211 | ||
| 212 | (defcustom eshell-command-completion-function | 212 | (defcustom eshell-command-completion-function |
| 213 | (lambda () | 213 | (lambda () |
| 214 | (pcomplete-here (eshell-complete-commands-list))) | 214 | (pcomplete-here (eshell--complete-commands-list))) |
| 215 | (eshell-cmpl--custom-variable-docstring 'pcomplete-command-completion-function) | 215 | (eshell-cmpl--custom-variable-docstring 'pcomplete-command-completion-function) |
| 216 | :type (get 'pcomplete-command-completion-function 'custom-type) | 216 | :type (get 'pcomplete-command-completion-function 'custom-type) |
| 217 | :group 'eshell-cmpl) | 217 | :group 'eshell-cmpl) |
| @@ -403,64 +403,66 @@ to writing a completion function." | |||
| 403 | args) | 403 | args) |
| 404 | posns))) | 404 | posns))) |
| 405 | 405 | ||
| 406 | (defun eshell-complete-commands-list () | 406 | (defun eshell--complete-commands-list () |
| 407 | "Generate list of applicable, visible commands." | 407 | "Generate list of applicable, visible commands." |
| 408 | (let ((filename (pcomplete-arg)) glob-name) | 408 | ;; Building the commands list can take quite a while, especially over Tramp |
| 409 | (if (file-name-directory filename) | 409 | ;; (bug#41423), so do it lazily. |
| 410 | (if eshell-force-execution | 410 | (completion-table-dynamic |
| 411 | (pcomplete-dirs-or-entries nil #'file-readable-p) | 411 | (lambda (filename) |
| 412 | (pcomplete-executables)) | 412 | (if (file-name-directory filename) |
| 413 | (if (and (> (length filename) 0) | 413 | (if eshell-force-execution |
| 414 | (eq (aref filename 0) eshell-explicit-command-char)) | 414 | (pcomplete-dirs-or-entries nil #'file-readable-p) |
| 415 | (setq filename (substring filename 1) | 415 | (pcomplete-executables)) |
| 416 | pcomplete-stub filename | 416 | (let (glob-name) |
| 417 | glob-name t)) | 417 | (if (and (> (length filename) 0) |
| 418 | (let* ((paths (eshell-get-path)) | 418 | (eq (aref filename 0) eshell-explicit-command-char)) |
| 419 | (cwd (file-name-as-directory | 419 | ;; FIXME: Shouldn't we handle this `*' outside of the |
| 420 | (expand-file-name default-directory))) | 420 | ;; `pcomplete-here' in `eshell-command-completion-function'? |
| 421 | (path "") (comps-in-path ()) | 421 | (setq filename (substring filename 1) |
| 422 | (file "") (filepath "") (completions ())) | 422 | pcomplete-stub filename |
| 423 | ;; Go thru each path in the search path, finding completions. | 423 | glob-name t)) |
| 424 | (while paths | 424 | (let* ((paths (eshell-get-path)) |
| 425 | (setq path (file-name-as-directory | 425 | (cwd (file-name-as-directory |
| 426 | (expand-file-name (or (car paths) "."))) | 426 | (expand-file-name default-directory))) |
| 427 | comps-in-path | 427 | (filepath "") (completions ())) |
| 428 | (and (file-accessible-directory-p path) | 428 | ;; Go thru each path in the search path, finding completions. |
| 429 | (file-name-all-completions filename path))) | 429 | (dolist (path paths) |
| 430 | ;; Go thru each completion found, to see whether it should | 430 | (setq path (file-name-as-directory |
| 431 | ;; be used. | 431 | (expand-file-name (or path ".")))) |
| 432 | (while comps-in-path | 432 | ;; Go thru each completion found, to see whether it should |
| 433 | (setq file (car comps-in-path) | 433 | ;; be used. |
| 434 | filepath (concat path file)) | 434 | (dolist (file (and (file-accessible-directory-p path) |
| 435 | (if (and (not (member file completions)) ; | 435 | (file-name-all-completions filename path))) |
| 436 | (or (string-equal path cwd) | 436 | (setq filepath (concat path file)) |
| 437 | (not (file-directory-p filepath))) | 437 | (if (and (not (member file completions)) ; |
| 438 | (if eshell-force-execution | 438 | (or (string-equal path cwd) |
| 439 | (file-readable-p filepath) | 439 | (not (file-directory-p filepath))) |
| 440 | (file-executable-p filepath))) | 440 | ;; FIXME: Those repeated file tests end up |
| 441 | (setq completions (cons file completions))) | 441 | ;; very costly over Tramp, we should cache the result. |
| 442 | (setq comps-in-path (cdr comps-in-path))) | 442 | (if eshell-force-execution |
| 443 | (setq paths (cdr paths))) | 443 | (file-readable-p filepath) |
| 444 | ;; Add aliases which are currently visible, and Lisp functions. | 444 | (file-executable-p filepath))) |
| 445 | (pcomplete-uniquify-list | 445 | (push file completions)))) |
| 446 | (if glob-name | 446 | ;; Add aliases which are currently visible, and Lisp functions. |
| 447 | completions | 447 | (pcomplete-uniquify-list |
| 448 | (setq completions | 448 | (if glob-name |
| 449 | (append (if (fboundp 'eshell-alias-completions) | 449 | completions |
| 450 | (eshell-alias-completions filename)) | 450 | (setq completions |
| 451 | (eshell-winnow-list | 451 | (append (if (fboundp 'eshell-alias-completions) |
| 452 | (mapcar | 452 | (eshell-alias-completions filename)) |
| 453 | (lambda (name) | 453 | (eshell-winnow-list |
| 454 | (substring name 7)) | 454 | (mapcar |
| 455 | (all-completions (concat "eshell/" filename) | 455 | (lambda (name) |
| 456 | obarray #'functionp)) | 456 | (substring name 7)) |
| 457 | nil '(eshell-find-alias-function)) | 457 | (all-completions (concat "eshell/" filename) |
| 458 | completions)) | 458 | obarray #'functionp)) |
| 459 | (append (and (or eshell-show-lisp-completions | 459 | nil '(eshell-find-alias-function)) |
| 460 | (and eshell-show-lisp-alternatives | 460 | completions)) |
| 461 | (null completions))) | 461 | (append (and (or eshell-show-lisp-completions |
| 462 | (all-completions filename obarray #'functionp)) | 462 | (and eshell-show-lisp-alternatives |
| 463 | completions))))))) | 463 | (null completions))) |
| 464 | (all-completions filename obarray #'functionp)) | ||
| 465 | completions))))))))) | ||
| 464 | 466 | ||
| 465 | (define-obsolete-function-alias 'eshell-pcomplete #'completion-at-point "27.1") | 467 | (define-obsolete-function-alias 'eshell-pcomplete #'completion-at-point "27.1") |
| 466 | 468 | ||