From 730e7da7ba6a4b545176ea246653928edb10cff4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Thu, 31 Oct 2019 10:58:38 +0000 Subject: [PATCH] New icomplete-tidy-shadowed-file-names variable * lisp/icomplete.el (rfn-eshadow): Require it. (icomplete-tidy-shadowed-file-names): New variable. (icomplete-exhibit): Use icomplete-tidy-shadowed-file-names. --- lisp/icomplete.el | 105 +++++++++++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 39 deletions(-) diff --git a/lisp/icomplete.el b/lisp/icomplete.el index 47e47f895f0..8357fd900f0 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -49,6 +49,8 @@ ;;; Code: +(require 'rfn-eshadow) ; rfn-eshadow-overlay + (defgroup icomplete nil "Show completions dynamically in minibuffer." :prefix "icomplete-" @@ -66,6 +68,12 @@ When nil, show candidates in full." :type 'boolean :version "24.4") +(defvar icomplete-tidy-shadowed-file-names nil + "If non-nil, delete superflous parts of input file names. +For example, if the user types ~/ after a long path name, +everything preceding the ~/ is discarded so the interactive +selection process starts again from the user's $HOME.") + (defcustom icomplete-show-matches-on-no-input nil "When non-nil, show completions when first prompting for input." :type 'boolean @@ -226,7 +234,11 @@ Last entry becomes the first and can be selected with ;;; (define-key imap (kbd "C-d") 'icomplete-magic-ido-delete-char) ;;; (define-key imap (kbd "RET") 'icomplete-magic-ido-ret) ;;; (define-key imap (kbd "DEL") 'icomplete-magic-ido-backward-updir)) - +;;; +;;; For more ido behaviour, you'll probably like this too: +;;; +;;; (setq icomplete-tidy-shadowed-file-names t) +;;; (defun icomplete-magic-ido-kill () "Kill line or current completion, like `ido-mode'. If killing to the end of line make sense, call `kill-line', @@ -422,44 +434,59 @@ See `icomplete-mode' and `minibuffer-setup-hook'." (save-excursion (goto-char (point-max)) ; Insert the match-status information: - (if (and (or icomplete-show-matches-on-no-input - (> (icomplete--field-end) (icomplete--field-beg))) - (or - ;; Don't bother with delay after certain number of chars: - (> (- (point) (icomplete--field-beg)) - icomplete-max-delay-chars) - ;; Don't delay if the completions are known. - completion-all-sorted-completions - ;; Don't delay if alternatives number is small enough: - (and (sequencep (icomplete--completion-table)) - (< (length (icomplete--completion-table)) - icomplete-delay-completions-threshold)) - ;; Delay - give some grace time for next keystroke, before - ;; embarking on computing completions: - (sit-for icomplete-compute-delay))) - (let* ((field-string (icomplete--field-string)) - ;; Not sure why, but such requests seem to come - ;; every once in a while. It's not fully - ;; deterministic but `C-x C-f M-DEL M-DEL ...' - ;; seems to trigger it fairly often! - (while-no-input-ignore-events '(selection-request)) - (text (while-no-input - (icomplete-completions - field-string - (icomplete--completion-table) - (icomplete--completion-predicate) - (if (window-minibuffer-p) - (not minibuffer-completion-confirm))))) - (buffer-undo-list t) - deactivate-mark) - ;; Do nothing if while-no-input was aborted. - (when (stringp text) - (move-overlay icomplete-overlay (point) (point) (current-buffer)) - ;; The current C cursor code doesn't know to use the overlay's - ;; marker's stickiness to figure out whether to place the cursor - ;; before or after the string, so let's spoon-feed it the pos. - (put-text-property 0 1 'cursor t text) - (overlay-put icomplete-overlay 'after-string text))))))) + (when (and (or icomplete-show-matches-on-no-input + (> (icomplete--field-end) (icomplete--field-beg))) + (or + ;; Don't bother with delay after certain number of chars: + (> (- (point) (icomplete--field-beg)) + icomplete-max-delay-chars) + ;; Don't delay if the completions are known. + completion-all-sorted-completions + ;; Don't delay if alternatives number is small enough: + ;; Not sure why, but such requests seem to come + ;; every once in a while. It's not fully + ;; deterministic but `C-x C-f M-DEL M-DEL ...' + ;; seems to trigger it fairly often! + (while-no-input-ignore-events '(selection-request)) (and (sequencep (icomplete--completion-table)) + (< (length (icomplete--completion-table)) + icomplete-delay-completions-threshold)) + ;; Delay - give some grace time for next keystroke, before + ;; embarking on computing completions: + (sit-for icomplete-compute-delay))) + (when (and + icomplete-tidy-shadowed-file-names + (eq (alist-get 'category + (cdr (completion--field-metadata + (icomplete--field-beg)))) + 'file) + rfn-eshadow-overlay (overlay-buffer rfn-eshadow-overlay) + (or (>= (- (point) (overlay-end rfn-eshadow-overlay)) 2) + (eq ?/ (char-before (- (point) 2))))) + (delete-region (overlay-start rfn-eshadow-overlay) + (overlay-end rfn-eshadow-overlay)) ) + (let* ((field-string (icomplete--field-string)) + ;; Not sure why, but such requests seem to come + ;; every once in a while. It's not fully + ;; deterministic but `C-x C-f M-DEL M-DEL ...' + ;; seems to trigger it fairly often! + (while-no-input-ignore-events '(selection-request)) + (text (while-no-input + (icomplete-completions + field-string + (icomplete--completion-table) + (icomplete--completion-predicate) + (if (window-minibuffer-p) + (not minibuffer-completion-confirm))))) + (buffer-undo-list t) + deactivate-mark) + ;; Do nothing if while-no-input was aborted. + (when (stringp text) + (move-overlay icomplete-overlay (point) (point) (current-buffer)) + ;; The current C cursor code doesn't know to use the overlay's + ;; marker's stickiness to figure out whether to place the cursor + ;; before or after the string, so let's spoon-feed it the pos. + (put-text-property 0 1 'cursor t text) + (overlay-put icomplete-overlay 'after-string text))))))) ;;;_ > icomplete-completions (name candidates predicate require-match) (defun icomplete-completions (name candidates predicate require-match) -- 2.39.5