summaryrefslogtreecommitdiff
path: root/lisp/eshell/em-cmpl.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/eshell/em-cmpl.el')
-rw-r--r--lisp/eshell/em-cmpl.el185
1 files changed, 83 insertions, 102 deletions
diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el
index 0200631da66..638c0ac230a 100644
--- a/lisp/eshell/em-cmpl.el
+++ b/lisp/eshell/em-cmpl.el
@@ -91,27 +91,23 @@ variable names, arguments, etc."
(defcustom eshell-cmpl-load-hook nil
"A list of functions to run when `eshell-cmpl' is loaded."
:version "24.1" ; removed eshell-cmpl-initialize
- :type 'hook
- :group 'eshell-cmpl)
+ :type 'hook)
(defcustom eshell-show-lisp-completions nil
"If non-nil, include Lisp functions in the command completion list.
If this variable is nil, Lisp completion can still be done in command
position by using M-TAB instead of TAB."
- :type 'boolean
- :group 'eshell-cmpl)
+ :type 'boolean)
(defcustom eshell-show-lisp-alternatives t
"If non-nil, and no other completions found, show Lisp functions.
Setting this variable means nothing if `eshell-show-lisp-completions'
is non-nil."
- :type 'boolean
- :group 'eshell-cmpl)
+ :type 'boolean)
(defcustom eshell-no-completion-during-jobs t
"If non-nil, don't allow completion while a process is running."
- :type 'boolean
- :group 'eshell-cmpl)
+ :type 'boolean)
(defcustom eshell-command-completions-alist
'(("acroread" . "\\.pdf\\'")
@@ -136,8 +132,7 @@ is non-nil."
"An alist that defines simple argument type correlations.
This is provided for common commands, as a simplistic alternative
to writing a completion function."
- :type '(repeat (cons string regexp))
- :group 'eshell-cmpl)
+ :type '(repeat (cons string regexp)))
(defun eshell-cmpl--custom-variable-docstring (pcomplete-var)
"Generate the docstring of a variable derived from a pcomplete-* variable."
@@ -148,23 +143,19 @@ to writing a completion function."
(defcustom eshell-cmpl-file-ignore "~\\'"
(eshell-cmpl--custom-variable-docstring 'pcomplete-file-ignore)
- :type (get 'pcomplete-file-ignore 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-file-ignore 'custom-type))
(defcustom eshell-cmpl-dir-ignore "\\`\\(\\.\\.?\\|CVS\\)/\\'"
(eshell-cmpl--custom-variable-docstring 'pcomplete-dir-ignore)
- :type (get 'pcomplete-dir-ignore 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-dir-ignore 'custom-type))
(defcustom eshell-cmpl-ignore-case (eshell-under-windows-p)
(eshell-cmpl--custom-variable-docstring 'pcomplete-ignore-case)
- :type (get 'pcomplete-ignore-case 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-ignore-case 'custom-type))
(defcustom eshell-cmpl-autolist nil
(eshell-cmpl--custom-variable-docstring 'pcomplete-autolist)
- :type (get 'pcomplete-autolist 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-autolist 'custom-type))
(defcustom eshell-cmpl-suffix-list (list ?/ ?:)
(eshell-cmpl--custom-variable-docstring 'pcomplete-suffix-list)
@@ -176,51 +167,42 @@ to writing a completion function."
(defcustom eshell-cmpl-recexact nil
(eshell-cmpl--custom-variable-docstring 'pcomplete-recexact)
- :type (get 'pcomplete-recexact 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-recexact 'custom-type))
-(defcustom eshell-cmpl-man-function 'man
+(defcustom eshell-cmpl-man-function #'man
(eshell-cmpl--custom-variable-docstring 'pcomplete-man-function)
- :type (get 'pcomplete-man-function 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-man-function 'custom-type))
-(defcustom eshell-cmpl-compare-entry-function 'file-newer-than-file-p
+(defcustom eshell-cmpl-compare-entry-function #'file-newer-than-file-p
(eshell-cmpl--custom-variable-docstring 'pcomplete-compare-entry-function)
- :type (get 'pcomplete-compare-entry-function 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-compare-entry-function 'custom-type))
(defcustom eshell-cmpl-expand-before-complete nil
(eshell-cmpl--custom-variable-docstring 'pcomplete-expand-before-complete)
- :type (get 'pcomplete-expand-before-complete 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-expand-before-complete 'custom-type))
(defcustom eshell-cmpl-cycle-completions t
(eshell-cmpl--custom-variable-docstring 'pcomplete-cycle-completions)
- :type (get 'pcomplete-cycle-completions 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-cycle-completions 'custom-type))
(defcustom eshell-cmpl-cycle-cutoff-length 5
(eshell-cmpl--custom-variable-docstring 'pcomplete-cycle-cutoff-length)
- :type (get 'pcomplete-cycle-cutoff-length 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-cycle-cutoff-length 'custom-type))
(defcustom eshell-cmpl-restore-window-delay 1
(eshell-cmpl--custom-variable-docstring 'pcomplete-restore-window-delay)
- :type (get 'pcomplete-restore-window-delay 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-restore-window-delay 'custom-type))
(defcustom eshell-command-completion-function
(lambda ()
- (pcomplete-here (eshell-complete-commands-list)))
+ (pcomplete-here (eshell--complete-commands-list)))
(eshell-cmpl--custom-variable-docstring 'pcomplete-command-completion-function)
- :type (get 'pcomplete-command-completion-function 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-command-completion-function 'custom-type))
(defcustom eshell-cmpl-command-name-function
- 'eshell-completion-command-name
+ #'eshell-completion-command-name
(eshell-cmpl--custom-variable-docstring 'pcomplete-command-name-function)
- :type (get 'pcomplete-command-name-function 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-command-name-function 'custom-type))
(defcustom eshell-default-completion-function
(lambda ()
@@ -229,13 +211,11 @@ to writing a completion function."
(cdr (assoc (funcall eshell-cmpl-command-name-function)
eshell-command-completions-alist))))))
(eshell-cmpl--custom-variable-docstring 'pcomplete-default-completion-function)
- :type (get 'pcomplete-default-completion-function 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-default-completion-function 'custom-type))
(defcustom eshell-cmpl-use-paring t
(eshell-cmpl--custom-variable-docstring 'pcomplete-use-paring)
- :type (get 'pcomplete-use-paring 'custom-type)
- :group 'eshell-cmpl)
+ :type (get 'pcomplete-use-paring 'custom-type))
;;; Functions:
@@ -274,7 +254,7 @@ to writing a completion function."
(setq-local pcomplete-default-completion-function
eshell-default-completion-function)
(setq-local pcomplete-parse-arguments-function
- 'eshell-complete-parse-arguments)
+ #'eshell-complete-parse-arguments)
(setq-local pcomplete-file-ignore
eshell-cmpl-file-ignore)
(setq-local pcomplete-dir-ignore
@@ -403,64 +383,65 @@ to writing a completion function."
args)
posns)))
-(defun eshell-complete-commands-list ()
+(defun eshell--complete-commands-list ()
"Generate list of applicable, visible commands."
- (let ((filename (pcomplete-arg)) glob-name)
- (if (file-name-directory filename)
- (if eshell-force-execution
- (pcomplete-dirs-or-entries nil #'file-readable-p)
- (pcomplete-executables))
- (if (and (> (length filename) 0)
- (eq (aref filename 0) eshell-explicit-command-char))
- (setq filename (substring filename 1)
- pcomplete-stub filename
- glob-name t))
- (let* ((paths (eshell-get-path))
- (cwd (file-name-as-directory
- (expand-file-name default-directory)))
- (path "") (comps-in-path ())
- (file "") (filepath "") (completions ()))
- ;; Go thru each path in the search path, finding completions.
- (while paths
- (setq path (file-name-as-directory
- (expand-file-name (or (car paths) ".")))
- comps-in-path
- (and (file-accessible-directory-p path)
- (file-name-all-completions filename path)))
- ;; Go thru each completion found, to see whether it should
- ;; be used.
- (while comps-in-path
- (setq file (car comps-in-path)
- filepath (concat path file))
- (if (and (not (member file completions)) ;
- (or (string-equal path cwd)
- (not (file-directory-p filepath)))
- (if eshell-force-execution
- (file-readable-p filepath)
- (file-executable-p filepath)))
- (setq completions (cons file completions)))
- (setq comps-in-path (cdr comps-in-path)))
- (setq paths (cdr paths)))
- ;; Add aliases which are currently visible, and Lisp functions.
- (pcomplete-uniquify-list
- (if glob-name
- completions
- (setq completions
- (append (if (fboundp 'eshell-alias-completions)
- (eshell-alias-completions filename))
- (eshell-winnow-list
- (mapcar
- (lambda (name)
- (substring name 7))
- (all-completions (concat "eshell/" filename)
- obarray #'functionp))
- nil '(eshell-find-alias-function))
- completions))
- (append (and (or eshell-show-lisp-completions
- (and eshell-show-lisp-alternatives
- (null completions)))
- (all-completions filename obarray #'functionp))
- completions)))))))
+ ;; Building the commands list can take quite a while, especially over Tramp
+ ;; (bug#41423), so do it lazily.
+ (let ((glob-name
+ ;; When a command is specified using `eshell-explicit-command-char',
+ ;; that char is not part of the command and hence not part of what
+ ;; we complete. Adjust `pcomplete-stub' accordingly!
+ (if (and (> (length pcomplete-stub) 0)
+ (eq (aref pcomplete-stub 0) eshell-explicit-command-char))
+ (setq pcomplete-stub (substring pcomplete-stub 1)))))
+ (completion-table-dynamic
+ (lambda (filename)
+ (if (file-name-directory filename)
+ (if eshell-force-execution
+ (pcomplete-dirs-or-entries nil #'file-readable-p)
+ (pcomplete-executables))
+ (let* ((paths (eshell-get-path))
+ (cwd (file-name-as-directory
+ (expand-file-name default-directory)))
+ (filepath "") (completions ()))
+ ;; Go thru each path in the search path, finding completions.
+ (dolist (path paths)
+ (setq path (file-name-as-directory
+ (expand-file-name (or path "."))))
+ ;; Go thru each completion found, to see whether it should
+ ;; be used.
+ (dolist (file (and (file-accessible-directory-p path)
+ (file-name-all-completions filename path)))
+ (setq filepath (concat path file))
+ (if (and (not (member file completions)) ;
+ (or (string-equal path cwd)
+ (not (file-directory-p filepath)))
+ ;; FIXME: Those repeated file tests end up
+ ;; very costly over Tramp, we should cache the result.
+ (if eshell-force-execution
+ (file-readable-p filepath)
+ (file-executable-p filepath)))
+ (push file completions))))
+ ;; Add aliases which are currently visible, and Lisp functions.
+ (pcomplete-uniquify-list
+ (if glob-name
+ completions
+ (setq completions
+ (append (if (fboundp 'eshell-alias-completions)
+ (eshell-alias-completions filename))
+ (eshell-winnow-list
+ (mapcar
+ (lambda (name)
+ (substring name 7))
+ (all-completions (concat "eshell/" filename)
+ obarray #'functionp))
+ nil '(eshell-find-alias-function))
+ completions))
+ (append (and (or eshell-show-lisp-completions
+ (and eshell-show-lisp-alternatives
+ (null completions)))
+ (all-completions filename obarray #'functionp))
+ completions)))))))))
(define-obsolete-function-alias 'eshell-pcomplete #'completion-at-point "27.1")