# HG changeset patch # User Glenn Morris # Date 1174965462 0 # Node ID 63293afecf15310af5ec0967c86ba20a5e34580b # Parent f803dda9e616e8b54aad0e2e961167d046f70a44 (PC-do-completion): Compute completion-base-size in the non-filename case, rather than setting to nil. (PC-lisp-complete-end): New variable. (PC-lisp-complete-symbol): Use PC-lisp-complete-end to store the original end in a series of consecutive invocations. diff -r f803dda9e616 -r 63293afecf15 lisp/complete.el --- a/lisp/complete.el Tue Mar 27 03:17:27 2007 +0000 +++ b/lisp/complete.el Tue Mar 27 03:17:42 2007 +0000 @@ -416,7 +416,7 @@ (let* ((table minibuffer-completion-table) (pred minibuffer-completion-predicate) (filename (funcall PC-completion-as-file-name-predicate)) - (dirname nil) ; non-nil only if a filename is being completed + (dirname nil) ; non-nil only if a filename is being completed ;; The following used to be "(dirlength 0)" which caused the erasure of ;; the entire buffer text before `point' when inserting a completion ;; into a buffer. @@ -681,7 +681,7 @@ (forward-char 1) (if (and (< (point) end) (and (looking-at " ") - (memq (aref prefix i) + (memq (aref prefix i) PC-delims-list))) ;; replace " " by the actual delimiter (progn @@ -689,12 +689,12 @@ (insert (substring prefix i (1+ i)))) ;; insert a new character (progn - (and filename (looking-at "\\*") - (progn - (delete-char 1) - (setq end (1- end)))) + (and filename (looking-at "\\*") + (progn + (delete-char 1) + (setq end (1- end)))) (setq improved t) - (insert (substring prefix i (1+ i))) + (insert (substring prefix i (1+ i))) (setq end (1+ end))))) (setq i (1+ i))) (or pt (setq pt (point))) @@ -729,7 +729,7 @@ ;; We changed it... would it be complete without the space? (if (test-completion (buffer-substring 1 (1- end)) - table pred) + table pred) (delete-region (1- end) end))) (if improved @@ -743,13 +743,25 @@ (and completion-auto-help (eq last-command this-command)) (eq mode 'help)) - (with-output-to-temp-buffer "*Completions*" - (display-completion-list (sort helpposs 'string-lessp)) - (with-current-buffer standard-output - ;; Record which part of the buffer we are completing - ;; so that choosing a completion from the list - ;; knows how much old text to replace. - (setq completion-base-size dirlength))) + (let ((prompt-end (minibuffer-prompt-end))) + (with-output-to-temp-buffer "*Completions*" + (display-completion-list (sort helpposs 'string-lessp)) + (with-current-buffer standard-output + ;; Record which part of the buffer we are completing + ;; so that choosing a completion from the list + ;; knows how much old text to replace. + ;; This was briefly nil in the non-dirname case. + ;; However, if one calls PC-lisp-complete-symbol + ;; on "(ne-f" with point on the hyphen, PC offers + ;; all completions starting with "(ne", some of + ;; which do not match the "-f" part (maybe it + ;; should not, but it does). In such cases, + ;; completion gets confused trying to figure out + ;; how much to replace, so we tell it explicitly + ;; (ie, the number of chars in the buffer before beg). + (setq completion-base-size (if dirname + dirlength + (- beg prompt-end)))))) (PC-temp-minibuffer-message " [Next char not unique]")) nil))))) @@ -799,6 +811,8 @@ (setq quit-flag nil unread-command-events '(7)))))))) +(defvar PC-lisp-complete-end nil + "Internal variable used by `PC-lisp-complete-symbol'.") (defun PC-lisp-complete-symbol () "Perform completion on Lisp symbol preceding point. @@ -825,7 +839,37 @@ (or (boundp sym) (fboundp sym) (symbol-plist sym)))))) (PC-not-minibuffer t)) - (PC-do-completion nil beg end))) + ;; http://lists.gnu.org/archive/html/emacs-devel/2007-03/msg01211.html + ;; + ;; This deals with cases like running PC-l-c-s on "M-: (n-f". + ;; The first call to PC-l-c-s expands this to "(ne-f", and moves + ;; point to the hyphen [1]. If one calls PC-l-c-s immediately after, + ;; then without the last-command check, one is offered all + ;; completions of "(ne", which is presumably not what one wants. + ;; + ;; This is arguably (at least, it seems to be the existing intended + ;; behaviour) what one _does_ want if point has been explicitly + ;; positioned on the hyphen. Note that if PC-do-completion (qv) binds + ;; completion-base-size to nil, then completion does not replace the + ;; correct amount of text in such cases. + ;; + ;; Neither of these problems occur when using PC for filenames in the + ;; minibuffer, because in that case PC-do-completion is called without + ;; an explicit value for END, and so uses (point-max). This is fine for + ;; a filename, because the end of the filename must be at the end of + ;; the minibuffer. The same is not true for lisp symbols. + ;; + ;; [1] An alternate fix would be to not move point to the hyphen + ;; in such cases, but that would make the behaviour different from + ;; that for filenames. It seems PC moves point to the site of the + ;; first difference between the possible completions. + ;; + ;; Alternatively alternatively, maybe end should be computed in + ;; the same way as beg. That would change the behaviour though. + (if (equal last-command 'PC-lisp-complete-symbol) + (PC-do-completion nil beg PC-lisp-complete-end) + (setq PC-lisp-complete-end (point-marker)) + (PC-do-completion nil beg end)))) (defun PC-complete-as-file-name () "Perform completion on file names preceding point.