# HG changeset patch # User Stefan Monnier # Date 1207769636 0 # Node ID dfe13eac745b1d6b6bb6c943261bfe6adbc5b326 # Parent 3bc9b0eef2325aaf3f92f9c52cd99d1076d5abb5 * minibuffer.el (minibuffer): Move group from cus-edit.el. (completion-auto-help): Move from C code. (minibuffer--maybe-completion-help): Remove. (minibuffer--bitset): New function. (minibuffer--do-completion): Rename from minibuffer-do-completion. Renumber a bit. Really complete on string *before* point. Add argument used for word-completion. Join trailing / in completion with following text, as done in minibuffer-complete-word. Handle new value `lazy' for completion-auto-help. (minibuffer-try-word-completion): New function extracted from minibuffer-complete-word. (minibuffer-complete-word): Use minibuffer--do-completion. (minibuffer--insert-strings): Rename from minibuffer-complete-insert-strings. (exit-minibuffer): Fix typo. * cus-edit.el (minibuffer): Move group to minibuffer.el. * cus-start.el: Remove completion-auto-help. * minibuf.c (Vcompletion_auto_help): Move to minibuffer.el. (syms_of_minibuf): Remove its initialization. diff -r 3bc9b0eef232 -r dfe13eac745b etc/NEWS --- a/etc/NEWS Wed Apr 09 19:08:22 2008 +0000 +++ b/etc/NEWS Wed Apr 09 19:33:56 2008 +0000 @@ -65,6 +65,10 @@ * Changes in Emacs 23.1 +** `completion-auto-help' can be set to `lazy' to list the completions only +if you repeat the completion. This was already supported in +`partial-completion-mode'. + ** Emacs now supports using both X displays and ttys in one session. Start the server (M-x server-start). Then `emacsclient -t' creates a tty frame connected to the running emacs server. You can also use any diff -r 3bc9b0eef232 -r dfe13eac745b lisp/ChangeLog --- a/lisp/ChangeLog Wed Apr 09 19:08:22 2008 +0000 +++ b/lisp/ChangeLog Wed Apr 09 19:33:56 2008 +0000 @@ -1,9 +1,30 @@ +2008-04-09 Stefan Monnier + + * minibuffer.el (minibuffer): Move group from cus-edit.el. + (completion-auto-help): Move from C code. + (minibuffer--maybe-completion-help): Remove. + (minibuffer--bitset): New function. + (minibuffer--do-completion): Rename from minibuffer-do-completion. + Renumber a bit. Really complete on string *before* point. + Add argument used for word-completion. + Join trailing / in completion with following text, as done in + minibuffer-complete-word. + Handle new value `lazy' for completion-auto-help. + (minibuffer-try-word-completion): New function extracted from + minibuffer-complete-word. + (minibuffer-complete-word): Use minibuffer--do-completion. + (minibuffer--insert-strings): Rename from + minibuffer-complete-insert-strings. + (exit-minibuffer): Fix typo. + * cus-edit.el (minibuffer): Move group to minibuffer.el. + * cus-start.el: Remove completion-auto-help. + 2008-04-09 Alexandre Julliard * vc.el (vc-status-add-entries): New function. - (vc-status-add-entry): Removed. - (vc-update-vc-status-buffer, vc-status-mark-buffer-changed): Use - vc-status-add-entries. + (vc-status-add-entry): Remove. + (vc-update-vc-status-buffer, vc-status-mark-buffer-changed): + Use vc-status-add-entries. * emacs-lisp/ewoc.el (ewoc-collect): Return results in the correct order. @@ -18,8 +39,8 @@ 2008-04-09 Chong Yidong - * emacs-lisp/regexp-opt.el (regexp-opt): Reduce - max-lisp-eval-depth and max-specpdl-size to 10000. + * emacs-lisp/regexp-opt.el (regexp-opt): + Reduce max-lisp-eval-depth and max-specpdl-size to 10000. 2008-04-09 Lennart Borgman diff -r 3bc9b0eef232 -r dfe13eac745b lisp/cus-edit.el --- a/lisp/cus-edit.el Wed Apr 09 19:08:22 2008 +0000 +++ b/lisp/cus-edit.el Wed Apr 09 19:33:56 2008 +0000 @@ -416,11 +416,6 @@ "Debugging Emacs itself." :group 'development) -(defgroup minibuffer nil - "Controlling the behavior of the minibuffer." - :link '(custom-manual "(emacs)Minibuffer") - :group 'environment) - (defgroup keyboard nil "Input from the keyboard." :group 'environment) diff -r 3bc9b0eef232 -r dfe13eac745b lisp/cus-start.el --- a/lisp/cus-start.el Wed Apr 09 19:08:22 2008 +0000 +++ b/lisp/cus-start.el Wed Apr 09 19:33:56 2008 +0000 @@ -248,7 +248,6 @@ ;;; (const :tag " current dir" nil) ;;; (directory :format "%v")))) ;; minibuf.c - (completion-auto-help minibuffer boolean) (enable-recursive-minibuffers minibuffer boolean) (history-length minibuffer (choice (const :tag "Infinite" t) integer) diff -r 3bc9b0eef232 -r dfe13eac745b lisp/minibuffer.el --- a/lisp/minibuffer.el Wed Apr 09 19:08:22 2008 +0000 +++ b/lisp/minibuffer.el Wed Apr 09 19:33:56 2008 +0000 @@ -21,6 +21,9 @@ ;;; Commentary: +;; Names starting with "minibuffer--" are for functions and variables that +;; are meant to be for internal use only. + ;; TODO: ;; - merge do-completion and complete-word ;; - move all I/O out of do-completion @@ -29,6 +32,11 @@ (eval-when-compile (require 'cl)) +(defgroup minibuffer nil + "Controlling the behavior of the minibuffer." + :link '(custom-manual "(emacs)Minibuffer") + :group 'environment) + (defun minibuffer-message (message &rest args) "Temporarily display MESSAGE at the end of the minibuffer. The text is displayed for `minibuffer-message-timeout' seconds, @@ -37,7 +45,7 @@ If ARGS are provided, then pass MESSAGE through `format'." ;; Clear out any old echo-area message to make way for our new thing. (message nil) - (unless (string-match "\\[.+\\]" message) + (unless (and (null args) (string-match "\\[.+\\]" message)) (setq message (concat " [" message "]"))) (when args (setq message (apply 'format message args))) (let ((ol (make-overlay (point-max) (point-max) nil t t))) @@ -57,33 +65,45 @@ If the current buffer is not a minibuffer, erase its entire contents." (delete-field)) -(defun minibuffer--maybe-completion-help () - (if completion-auto-help - (minibuffer-completion-help) - (minibuffer-message "Next char not unique"))) +(defcustom completion-auto-help t + "Non-nil means automatically provide help for invalid completion input. +If the value is t the *Completion* buffer is displayed whenever completion +is requested but cannot be done. +If the value is `lazy', the *Completions* buffer is only displayed after +the second failed attempt to complete." + :type (choice (const nil) (const t) (const lazy)) + :group 'minibuffer) -(defun minibuffer-do-completion () - "Do the completion and return a summary of what happened. -C = There were available completions. -E = After completion we now have an exact match. -M = Completion was performed, the text was Modified. +(defun minibuffer--bitset (modified completions exact) + (logior (if modified 4 0) + (if completions 2 0) + (if exact 1 0))) - CEM - 000 0 no possible completion - 010 1 was already an exact and unique completion - 110 3 was already an exact completion - 111 4 completed to an exact completion - 101 5 some completion happened - 100 6 no completion happened" - (let* ((string (minibuffer-completion-contents)) - (completion (try-completion (field-string) - minibuffer-completion-table - minibuffer-completion-predicate))) - (setq last-exact-completion nil) +(defun minibuffer--do-completion (&optional try-completion-function) + "Do the completion and return a summary of what happened. +M = completion was performed, the text was Modified. +C = there were available Completions. +E = after completion we now have an Exact match. + + MCE + 000 0 no possible completion + 001 1 was already an exact and unique completion + 010 2 no completion happened + 011 3 was already an exact completion + 100 4 ??? impossible + 101 5 ??? impossible + 110 6 some completion happened + 111 7 completed to an exact completion" + (let* ((beg (field-beginning)) + (string (buffer-substring beg (point))) + (completion (funcall (or try-completion-function 'try-completion) + string + minibuffer-completion-table + minibuffer-completion-predicate))) (cond ((null completion) - (ding) (minibuffer-message "No match") 0) - ((eq t completion) 1) ;Exact and unique match. + (ding) (minibuffer-message "No match") (minibuffer--bitset nil nil nil)) + ((eq t completion) (minibuffer--bitset nil nil t)) ;Exact and unique match. (t ;; `completed' should be t if some completion was done, which doesn't ;; include simply changing the case of the entered string. However, @@ -93,34 +113,46 @@ (unchanged (eq t (compare-strings completion nil nil string nil nil nil)))) (unless unchanged - (let ((beg (field-beginning)) - (end (point))) + ;; Merge a trailing / in completion with a / after point. + ;; We used to only do it for word completion, but it seems to make + ;; sense for all completions. + (if (and (eq ?/ (aref completion (1- (length completion)))) + (< (point) (field-end)) + (eq ?/ (char-after))) + (setq completion (substring completion 0 -1))) + + ;; Insert in minibuffer the chars we got. + (let ((end (point))) (insert completion) (delete-region beg end))) + (if (not (or unchanged completed)) ;; The case of the string changed, but that's all. We're not sure ;; whether this is a unique completion or not, so try again using ;; the real case (this shouldn't recurse again, because the next ;; time try-completion will return either t or the exact string). - (minibuffer-do-completion) + (minibuffer--do-completion) ;; It did find a match. Do we match some possibility exactly now? (let ((exact (test-completion (field-string) minibuffer-completion-table minibuffer-completion-predicate))) - (cond - ((not exact) - (if completed 5 - (minibuffer--maybe-completion-help) - 6)) - (completed 4) - (t - ;; If the last exact completion and this one were the same, - ;; it means we've already given a "Complete but not unique" - ;; message and the user's hit TAB again, so now we give him help. - (if (eq this-command last-command) - (minibuffer-completion-help)) - 3))))))))) + (unless completed + ;; Show the completion table, if requested. + (cond + ((not exact) + (if (case completion-auto-help + (lazy (eq this-command last-command)) + (t completion-auto-help)) + (minibuffer-completion-help) + (minibuffer-message "Next char not unique"))) + ;; If the last exact completion and this one were the same, + ;; it means we've already given a "Complete but not unique" + ;; message and the user's hit TAB again, so now we give him help. + ((eq this-command last-command) + (if completion-auto-help (minibuffer-completion-help))))) + + (minibuffer--bitset completed t exact)))))))) (defun minibuffer-complete () "Complete the minibuffer contents as far as possible. @@ -146,16 +178,15 @@ (scroll-other-window)) nil) - (let ((i (minibuffer-do-completion))) - (case i - (0 nil) - (1 (goto-char (field-end)) - (minibuffer-message "Sole completion") - t) - (3 (goto-char (field-end)) - (minibuffer-message "Complete, but not unique") - t) - (t t)))))) + (case (minibuffer--do-completion) + (0 nil) + (1 (goto-char (field-end)) + (minibuffer-message "Sole completion") + t) + (3 (goto-char (field-end)) + (minibuffer-message "Complete, but not unique") + t) + (t t))))) (defun minibuffer-complete-and-exit () "If the minibuffer contents is a valid completion then exit. @@ -195,33 +226,21 @@ (t ;; Call do-completion, but ignore errors. - (let ((i (condition-case nil - (minibuffer-do-completion) - (error 1)))) - (case i - ((1 3) (exit-minibuffer)) - (4 (if (not minibuffer-completion-confirm) - (exit-minibuffer) - (minibuffer-message "Confirm") - nil)) - (t nil)))))) + (case (condition-case nil + (minibuffer--do-completion) + (error 1)) + ((1 3) (exit-minibuffer)) + (7 (if (not minibuffer-completion-confirm) + (exit-minibuffer) + (minibuffer-message "Confirm") + nil)) + (t nil))))) -(defun minibuffer-complete-word () - "Complete the minibuffer contents at most a single word. -After one word is completed as much as possible, a space or hyphen -is added, provided that matches some possible completion. -Return nil if there is no valid completion, else t." - (interactive) - (let* ((beg (field-beginning)) - (string (buffer-substring beg (point))) - (completion (try-completion string - minibuffer-completion-table - minibuffer-completion-predicate))) - (cond - ((null completion) - (ding) (minibuffer-message "No match") nil) - ((eq t completion) nil) ;Exact and unique match. - (t +(defun minibuffer-try-word-completion (string table predicate) + (let ((completion (try-completion string table predicate))) + (if (not (stringp completion)) + completion + ;; Completing a single word is actually more difficult than completing ;; as much as possible, because we first have to find the "current ;; position" in `completion' in order to find the end of the word @@ -239,10 +258,7 @@ (substitute-in-file-name string) (error string)))) (unless (eq string substituted) - (setq string substituted) - (let ((end (point))) - (insert substituted) - (delete-region beg end))))) + (setq string substituted)))) ;; Make buffer (before point) contain the longest match ;; of `string's tail and `completion's head. @@ -255,8 +271,7 @@ (setq startpos (1+ startpos)) (setq length (1- length))) - (setq string (substring string startpos)) - (delete-region beg (+ beg startpos))) + (setq string (substring string startpos))) ;; Now `string' is a prefix of `completion'. @@ -267,31 +282,34 @@ tem) (while (and exts (not (stringp tem))) (setq tem (try-completion (concat string (pop exts)) - minibuffer-completion-table - minibuffer-completion-predicate))) + table predicate))) (if (stringp tem) (setq completion tem)))) - (if (= (length string) (length completion)) - ;; If got no characters, print help for user. - (progn - (if completion-auto-help (minibuffer-completion-help)) - nil) - ;; Otherwise insert in minibuffer the chars we got. - (if (string-match "\\W" completion (length string)) - ;; First find first word-break in the stuff found by completion. - ;; i gets index in string of where to stop completing. - (setq completion (substring completion 0 (match-end 0)))) + ;; Otherwise cut after the first word. + (if (string-match "\\W" completion (length string)) + ;; First find first word-break in the stuff found by completion. + ;; i gets index in string of where to stop completing. + (substring completion 0 (match-end 0)) + completion)))) + - (if (and (eq ?/ (aref completion (1- (length completion)))) - (eq ?/ (char-after))) - (setq completion (substring completion 0 (1- (length completion))))) +(defun minibuffer-complete-word () + "Complete the minibuffer contents at most a single word. +After one word is completed as much as possible, a space or hyphen +is added, provided that matches some possible completion. +Return nil if there is no valid completion, else t." + (interactive) + (case (minibuffer--do-completion 'minibuffer-try-word-completion) + (0 nil) + (1 (goto-char (field-end)) + (minibuffer-message "Sole completion") + t) + (3 (goto-char (field-end)) + (minibuffer-message "Complete, but not unique") + t) + (t t))) - (let ((pos (point))) - (insert completion) - (delete-region beg pos) - t)))))) - -(defun minibuffer-complete-insert-strings (strings) +(defun minibuffer--insert-strings (strings) "Insert a list of STRINGS into the current buffer. Uses columns to keep the listing readable but compact. It also eliminates runs of equal strings." @@ -378,7 +396,7 @@ (insert "There are no possible completions of what you have typed.") (insert "Possible completions are:\n") - (minibuffer-complete-insert-strings completions)))) + (minibuffer--insert-strings completions)))) (let ((completion-common-substring common-substring)) (run-hooks 'completion-setup-hook)) nil) @@ -421,7 +439,7 @@ ;; A better solution would be to make deactivate-mark buffer-local ;; (or to turn it into a list of buffers, ...), but in the mean time, ;; this should do the trick in most cases. - (setq deactivate_mark nil) + (setq deactivate-mark nil) (throw 'exit nil)) (defun self-insert-and-exit () diff -r 3bc9b0eef232 -r dfe13eac745b src/ChangeLog --- a/src/ChangeLog Wed Apr 09 19:08:22 2008 +0000 +++ b/src/ChangeLog Wed Apr 09 19:33:56 2008 +0000 @@ -1,5 +1,8 @@ 2008-04-09 Stefan Monnier + * minibuf.c (Vcompletion_auto_help): Move to minibuffer.el. + (syms_of_minibuf): Remove its initialization. + * minibuf.c (temp_echo_area_glyphs): Remove unused function. 2008-04-09 Juanma Barranquero diff -r 3bc9b0eef232 -r dfe13eac745b src/minibuf.c --- a/src/minibuf.c Wed Apr 09 19:08:22 2008 +0000 +++ b/src/minibuf.c Wed Apr 09 19:33:56 2008 +0000 @@ -55,10 +55,6 @@ int minibuf_level; -/* Nonzero means display completion help for invalid input. */ - -Lisp_Object Vcompletion_auto_help; - /* The maximum length of a minibuffer history. */ Lisp_Object Qhistory_length, Vhistory_length; @@ -2126,12 +2122,6 @@ `add-to-history' explicitly. */); Vhistory_add_new_input = Qt; - DEFVAR_LISP ("completion-auto-help", &Vcompletion_auto_help, - doc: /* *Non-nil means automatically provide help for invalid completion input. -Under Partial Completion mode, a non-nil, non-t value has a special meaning; -see the doc string of `partial-completion-mode' for more details. */); - Vcompletion_auto_help = Qt; - DEFVAR_BOOL ("completion-ignore-case", &completion_ignore_case, doc: /* Non-nil means don't consider case significant in completion.