- (let ((conf (current-window-configuration)))
- (with-output-to-temp-buffer "*Completions*"
- (display-completion-list (sort completions 'string-lessp)))
- (message "Hit space to flush")
- (let (key first)
- (if (save-excursion
- (set-buffer (get-buffer "*Completions*"))
- (setq key (read-key-sequence nil)
- first (aref key 0))
- (and (consp first) (consp (event-start first))
- (eq (window-buffer (posn-window (event-start first)))
- (get-buffer "*Completions*"))
- (eq (key-binding key) 'mouse-choose-completion)))
- ;; If the user does mouse-choose-completion with the mouse,
- ;; execute the command, then delete the completion window.
- (progn
- (mouse-choose-completion first)
- (set-window-configuration conf))
- (if (eq first ?\ )
- (set-window-configuration conf)
- (setq unread-command-events (listify-key-sequence key)))))))
+ (let ((window (get-buffer-window "*Completions*")))
+ (setq completions (sort completions 'string-lessp))
+ (if (and (eq last-command this-command)
+ window (window-live-p window) (window-buffer window)
+ (buffer-name (window-buffer window))
+ ;; The above tests are not sufficient to detect the case where we
+ ;; should scroll, because the top-level interactive command may
+ ;; not have displayed a completions window the last time it was
+ ;; invoked, and there may be such a window left over from a
+ ;; previous completion command with a different set of
+ ;; completions. To detect that case, we also test that the set
+ ;; of displayed completions is in fact the same as the previously
+ ;; displayed set.
+ (equal completions
+ (buffer-local-value 'comint-displayed-dynamic-completions
+ (window-buffer window))))
+ ;; If this command was repeated, and
+ ;; there's a fresh completion window with a live buffer,
+ ;; and this command is repeated, scroll that window.
+ (with-current-buffer (window-buffer window)
+ (if (pos-visible-in-window-p (point-max) window)
+ (set-window-start window (point-min))
+ (save-selected-window
+ (select-window window)
+ (scroll-up))))
+
+ (let ((conf (current-window-configuration)))
+ (with-output-to-temp-buffer "*Completions*"
+ (display-completion-list completions))
+ (message "Type space to flush; repeat completion command to scroll")
+ (let (key first)
+ (if (save-excursion
+ (set-buffer (get-buffer "*Completions*"))
+ (set (make-local-variable
+ 'comint-displayed-dynamic-completions)
+ completions)
+ (setq key (read-key-sequence nil)
+ first (aref key 0))
+ (and (consp first) (consp (event-start first))
+ (eq (window-buffer (posn-window (event-start first)))
+ (get-buffer "*Completions*"))
+ (eq (key-binding key) 'mouse-choose-completion)))
+ ;; If the user does mouse-choose-completion with the mouse,
+ ;; execute the command, then delete the completion window.
+ (progn
+ (mouse-choose-completion first)
+ (set-window-configuration conf))
+ (if (eq first ?\ )
+ (set-window-configuration conf)
+ (setq unread-command-events (listify-key-sequence key)))))))))