b2b828b56cb2f55e006108ba77641f5dd3ae3f65
[chise/xemacs-chise.git.1] / lisp / list-mode.el
1 ;;; list-mode.el --- Major mode for buffers containing lists of items
2
3 ;; Copyright (C) 1992-4, 1997 Free Software Foundation, Inc.
4 ;; Copyright (C) 1996 Ben Wing.
5  
6 ;; Maintainer: XEmacs Development Team
7 ;; Keywords: extensions, dumped
8
9 ;; This file is part of XEmacs.
10
11 ;; XEmacs is free software; you can redistribute it and/or modify it
12 ;; under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15
16 ;; XEmacs is distributed in the hope that it will be useful, but
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 ;; General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with XEmacs; see the file COPYING.  If not, write to the 
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
25
26 ;;; Synched up with: Not synched
27
28 ;;; Commentary:
29
30 ;; This file is dumped with XEmacs.
31
32 ;; Cleanup, merging with FSF by Ben Wing, January 1996
33
34 ;;; Code:
35
36 (defvar list-mode-extent nil)
37 (make-variable-buffer-local 'list-mode-extent)
38
39 (defvar list-mode-map nil
40   "Local map for buffers containing lists of items.")
41 (or list-mode-map
42     (let ((map (setq list-mode-map (make-sparse-keymap 'list-mode-map))))
43       (suppress-keymap map)
44       (define-key map 'button2up 'list-mode-item-mouse-selected)
45       (define-key map 'button2 'undefined)
46       (define-key map "\C-m" 'list-mode-item-keyboard-selected)
47 ;;
48 ;; The following calls to `substitute-key-definition' losed because
49 ;; they were based on an incorrect assumption that `forward-char' and
50 ;; `backward-char' are bound to keys in the global map. This might not
51 ;; be the case if a user binds motion keys to different functions,
52 ;; and was not actually the case since 20.5 beta 28 or around.
53 ;;
54 ;;    (substitute-key-definition 'forward-char 'next-list-mode-item map
55 ;;                               global-map)
56 ;;    (substitute-key-definition 'backward-char 'previous-list-mode-item map
57 ;;                               global-map)
58 ;;
59 ;; We bind standard keys to motion commands instead.
60 ;;
61       (dolist (key '(kp-right right (control ?f)))
62         (define-key map key 'next-list-mode-item))
63       (dolist (key '(kp-left left (control ?b)))
64         (define-key map key 'previous-list-mode-item))))
65
66 (defun list-mode ()
67   "Major mode for buffer containing lists of items."
68   (interactive)
69   (kill-all-local-variables)
70   (use-local-map list-mode-map)
71   (setq mode-name "List")
72   (setq major-mode 'list-mode)
73   (make-local-hook 'post-command-hook)
74   (add-hook 'post-command-hook 'set-list-mode-extent nil t)
75   (make-local-hook 'pre-command-hook)
76   (add-hook 'pre-command-hook 'list-mode-extent-pre-hook nil t)
77   (make-local-variable 'next-line-add-newlines)
78   (setq next-line-add-newlines nil)
79   (setq list-mode-extent nil)
80 ;; It is visually disconcerting to have the text cursor disappear within list 
81 ;; buffers, especially when moving from window to window, so leave it
82 ;; visible.  -- Bob Weiner, 06/20/1999
83 ; (set-specifier text-cursor-visible-p nil (current-buffer))
84   (setq buffer-read-only t)
85   (goto-char (point-min))
86   (run-hooks 'list-mode-hook))
87
88 ;; List mode is suitable only for specially formatted data.
89 (put 'list-mode 'mode-class 'special)
90
91 (defvar list-mode-extent-old-point nil
92   "The value of point when pre-command-hook is called.
93 Used to determine the direction of motion.")
94 (make-variable-buffer-local 'list-mode-extent-old-point)
95
96 (defun list-mode-extent-pre-hook ()
97   (setq list-mode-extent-old-point (point))
98   ;(setq atomic-extent-goto-char-p nil)
99 )
100
101 (defun set-list-mode-extent ()
102   "Move to the closest list item and set up the extent for it.
103 This is called from `post-command-hook'."
104   (cond ((get-char-property (point) 'list-mode-item))
105         ((and (> (point) (point-min))
106               (get-char-property (1- (point)) 'list-mode-item))
107          (goto-char (1- (point))))
108         (t
109          (let ((pos (point))
110                dirflag)
111            ;this fucks things up more than it helps.
112            ;atomic-extent-goto-char-p as currently defined is all broken,
113            ;since it will be triggered if the command *ever* runs goto-char!
114            ;(if atomic-extent-goto-char-p
115            ;    (setq dirflag 1)
116            (if (and list-mode-extent-old-point
117                     (> pos list-mode-extent-old-point))
118                (setq dirflag 1)
119              (setq dirflag -1))
120            (next-list-mode-item dirflag)
121            (or (get-char-property (point) 'list-mode-item)
122                (next-list-mode-item (- dirflag))))))
123   (or (and list-mode-extent
124            (eq (current-buffer) (extent-object list-mode-extent)))
125       (progn
126         (setq list-mode-extent (make-extent nil nil (current-buffer)))
127         (set-extent-face list-mode-extent 'list-mode-item-selected)))
128   (let ((ex (extent-at (point) nil 'list-mode-item nil 'at)))
129     (if ex
130         (progn
131           (set-extent-endpoints list-mode-extent
132                                 (extent-start-position ex)
133                                 (extent-end-position ex))
134           (auto-show-make-region-visible (extent-start-position ex)
135                                          (extent-end-position ex)))
136       (detach-extent list-mode-extent))))
137
138 (defun previous-list-mode-item (n)
139   "Move to the previous item in list-mode."
140   (interactive "p")
141   (next-list-mode-item (- n)))
142
143 (defun next-list-mode-item (n)
144   "Move to the next item in list-mode.
145 With prefix argument N, move N items (negative N means move backward)."
146   (interactive "p")
147   (while (and (> n 0) (not (eobp)))
148     (let ((extent (extent-at (point) (current-buffer) 'list-mode-item))
149           (end (point-max)))
150       ;; If in a completion, move to the end of it.
151       (if extent (goto-char (extent-end-position extent)))
152       ;; Move to start of next one.
153       (or (extent-at (point) (current-buffer) 'list-mode-item)
154           (goto-char (next-single-property-change (point) 'list-mode-item
155                                                   nil end))))
156     (setq n (1- n)))
157   (while (and (< n 0) (not (bobp)))
158     (let ((extent (extent-at (point) (current-buffer) 'list-mode-item))
159           (end (point-min)))
160       ;; If in a completion, move to the start of it.
161       (if extent (goto-char (extent-start-position extent)))
162       ;; Move to the start of that one.
163       (if (setq extent (extent-at (point) (current-buffer) 'list-mode-item
164                                   nil 'before))
165           (goto-char (extent-start-position extent))
166         (goto-char (previous-single-property-change
167                     (point) 'list-mode-item nil end))
168         (if (setq extent (extent-at (point) (current-buffer) 'list-mode-item
169                                     nil 'before))
170             (goto-char (extent-start-position extent)))))
171     (setq n (1+ n))))
172
173 (defun list-mode-item-selected-1 (extent event)
174   (let ((func (extent-property extent 'list-mode-item-activate-callback))
175         (user-data (extent-property extent 'list-mode-item-user-data)))
176     (if func
177         (funcall func event extent user-data))))
178
179 ;; we could make these two be just one function, but we want to be
180 ;; able to refer to them in DOC strings.
181
182 (defun list-mode-item-keyboard-selected ()
183   (interactive)
184   (list-mode-item-selected-1 (extent-at (point) (current-buffer)
185                                         'list-mode-item nil 'at)
186                              nil))
187
188 (defun list-mode-item-mouse-selected (event)
189   (interactive "e")
190   ;; Sometimes event-closest-point returns nil.
191   ;; So beep instead of bombing.
192   (let ((point (event-closest-point event)))
193     (if point
194         (list-mode-item-selected-1 (extent-at point
195                                               (event-buffer event)
196                                               'list-mode-item nil 'at)
197                                    event)
198       (ding))))
199
200 (defun add-list-mode-item (start end &optional buffer activate-callback
201                                  user-data)
202   "Add a new list item in list-mode, from START to END in BUFFER.
203 BUFFER defaults to the current buffer.
204 This works by creating an extent for the span of text in question.
205 If ACTIVATE-CALLBACK is non-nil, it should be a function of three
206   arguments (EVENT EXTENT USER-DATA) that will be called when button2
207   is pressed on the extent.  USER-DATA comes from the optional
208   USER-DATA argument."
209   (let ((extent (make-extent start end buffer)))
210     (set-extent-property extent 'list-mode-item t)
211     (set-extent-property extent 'start-open t)
212     (if activate-callback
213         (progn
214           (set-extent-property extent 'mouse-face 'highlight)
215           (set-extent-property extent 'list-mode-item-activate-callback
216                                activate-callback)
217           (set-extent-property extent 'list-mode-item-user-data user-data)))
218     extent))
219
220 \f
221 ;; Define the major mode for lists of completions.
222
223
224 (defvar completion-highlight-first-word-only nil
225   "*Completion will only highlight the first blank delimited word if t.
226 If the variable in not t or nil, the string is taken as a regexp to match for end
227 of highlight")
228
229 (defvar completion-setup-hook nil
230   "Normal hook run at the end of setting up the text of a completion buffer.")
231
232 ; Unnecessary FSFmacs crock.  We frob the extents directly in
233 ; display-completion-list, so no "heuristics" like this are necessary.
234 ;(defvar completion-fixup-function nil
235 ;  "A function to customize how completions are identified in completion lists.
236 ;`completion-setup-function' calls this function with no arguments
237 ;each time it has found what it thinks is one completion.
238 ;Point is at the end of the completion in the completion list buffer.
239 ;If this function moves point, it can alter the end of that completion.")
240
241 (defvar completion-default-help-string
242   '(concat
243     (if (device-on-window-system-p)
244         (substitute-command-keys
245          "Click \\<list-mode-map>\\[list-mode-item-mouse-selected] on a completion to select it.\n") "")
246     (substitute-command-keys
247      "Type \\<minibuffer-local-completion-map>\\[advertised-switch-to-completions] or \\[switch-to-completions] to move to this buffer, for keyboard selection.\n\n"))
248   "Form the evaluate to get a help string for completion lists.
249 This string is inserted at the beginning of the buffer.
250 See `display-completion-list'.")
251
252 (defun display-completion-list (completions &rest cl-keys)
253   "Display the list of completions, COMPLETIONS, using `standard-output'.
254 Each element may be just a symbol or string or may be a list of two
255  strings to be printed as if concatenated.
256 Frob a mousable extent onto each completion.  This extent has properties
257  'mouse-face (so it highlights when the mouse passes over it) and
258  'list-mode-item (so it can be located).
259
260 Keywords:
261   :activate-callback (default is `default-choose-completion')
262     See `add-list-mode-item'.
263   :user-data
264     Value passed to activation callback.
265   :window-width
266     If non-nil, width to use in displaying the list, instead of the
267     actual window's width.
268   :help-string (default is the value of `completion-default-help-string')
269     Form to evaluate to get a string to insert at the beginning of
270     the completion list buffer.  This is evaluated when that buffer
271     is the current buffer and after it has been put into
272     completion-list-mode.
273   :reference-buffer (default is the current buffer)
274     This specifies the value of `completion-reference-buffer' in
275     the completion buffer.  This specifies the buffer (normally a
276     minibuffer) that `default-choose-completion' will insert the
277     completion into.
278
279 At the end, run the normal hook `completion-setup-hook'.
280 It can find the completion buffer in `standard-output'.
281 If `completion-highlight-first-word-only' is non-nil, then only the start
282  of the string is highlighted."
283    ;; #### I18N3 should set standard-output to be (temporarily)
284    ;; output-translating.
285   (cl-parsing-keywords
286       ((:activate-callback 'default-choose-completion)
287        :user-data
288        :reference-buffer
289        (:help-string completion-default-help-string)
290        (:completion-string "Possible completions are:")
291        :window-width)
292       ()
293     (let ((old-buffer (current-buffer))
294           (bufferp (bufferp standard-output)))
295       (if bufferp
296           (set-buffer standard-output))
297       (if (null completions)
298           (princ (gettext
299                   "There are no possible completions of what you have typed."))
300         (let ((win-width
301                (or cl-window-width
302                    (if bufferp
303                        ;; This needs fixing for the case of windows 
304                        ;; that aren't the same width's the frame.
305                        ;; Sadly, the window it will appear in is not known
306                        ;; until after the text has been made.
307
308                        ;; We have to use last-nonminibuf-frame here
309                        ;; and not selected-frame because if a
310                        ;; minibuffer-only frame is being used it will
311                        ;; be the selected-frame at the point this is
312                        ;; run.  We keep the selected-frame call around
313                        ;; just in case.
314                        (frame-width (or (last-nonminibuf-frame)
315                                         (selected-frame)))
316                      80))))
317           (let ((count 0)
318                 (max-width 0))
319             ;; Find longest completion
320             (let ((tail completions))
321               (while tail
322                 (let* ((elt (car tail))
323                        (len (cond ((stringp elt)
324                                    (length elt))
325                                   ((and (consp elt)
326                                         (stringp (car elt))
327                                         (stringp (car (cdr elt))))
328                                    (+ (length (car elt))
329                                       (length (car (cdr elt)))))
330                                   (t
331                                    (signal 'wrong-type-argument
332                                            (list 'stringp elt))))))
333                   (if (> len max-width)
334                       (setq max-width len))
335                   (setq count (1+ count)
336                         tail (cdr tail)))))
337         
338             (setq max-width (+ 2 max-width)) ; at least two chars between cols
339             (let ((rows (let ((cols (min (/ win-width max-width) count)))
340                           (if (<= cols 1)
341                               count
342                             (progn
343                               ;; re-space the columns
344                               (setq max-width (/ win-width cols))
345                               (if (/= (% count cols) 0) ; want ceiling...
346                                   (1+ (/ count cols))
347                                 (/ count cols)))))))
348               (if (stringp cl-completion-string)
349                   (princ (gettext cl-completion-string)))
350               (let ((tail completions)
351                     (r 0)
352                     (regexp-string
353                      (if (eq t
354                              completion-highlight-first-word-only)
355                          "[ \t]"
356                        completion-highlight-first-word-only)))
357                 (while (< r rows)
358                   (terpri)
359                   (let ((indent 0)
360                         (column 0)
361                         (tail2 tail))
362                     (while tail2
363                       (let ((elt (car tail2)))
364                         (if (/= indent 0)
365                             (if bufferp
366                                 (indent-to indent 2)
367                               (while (progn (write-char ?\ )
368                                             (setq column (1+ column))
369                                             (< column indent)))))
370                         (setq indent (+ indent max-width))
371                         (let ((start (point))
372                               end)
373                           ;; Frob some mousable extents in there too!
374                           (if (consp elt)
375                               (progn
376                                 (princ (car elt))
377                                 (princ (car (cdr elt)))
378                                 (or bufferp
379                                     (setq column
380                                           (+ column
381                                              (length (car elt))
382                                              (length (car (cdr elt)))))))
383                             (progn
384                               (princ elt)
385                               (or bufferp
386                                   (setq column (+ column (length
387                                                           elt))))))
388                           (add-list-mode-item
389                            start
390                            (progn
391                              (setq end (point))
392                              (or
393                               (and completion-highlight-first-word-only
394                                    (goto-char start)
395                                    (re-search-forward regexp-string end t)
396                                    (match-beginning 0))
397                               end))
398                            nil cl-activate-callback cl-user-data)
399                           (goto-char end)))
400                       (setq tail2 (nthcdr rows tail2)))
401                     (setq tail (cdr tail)
402                           r (1+ r)))))))))
403       (if bufferp
404           (set-buffer old-buffer)))
405     (save-excursion
406       (let ((mainbuf (or cl-reference-buffer (current-buffer))))
407         (set-buffer standard-output)
408         (completion-list-mode)
409         (make-local-variable 'completion-reference-buffer)
410         (setq completion-reference-buffer mainbuf)
411 ;;; The value 0 is right in most cases, but not for file name completion.
412 ;;; so this has to be turned off.
413 ;;;      (setq completion-base-size 0)
414         (goto-char (point-min))
415         (let ((buffer-read-only nil))
416           (insert (eval cl-help-string)))
417           ;; unnecessary FSFmacs crock
418           ;;(forward-line 1)
419           ;;(while (re-search-forward "[^ \t\n]+\\( [^ \t\n]+\\)*" nil t)
420           ;;      (let ((beg (match-beginning 0))
421           ;;            (end (point)))
422           ;;        (if completion-fixup-function
423           ;;            (funcall completion-fixup-function))
424           ;;        (put-text-property beg (point) 'mouse-face 'highlight)
425           ;;        (put-text-property beg (point) 'list-mode-item t)
426           ;;        (goto-char end)))))
427         ))
428     (run-hooks 'completion-setup-hook)))
429
430 (defvar completion-display-completion-list-function 'display-completion-list
431   "Function to set up the list of completions in the completion buffer.
432 The function is called with one argument, the sorted list of completions.
433 Particular minibuffer interface functions (e.g. `read-file-name') may
434 want to change this.  To do that, set a local value for this variable
435 in the minibuffer; that ensures that other minibuffer invocations will
436 not be affected.")
437
438 (defun minibuffer-completion-help ()
439   "Display a list of possible completions of the current minibuffer contents.
440 The list of completions is determined by calling `all-completions',
441 passing it the current minibuffer contents, the value of
442 `minibuffer-completion-table', and the value of
443 `minibuffer-completion-predicate'.  The list is displayed by calling
444 the value of `completion-display-completion-list-function' on the sorted
445 list of completions, with the standard output set to the completion
446 buffer."
447   (interactive)
448   (message "Making completion list...")
449   (let ((completions (all-completions (buffer-string)
450                                       minibuffer-completion-table
451                                       minibuffer-completion-predicate)))
452     (message nil)
453     (if (null completions)
454         (progn
455           (ding nil 'no-completion)
456           (temp-minibuffer-message " [No completions]"))
457         (with-output-to-temp-buffer "*Completions*"
458           (funcall completion-display-completion-list-function
459                    (sort completions #'string-lessp))))))
460
461 (define-derived-mode completion-list-mode list-mode 
462   "Completion List"
463   "Major mode for buffers showing lists of possible completions.
464 \\{completion-list-mode-map}"
465   (make-local-variable 'completion-base-size)
466   (setq completion-base-size nil))
467
468 (let ((map completion-list-mode-map))
469   (define-key map 'button2up 'mouse-choose-completion)
470   (define-key map 'button2 'undefined)
471   (define-key map "\C-m" 'choose-completion)
472   (define-key map "\e\e\e" 'delete-completion-window)
473   (define-key map "\C-g" 'minibuffer-keyboard-quit)
474   (define-key map "q" 'completion-list-mode-quit)
475   (define-key map " " 'completion-switch-to-minibuffer)
476   ;; [Tab] used to switch to the minibuffer but since [space] does that and
477   ;; since most applications in the world use [Tab] to select the next item
478   ;; in a list, do that in the *Completions* buffer too.  -- Bob Weiner,
479   ;; BeOpen.com, 06/23/1999.
480   (define-key map "\t" 'next-list-mode-item))
481
482 (defvar completion-reference-buffer nil
483   "Record the buffer that was current when the completion list was requested.
484 This is a local variable in the completion list buffer.
485 Initial value is nil to avoid some compiler warnings.")
486
487 (defvar completion-base-size nil
488   "Number of chars at beginning of minibuffer not involved in completion.
489 This is a local variable in the completion list buffer
490 but it talks about the buffer in `completion-reference-buffer'.
491 If this is nil, it means to compare text to determine which part
492 of the tail end of the buffer's text is involved in completion.")
493
494 ;; These names are referenced in the doc string for `completion-list-mode'.
495 (defalias 'choose-completion 'list-mode-item-keyboard-selected)
496 (defalias 'mouse-choose-completion 'list-mode-item-mouse-selected)
497
498 (defun delete-completion-window ()
499   "Delete the completion list window.
500 Go to the window from which completion was requested."
501   (interactive)
502   (let ((buf completion-reference-buffer))
503     (delete-window (selected-window))
504     (if (get-buffer-window buf)
505          (select-window (get-buffer-window buf)))))
506
507 (defun completion-switch-to-minibuffer ()
508   "Move from a completions buffer to the active minibuffer window."
509   (interactive)
510   (select-window (minibuffer-window)))
511
512 (defun completion-list-mode-quit ()
513   "Abort any recursive edit and bury the completions buffer."
514   (interactive)
515   (condition-case ()
516       (abort-recursive-edit)
517     (error nil))
518   ;; If there was no recursive edit to abort, simply bury the completions
519   ;; list buffer.
520   (if (eq major-mode 'completion-list-mode) (bury-buffer)))
521
522 (defun completion-do-in-minibuffer ()
523   (interactive "_")
524   (save-excursion
525     (set-buffer (window-buffer (minibuffer-window)))
526     (call-interactively (key-binding (this-command-keys)))))
527
528 (defun default-choose-completion (event extent buffer)
529   "Click on an alternative in the `*Completions*' buffer to choose it."
530   (and (button-event-p event)
531        ;; Give temporary modes such as isearch a chance to turn off.
532        (run-hooks 'mouse-leave-buffer-hook))
533   (or buffer (setq buffer (symbol-value-in-buffer
534                            'completion-reference-buffer
535                            (or (and (button-event-p event)
536                                     (event-buffer event))
537                                (current-buffer)))))
538   (save-selected-window
539    (and (button-event-p event)
540         (select-window (event-window event)))
541    (if (and (one-window-p t 'selected-frame)
542             (window-dedicated-p (selected-window)))
543        ;; This is a special buffer's frame
544        (iconify-frame (selected-frame))
545      (or (window-dedicated-p (selected-window))
546          (bury-buffer))))
547   (choose-completion-string (extent-string extent)
548                             buffer
549                             completion-base-size))
550
551 ;; Delete the longest partial match for STRING
552 ;; that can be found before POINT.
553 (defun choose-completion-delete-max-match (string)
554   (let ((len (min (length string)
555                   (- (point) (point-min)))))
556     (goto-char (- (point) (length string)))
557     (if completion-ignore-case
558          (setq string (downcase string)))
559     (while (and (> len 0)
560                  (let ((tail (buffer-substring (point)
561                                                (+ (point) len))))
562                    (if completion-ignore-case
563                        (setq tail (downcase tail)))
564                    (not (string= tail (substring string 0 len)))))
565       (setq len (1- len))
566       (forward-char 1))
567     (delete-char len)))
568
569 ;; Switch to BUFFER and insert the completion choice CHOICE.
570 ;; BASE-SIZE, if non-nil, says how many characters of BUFFER's text
571 ;; to keep.  If it is nil, use choose-completion-delete-max-match instead.
572 (defun choose-completion-string (choice &optional buffer base-size)
573   (let ((buffer (or buffer completion-reference-buffer)))
574     ;; If BUFFER is a minibuffer, barf unless it's the currently
575     ;; active minibuffer.
576     (if (and (string-match "\\` \\*Minibuf-[0-9]+\\*\\'" (buffer-name buffer))
577               (or (not (active-minibuffer-window))
578                   (not (equal buffer
579                               (window-buffer (active-minibuffer-window))))))
580          (error "Minibuffer is not active for completion")
581       ;; Insert the completion into the buffer where completion was requested.
582       (set-buffer buffer)
583       (if base-size
584            (delete-region (+ base-size (point-min)) (point))
585          (choose-completion-delete-max-match choice))
586       (insert choice)
587       (remove-text-properties (- (point) (length choice)) (point)
588                                '(highlight nil))
589       ;; Update point in the window that BUFFER is showing in.
590       (let ((window (get-buffer-window buffer t)))
591          (set-window-point window (point)))
592       ;; If completing for the minibuffer, exit it with this choice.
593       (and (equal buffer (window-buffer (minibuffer-window)))
594             minibuffer-completion-table
595             (exit-minibuffer)))))
596
597 (define-key minibuffer-local-completion-map [prior]
598   'switch-to-completions)
599 (define-key minibuffer-local-must-match-map [prior]
600   'switch-to-completions)
601 (define-key minibuffer-local-completion-map "\M-v"
602   'advertised-switch-to-completions)
603 (define-key minibuffer-local-must-match-map "\M-v"
604   'advertised-switch-to-completions)
605
606 (defalias 'advertised-switch-to-completions 'switch-to-completions)
607 (defun switch-to-completions ()
608   "Select the completion list window."
609   (interactive)
610   ;; Make sure we have a completions window.
611   (or (get-buffer-window "*Completions*")
612       (minibuffer-completion-help))
613   (if (not (get-buffer-window "*Completions*"))
614       nil
615     (select-window (get-buffer-window "*Completions*"))
616     (goto-char (next-single-property-change (point-min) 'list-mode-item nil
617                                             (point-max)))))
618
619 ;;; list-mode.el ends here