summaryrefslogtreecommitdiff
path: root/lisp/pcomplete.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/pcomplete.el')
-rw-r--r--lisp/pcomplete.el125
1 files changed, 71 insertions, 54 deletions
diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el
index 5c81138d596..0b34712a50c 100644
--- a/lisp/pcomplete.el
+++ b/lisp/pcomplete.el
@@ -138,6 +138,11 @@
"A regexp of names to be disregarded during directory completion."
:type '(choice regexp (const :tag "None" nil)))
+(defcustom pcomplete-remote-file-ignore nil
+ "Whether to ignore remote file names."
+ :version "30.1"
+ :type 'boolean)
+
(define-obsolete-variable-alias 'pcomplete-ignore-case 'completion-ignore-case
"28.1")
@@ -362,6 +367,32 @@ modified to be an empty string, or the desired separation string."
;;; User Functions:
+(defun pcomplete-default-exit-function (_s status)
+ "The default exit function to use in `pcomplete-completions-at-point'.
+This just adds `pcomplete-termination-string' after the
+completion if STATUS is `finished'."
+ (unless (zerop (length pcomplete-termination-string))
+ (when (eq status 'finished)
+ (if (looking-at
+ (regexp-quote pcomplete-termination-string))
+ (goto-char (match-end 0))
+ (insert pcomplete-termination-string)))))
+
+(defvar pcomplete-exit-function #'pcomplete-default-exit-function
+ "The exit function to call in `pcomplete-completions-at-point'.
+
+This variable is let-bound in `pcomplete-completions-at-point',
+so you can modify or advise it in order to adjust the behavior
+for a specific completion. For example, you might do the
+following in a `pcomplete-try-first-hook' function to insert a
+trailing slash after a completion:
+
+ (add-function
+ :before (var pcomplete-exit-function)
+ (lambda (_ status)
+ (when (eq status \\='finished)
+ (insert \"/\"))))")
+
;;; Alternative front-end using the standard completion facilities.
;; The way pcomplete-parse-arguments and pcomplete-stub work only
@@ -406,6 +437,7 @@ Same as `pcomplete' but using the standard completion UI."
(if pcomplete-allow-modifications buffer-read-only t))
pcomplete-seen pcomplete-norm-func
pcomplete-args pcomplete-last pcomplete-index
+ (pcomplete-exit-function pcomplete-exit-function)
(pcomplete-autolist pcomplete-autolist)
(pcomplete-suffix-list pcomplete-suffix-list)
;; Apparently the vars above are global vars modified by
@@ -438,6 +470,8 @@ Same as `pcomplete' but using the standard completion UI."
;; rely less on c-t-subvert.
(beg (max (- (point) (length pcomplete-stub))
argbeg))
+ (end (point))
+ tmp
buftext)
;; Try and improve our guess of `beg' in case the difference
;; between pcomplete-stub and the buffer's text is simply due to
@@ -445,11 +479,19 @@ Same as `pcomplete' but using the standard completion UI."
;; indispensable but reduces the reliance on c-t-subvert and
;; improves corner case behaviors.
(while (progn (setq buftext (pcomplete-unquote-argument
- (buffer-substring beg (point))))
+ (buffer-substring beg end)))
(and (> beg argbeg)
(> (length pcomplete-stub) (length buftext))))
(setq beg (max argbeg (- beg (- (length pcomplete-stub)
(length buftext))))))
+ ;; Try and improve our guess of `end' in case it's not point.
+ (while (and (< (length buftext) (length pcomplete-stub))
+ (< end (point-max))
+ (string-prefix-p (setq tmp (pcomplete-unquote-argument
+ (buffer-substring beg (1+ end))))
+ pcomplete-stub))
+ (setq end (1+ end))
+ (setq buftext tmp))
(when completions
(let ((table
(completion-table-with-quoting
@@ -483,7 +525,7 @@ Same as `pcomplete' but using the standard completion UI."
seen)))))))
(when completion-ignore-case
(setq table (completion-table-case-fold table)))
- (list beg (point) table
+ (list beg end table
:annotation-function
(lambda (cand)
(when (stringp cand)
@@ -494,16 +536,7 @@ Same as `pcomplete' but using the standard completion UI."
(get-text-property 0 'pcomplete-help cand)))
:predicate pred
:exit-function
- ;; If completion is finished, add a terminating space.
- ;; We used to also do this if STATUS is `sole', but
- ;; that does not work right when completion cycling.
- (unless (zerop (length pcomplete-termination-string))
- (lambda (_s status)
- (when (eq status 'finished)
- (if (looking-at
- (regexp-quote pcomplete-termination-string))
- (goto-char (match-end 0))
- (insert pcomplete-termination-string)))))))))))
+ pcomplete-exit-function))))))
;; I don't think such commands are usable before first setting up buffer-local
;; variables to parse args, so there's no point autoloading it.
@@ -652,35 +685,13 @@ parts of the list.
The OFFSET argument is added to/taken away from the index that will be
used. This is really only useful with `first' and `last', for
-accessing absolute argument positions.
-
-When the argument has been transformed into something that is not
-a string by `pcomplete-parse-arguments-function', the text
-representation of the argument, namely what the user actually
-typed in, is returned, and the value of the argument is stored in
-the pcomplete-arg-value text property of that string."
- (let ((arg
- (nth (+ (pcase index
- ('first 0)
- ('last pcomplete-last)
- (_ (- pcomplete-index (or index 0))))
- (or offset 0))
- pcomplete-args)))
- (if (or (stringp arg)
- ;; FIXME: 'last' is handled specially in Emacs 29, because
- ;; 'pcomplete-parse-arguments' accepts a list of strings
- ;; (which are completion candidates) as return value for
- ;; (pcomplete-arg 'last). See below: "it means it's a
- ;; list of completions computed during parsing,
- ;; e.g. Eshell uses that to turn globs into lists of
- ;; completions". This special case will be dealt with
- ;; differently in Emacs 30: the pcomplete-arg-value
- ;; property will be used by 'pcomplete-parse-arguments'.
- (eq index 'last))
- arg
- (propertize
- (car (split-string (pcomplete-actual-arg index offset)))
- 'pcomplete-arg-value arg))))
+accessing absolute argument positions."
+ (nth (+ (pcase index
+ ('first 0)
+ ('last pcomplete-last)
+ (_ (- pcomplete-index (or index 0))))
+ (or offset 0))
+ pcomplete-args))
(defun pcomplete-begin (&optional index offset)
"Return the beginning position of the INDEXth argument.
@@ -891,14 +902,16 @@ this is `comint-dynamic-complete-functions'."
(and dir-ignore (string-match dir-ignore file))
(and file-ignore (string-match file-ignore file))))))))
(reg-pred (if regexp (lambda (file) (string-match regexp file))))
- (pred (cond
- ((null (or ign-pred reg-pred)) predicate)
- ((null (or ign-pred predicate)) reg-pred)
- ((null (or reg-pred predicate)) ign-pred)
- (t (lambda (f)
+ ;; `completion-file-name-table' calls `file-exists-p' when
+ ;; the predicate is nil.
+ ;; So likewise, defer to PREDICATE if it's there, else take
+ ;; ourselves to be responsible for calling `file-exists-p'.
+ (pred (if (or ign-pred reg-pred)
+ (lambda (f)
(and (or (null reg-pred) (funcall reg-pred f))
(or (null ign-pred) (funcall ign-pred f))
- (or (null predicate) (funcall predicate f))))))))
+ (funcall (or predicate #'file-exists-p) f)))
+ predicate)))
(lambda (s p a)
(if (and (eq a 'metadata) pcomplete-compare-entry-function)
`(metadata (cycle-sort-function
@@ -906,7 +919,10 @@ this is `comint-dynamic-complete-functions'."
(sort comps pcomplete-compare-entry-function)))
,@(cdr (completion-file-name-table s p a)))
(let ((completion-ignored-extensions nil)
- (completion-ignore-case completion-ignore-case))
+ (completion-ignore-case completion-ignore-case)
+ (tramp-mode (and tramp-mode (not pcomplete-remote-file-ignore)))
+ (non-essential (not (file-remote-p s)))
+ (minibuffer-completing-file-name (not (file-remote-p s))))
(completion-table-with-predicate
#'comint-completion-file-name-table pred 'strict s p a))))))
@@ -1124,7 +1140,7 @@ Typing SPC flushes the help buffer."
(let (event)
(prog1
(catch 'done
- (while (with-current-buffer (get-buffer "*Completions*")
+ (while (with-current-buffer "*Completions*"
(setq event (read-event)))
(cond
((eq event ?\s)
@@ -1300,11 +1316,12 @@ If specific documentation can't be given, be generic."
;; general utilities
-(defun pcomplete-uniquify-list (l)
- "Sort and remove multiples in L."
- (setq l (sort l #'string-lessp))
- (seq-uniq l))
-(define-obsolete-function-alias 'pcomplete-uniqify-list #'pcomplete-uniquify-list "27.1")
+(defun pcomplete-uniquify-list (sequence)
+ "Sort and remove multiples in SEQUENCE.
+Sequence should be a vector or list of strings."
+ (sort (seq-uniq sequence) #'string-lessp))
+(define-obsolete-function-alias
+ 'pcomplete-uniqify-list #'pcomplete-uniquify-list "27.1")
(defun pcomplete-process-result (cmd &rest args)
"Call CMD using `call-process' and return the simplest result."