diff --git a/lisp/icomplete.el b/lisp/icomplete.el index 2ea5e36fa88..c37275587b6 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -317,6 +317,30 @@ icomplete-vertical-goto-last ;;;_* Helpers for `fido-mode' (or `ido-mode' emulation) +(cl-defgeneric icomplete-kill-candidate (category _candidate) + "\"Kill\" CANDIDATE, assuming it is of kind CATEGORY. +CANDIDATE is a string denoting a completion candidate, +CATEGORY should be a completion category, as specified +in `completion-metadata'. +\"Kill\" here means to actually delete the underlying object, such +as a file, buffer, ..." + (error "Don't know how to kill things for category `%s'" category)) + +(cl-defmethod icomplete-kill-candidate ((_ (eq 'buffer)) thing) + ;; FIXME: Shouldn't the confirmation prompting be done by the caller? + (when (yes-or-no-p (concat "Kill buffer " thing "? ")) + (kill-buffer thing))) + +(cl-defmethod icomplete-kill-candidate ((_ (eq 'file)) thing) + ;; FIXME: This makes assumptions about completion style: e.g. with + ;; partial-completion, `/usr/s/d/ema' can result in DIR being + ;; `/usr/s/d/' and THING being `share/doc/emacs', in which case DIR + ;; isn't the right base directory to pass to `expand-file-name'! + (let* ((dir (file-name-directory (icomplete--field-string))) + (file (expand-file-name thing dir))) + (when (yes-or-no-p (concat "Delete file " file "? ")) + (delete-file file) t))) + (defun icomplete-fido-kill () "Kill line or current completion, like `ido-mode'. If killing to the end of line make sense, call `kill-line', @@ -331,26 +355,12 @@ icomplete-fido-kill (call-interactively 'kill-line) (let* ((all (completion-all-sorted-completions)) (thing (car all)) - (cat (icomplete--category)) - (action - (cl-case cat - (buffer - (lambda () - (when (yes-or-no-p (concat "Kill buffer " thing "? ")) - (kill-buffer thing)))) - ((project-file file) - (lambda () - (let* ((dir (file-name-directory (icomplete--field-string))) - (path (expand-file-name thing dir))) - (when (yes-or-no-p (concat "Delete file " path "? ")) - (delete-file path) t)))) - (t - (error "Sorry, don't know how to kill things for `%s'" cat))))) + (cat (icomplete--category))) (when (let (;; Allow `yes-or-no-p' to work and don't let it ;; `icomplete-exhibit' anything. (enable-recursive-minibuffers t) (icomplete-mode nil)) - (funcall action)) + (icomplete-kill-candidate cat thing)) (completion--cache-all-sorted-completions (icomplete--field-beg) (icomplete--field-end) @@ -373,6 +383,8 @@ icomplete-fido-ret (file-name-directory (icomplete--field-string)))) (current (car completion-all-sorted-completions)) (probe (and dir current + ;; FIXME: Same problem as in + ;; `icomplete-kill-candidate' above. (expand-file-name (directory-file-name current) (substitute-env-vars dir))))) (cond ((and probe (file-directory-p probe) (not (string= current "./")))