aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2021-01-31 19:27:10 -0500
committerStefan Monnier2021-01-31 19:27:10 -0500
commit82c76e3aeb2465d1d1e66eae5db13ba53e38ed84 (patch)
treea9a59dd4dcd1a08b96c43192e0c3d3c2b419ad82
parent24b9515da0588aca38a1bce5f615e0cdf7891388 (diff)
downloademacs-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.el118
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