diff options
author | Jambunathan K <kjambunathan@gmail.com> | 2012-11-29 16:32:24 -0500 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2012-11-29 16:32:24 -0500 |
commit | cc37e70f6699cbadb1a8f5467e8dc9fcea986aa1 (patch) | |
tree | d0bd2e2dc9ebf2f2a958c7acb9cff788f11788ca | |
parent | 83e12fe07c18a6190c6c5ef6e959697eb0ac9f19 (diff) | |
download | emacs-cc37e70f6699cbadb1a8f5467e8dc9fcea986aa1.tar.gz |
* lisp/icomplete.el: Change separator; add ido-style commands.
(icomplete-show-key-bindings): Remove custom var.
(icomplete-get-keys): Remove function.
(icomplete-forward-completions, icomplete-backward-completions):
New commands.
(icomplete-minibuffer-map): New var.
(icomplete-minibuffer-setup): Use it.
(icomplete-exhibit): Don't delay if the list of completions is known.
(icomplete-separator): New custom.
(icomplete-completions): Use it.
* lisp/minibuffer.el (completion-all-sorted-completions): Delete duplicates.
(minibuffer-force-complete-and-exit): New command.
(minibuffer--complete-and-exit): New function extracted from
minibuffer-complete-and-exit.
(minibuffer-complete-and-exit): Use it.
-rw-r--r-- | etc/NEWS | 4 | ||||
-rw-r--r-- | lisp/ChangeLog | 19 | ||||
-rw-r--r-- | lisp/icomplete.el | 107 | ||||
-rw-r--r-- | lisp/minibuffer.el | 42 |
4 files changed, 116 insertions, 56 deletions
@@ -29,6 +29,10 @@ so we will look at it and add it to the manual. * Changes in Specialized Modes and Packages in Emacs 24.4 +** Icomplete is a bit more like IDO. +*** key bindings to navigate through and select the completions. +*** The icomplete-separator is customizable, and its default has changed. +*** Removed icomplete-show-key-bindings. ** Calc *** Calc by default now uses the Gregorian calendar for all dates, and diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 20de699a5ed..73a58600ba2 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,4 +1,21 @@ -2012-11-29 Stefan Monnier <monnier@iro.umontreal.ca> +2012-11-29 Jambunathan K <kjambunathan@gmail.com> + Stefan Monnier <monnier@iro.umontreal.ca> + + * icomplete.el: Change separator; add ido-style commands. + (icomplete-show-key-bindings): Remove custom var. + (icomplete-get-keys): Remove function. + (icomplete-forward-completions, icomplete-backward-completions): + New commands. + (icomplete-minibuffer-map): New var. + (icomplete-minibuffer-setup): Use it. + (icomplete-exhibit): Don't delay if the list of completions is known. + (icomplete-separator): New custom. + (icomplete-completions): Use it. + * minibuffer.el (completion-all-sorted-completions): Delete duplicates. + (minibuffer-force-complete-and-exit): New command. + (minibuffer--complete-and-exit): New function extracted from + minibuffer-complete-and-exit. + (minibuffer-complete-and-exit): Use it. * progmodes/etags.el (visit-tags-table-buffer): Give a more precise error message when the file doesn't exist (bug#12974). diff --git a/lisp/icomplete.el b/lisp/icomplete.el index a4e3e339470..768692281f8 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -71,6 +71,11 @@ (make-obsolete-variable 'icomplete-prospects-length 'icomplete-prospects-height "23.1") +(defcustom icomplete-separator " | " + "String used by icomplete to separate alternatives in the minibuffer." + :type 'string + :version "24.3") + ;;;_* User Customization variables (defcustom icomplete-prospects-height ;; 20 is an estimated common size for the prompt + minibuffer content, to @@ -97,11 +102,6 @@ See `icomplete-delay-completions-threshold'." :type 'integer :group 'icomplete) -(defcustom icomplete-show-key-bindings t - "If non-nil, show key bindings as well as completion for sole matches." - :type 'boolean - :group 'icomplete) - (defcustom icomplete-minibuffer-setup-hook nil "Icomplete-specific customization of minibuffer setup. @@ -145,23 +145,6 @@ Use `icomplete-mode' function to set it up properly for incremental minibuffer completion.") (add-hook 'icomplete-post-command-hook 'icomplete-exhibit) -(defun icomplete-get-keys (func-name) - "Return strings naming keys bound to FUNC-NAME, or nil if none. -Examines the prior, not current, buffer, presuming that current buffer -is minibuffer." - (when (commandp func-name) - (save-excursion - (let* ((sym (intern func-name)) - (buf (other-buffer nil t)) - (keys (with-current-buffer buf (where-is-internal sym)))) - (when keys - (concat "<" - (mapconcat 'key-description - (sort keys - #'(lambda (x y) - (< (length x) (length y)))) - ", ") - ">")))))) ;;;_ = icomplete-with-completion-tables (defvar icomplete-with-completion-tables '(internal-complete-buffer) "Specialized completion tables with which icomplete should operate. @@ -169,6 +152,37 @@ is minibuffer." Icomplete does not operate with any specialized completion tables except those on this list.") +(defvar icomplete-minibuffer-map + (let ((map (make-sparse-keymap))) + (define-key map [?\M-\t] 'minibuffer-force-complete) + (define-key map [?\C-j] 'minibuffer-force-complete-and-exit) + (define-key map [?\C-s] 'icomplete-forward-completions) + (define-key map [?\C-r] 'icomplete-backward-completions) + map)) + +(defun icomplete-forward-completions () + "Step forward completions by one entry. +Second entry becomes the first and can be selected with +`minibuffer-force-complete-and-exit'." + (interactive) + (let* ((comps (completion-all-sorted-completions)) + (last (last comps))) + (setcdr last (cons (car comps) (cdr last))) + (completion--cache-all-sorted-completions (cdr comps)))) + +(defun icomplete-backward-completions () + "Step backward completions by one entry. +Last entry becomes the first and can be selected with +`minibuffer-force-complete-and-exit'." + (interactive) + (let* ((comps (completion-all-sorted-completions)) + (last-but-one (last comps 2)) + (last (cdr last-but-one))) + (when last + (setcdr last-but-one (cdr last)) + (push (car last) comps) + (completion--cache-all-sorted-completions comps)))) + ;;;_ > icomplete-mode (&optional prefix) ;;;###autoload (define-minor-mode icomplete-mode @@ -208,6 +222,8 @@ Conditions are: Usually run by inclusion in `minibuffer-setup-hook'." (when (and icomplete-mode (icomplete-simple-completing-p)) (set (make-local-variable 'completion-show-inline-help) nil) + (use-local-map (make-composed-keymap icomplete-minibuffer-map + (current-local-map))) (add-hook 'pre-command-hook (lambda () (let ((non-essential t)) (run-hooks 'icomplete-pre-command-hook))) @@ -239,27 +255,29 @@ and `minibuffer-setup-hook'." (goto-char (point-max)) ; Insert the match-status information: (if (and (> (point-max) (minibuffer-prompt-end)) - buffer-undo-list ; Wait for some user input. - (or - ;; Don't bother with delay after certain number of chars: - (> (- (point) (field-beginning)) icomplete-max-delay-chars) - ;; Don't delay if alternatives number is small enough: - (and (sequencep minibuffer-completion-table) - (< (length minibuffer-completion-table) - icomplete-delay-completions-threshold)) - ;; Delay - give some grace time for next keystroke, before + buffer-undo-list ; Wait for some user input. + (or + ;; Don't bother with delay after certain number of chars: + (> (- (point) (field-beginning)) 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 minibuffer-completion-table) + (< (length minibuffer-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 ((text (while-no-input - (icomplete-completions - (field-string) - minibuffer-completion-table - minibuffer-completion-predicate + (icomplete-completions + (field-string) + minibuffer-completion-table + minibuffer-completion-predicate (not minibuffer-completion-confirm)))) (buffer-undo-list t) deactivate-mark) ;; Do nothing if while-no-input was aborted. - (when (stringp text) + (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 @@ -365,17 +383,14 @@ are exhibited within the square braces.)" (if prospects (concat determ "{" - (and most-is-exact ",") - (mapconcat 'identity (nreverse prospects) ",") - (and limit ",...") + (and most-is-exact + (substring icomplete-separator + (string-match "[^ ]" icomplete-separator))) + (mapconcat 'identity (nreverse prospects) + icomplete-separator) + (and limit (concat icomplete-separator "…")) "}") - (concat determ - " [Matched" - (let ((keys (and icomplete-show-key-bindings - (commandp (intern-soft most)) - (icomplete-get-keys most)))) - (if keys (concat "; " keys) "")) - "]")))))) + (concat determ " [Matched]")))))) ;;_* Local emacs vars. ;;Local variables: diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 6e704fad807..7fe50e930ce 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1106,6 +1106,13 @@ scroll the window of possible completions." (sort-fun (completion-metadata-get all-md 'cycle-sort-function))) (when last (setcdr last nil) + + ;; Delete duplicates: do it after setting last's cdr to nil (so + ;; it's a proper list), and be careful to reset `last' since it + ;; may be a different cons-cell. + (setq all (delete-dups all)) + (setq last (last all)) + (setq all (if sort-fun (funcall sort-fun all) ;; Prefer shorter completions, by default. (sort all (lambda (c1 c2) (< (length c1) (length c2)))))) @@ -1120,6 +1127,15 @@ scroll the window of possible completions." ;; all possibilities. (completion--cache-all-sorted-completions (nconc all base-size)))))) +(defun minibuffer-force-complete-and-exit () + "Complete the minibuffer with first of the matches and exit." + (interactive) + (minibuffer-force-complete) + (minibuffer--complete-and-exit + ;; If the previous completion completed to an element which fails + ;; test-completion, then we shouldn't exit, but that should be rare. + (lambda () (minibuffer-message "Incomplete")))) + (defun minibuffer-force-complete () "Complete the minibuffer to an exact match. Repeated uses step through the possible completions." @@ -1192,6 +1208,22 @@ If `minibuffer-completion-confirm' is `confirm-after-completion', `minibuffer-confirm-exit-commands', and accept the input otherwise." (interactive) + (minibuffer--complete-and-exit + (lambda () + (pcase (condition-case nil + (completion--do-completion nil 'expect-exact) + (error 1)) + ((or #b001 #b011) (exit-minibuffer)) + (#b111 (if (not minibuffer-completion-confirm) + (exit-minibuffer) + (minibuffer-message "Confirm") + nil)) + (_ nil))))) + +(defun minibuffer--complete-and-exit (completion-function) + "Exit from `require-match' minibuffer. +COMPLETION-FUNCTION is called if the current buffer's content does not +appear to be a match." (let ((beg (field-beginning)) (end (field-end))) (cond @@ -1239,15 +1271,7 @@ If `minibuffer-completion-confirm' is `confirm-after-completion', (t ;; Call do-completion, but ignore errors. - (pcase (condition-case nil - (completion--do-completion nil 'expect-exact) - (error 1)) - ((or #b001 #b011) (exit-minibuffer)) - (#b111 (if (not minibuffer-completion-confirm) - (exit-minibuffer) - (minibuffer-message "Confirm") - nil)) - (_ nil)))))) + (funcall completion-function))))) (defun completion--try-word-completion (string table predicate point md) (let ((comp (completion-try-completion string table predicate point md))) |