comparison lisp/list-mode.el @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents 2f8bb876ab1d
children 41dbb7a9d5f2
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
1 ;;; list-mode.el --- Major mode for buffers containing lists of items 1 ;;; list-mode.el --- Major mode for buffers containing lists of items
2 2
3 ;; Copyright (C) 1992-4, 1997 Free Software Foundation, Inc. 3 ;; Copyright (C) 1992-4, 1997 Free Software Foundation, Inc.
4 ;; Copyright (C) 1996, 2000 Ben Wing. 4 ;; Copyright (C) 1996 Ben Wing.
5 5
6 ;; Maintainer: XEmacs Development Team 6 ;; Maintainer: XEmacs Development Team
7 ;; Keywords: extensions, dumped 7 ;; Keywords: extensions, dumped
8 8
9 ;; This file is part of XEmacs. 9 ;; This file is part of XEmacs.
61 (dolist (key '(kp-right right (control ?f))) 61 (dolist (key '(kp-right right (control ?f)))
62 (define-key map key 'next-list-mode-item)) 62 (define-key map key 'next-list-mode-item))
63 (dolist (key '(kp-left left (control ?b))) 63 (dolist (key '(kp-left left (control ?b)))
64 (define-key map key 'previous-list-mode-item)))) 64 (define-key map key 'previous-list-mode-item))))
65 65
66 ;; #### We make list-mode-hook, as well as completion-setup-hook and
67 ;; minibuffer-setup-hook, permanent-local so that it's possible to create
68 ;; buffers in these modes and then set up some buffer-specific
69 ;; customizations without resorting to awful kludges. (The problem here
70 ;; is that when you switch a buffer into a mode, reset-buffer is usually
71 ;; called, which destroys all buffer-local settings that you carefully
72 ;; tried to set up when you created the buffer. Therefore, the only way
73 ;; to set these variables is to use the setup hooks -- but if they are
74 ;; not declared permanent local, then any local hook functions that you
75 ;; put on them (which is exactly what you want to do) also get removed,
76 ;; so you would have to resort to putting a global hook function on the
77 ;; setup hook, and then making sure it gets removed later. I actually
78 ;; added some support for doing this with one-shot hooks, but this is
79 ;; clearly not the correct way to do things, and it fails in some cases,
80 ;; particularly when the buffer gets put into the mode more than once,
81 ;; which typically happens with completion buffers, for example.) In
82 ;; fact, all setup hooks should be made permanent local, but I didn't
83 ;; feel like making a global change like this quite yet. The proper way
84 ;; to do it would be to declare new def-style forms, such as defhook and
85 ;; define-local-setup-hook, which are used to initialize hooks in place
86 ;; of the current generic defvars. --ben
87
88 (put 'list-mode-hook 'permanent-local t)
89 (defvar list-mode-hook nil
90 "Normal hook run when entering List mode.")
91
92 (defun list-mode () 66 (defun list-mode ()
93 "Major mode for buffer containing lists of items." 67 "Major mode for buffer containing lists of items."
94 (interactive) 68 (interactive)
95 (kill-all-local-variables) 69 (kill-all-local-variables)
96 (use-local-map list-mode-map) 70 (use-local-map list-mode-map)
97 (setq mode-name "List") 71 (setq mode-name "List")
98 (setq major-mode 'list-mode) 72 (setq major-mode 'list-mode)
99 (add-local-hook 'post-command-hook 'set-list-mode-extent) 73 (make-local-hook 'post-command-hook)
100 (add-local-hook 'pre-command-hook 'list-mode-extent-pre-hook) 74 (add-hook 'post-command-hook 'set-list-mode-extent nil t)
101 (set (make-local-variable 'next-line-add-newlines) nil) 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)
102 (setq list-mode-extent nil) 79 (setq list-mode-extent nil)
103 ;; It is visually disconcerting to have the text cursor disappear within list 80 (set-specifier text-cursor-visible-p nil (current-buffer))
104 ;; buffers, especially when moving from window to window, so leave it
105 ;; visible. -- Bob Weiner, 06/20/1999
106 ; (set-specifier text-cursor-visible-p nil (current-buffer))
107 (setq buffer-read-only t) 81 (setq buffer-read-only t)
108 (goto-char (point-min)) 82 (goto-char (point-min))
109 (run-hooks 'list-mode-hook)) 83 (run-hooks 'list-mode-hook))
110 84
111 ;; List mode is suitable only for specially formatted data. 85 ;; List mode is suitable only for specially formatted data.
247 (defvar completion-highlight-first-word-only nil 221 (defvar completion-highlight-first-word-only nil
248 "*Completion will only highlight the first blank delimited word if t. 222 "*Completion will only highlight the first blank delimited word if t.
249 If the variable in not t or nil, the string is taken as a regexp to match for end 223 If the variable in not t or nil, the string is taken as a regexp to match for end
250 of highlight") 224 of highlight")
251 225
252 ;; see comment at list-mode-hook.
253 (put 'completion-setup-hook 'permanent-local t)
254 (defvar completion-setup-hook nil 226 (defvar completion-setup-hook nil
255 "Normal hook run at the end of setting up the text of a completion buffer. 227 "Normal hook run at the end of setting up the text of a completion buffer.")
256 When run, the completion buffer is the current buffer.")
257 228
258 ; Unnecessary FSFmacs crock. We frob the extents directly in 229 ; Unnecessary FSFmacs crock. We frob the extents directly in
259 ; display-completion-list, so no "heuristics" like this are necessary. 230 ; display-completion-list, so no "heuristics" like this are necessary.
260 ;(defvar completion-fixup-function nil 231 ;(defvar completion-fixup-function nil
261 ; "A function to customize how completions are identified in completion lists. 232 ; "A function to customize how completions are identified in completion lists.
289 :user-data 260 :user-data
290 Value passed to activation callback. 261 Value passed to activation callback.
291 :window-width 262 :window-width
292 If non-nil, width to use in displaying the list, instead of the 263 If non-nil, width to use in displaying the list, instead of the
293 actual window's width. 264 actual window's width.
294 :window-height
295 If non-nil, use no more than this many lines, and extend line width as
296 necessary.
297 :help-string (default is the value of `completion-default-help-string') 265 :help-string (default is the value of `completion-default-help-string')
298 Form to evaluate to get a string to insert at the beginning of 266 Form to evaluate to get a string to insert at the beginning of
299 the completion list buffer. This is evaluated when that buffer 267 the completion list buffer. This is evaluated when that buffer
300 is the current buffer and after it has been put into 268 is the current buffer and after it has been put into
301 completion-list-mode. 269 completion-list-mode.
315 ((:activate-callback 'default-choose-completion) 283 ((:activate-callback 'default-choose-completion)
316 :user-data 284 :user-data
317 :reference-buffer 285 :reference-buffer
318 (:help-string completion-default-help-string) 286 (:help-string completion-default-help-string)
319 (:completion-string "Possible completions are:") 287 (:completion-string "Possible completions are:")
320 :window-width 288 :window-width)
321 :window-height)
322 () 289 ()
323 (let ((old-buffer (current-buffer)) 290 (let ((old-buffer (current-buffer))
324 (bufferp (bufferp standard-output))) 291 (bufferp (bufferp standard-output)))
325 (if bufferp 292 (if bufferp
326 (set-buffer standard-output)) 293 (set-buffer standard-output))
343 ;; just in case. 310 ;; just in case.
344 (frame-width (or (last-nonminibuf-frame) 311 (frame-width (or (last-nonminibuf-frame)
345 (selected-frame))) 312 (selected-frame)))
346 80)))) 313 80))))
347 (let ((count 0) 314 (let ((count 0)
348 (max-width 0) 315 (max-width 0))
349 old-max-width)
350 ;; Find longest completion 316 ;; Find longest completion
351 (let ((tail completions)) 317 (let ((tail completions))
352 (while tail 318 (while tail
353 (let* ((elt (car tail)) 319 (let* ((elt (car tail))
354 (len (cond ((stringp elt) 320 (len (cond ((stringp elt)
365 (setq max-width len)) 331 (setq max-width len))
366 (setq count (1+ count) 332 (setq count (1+ count)
367 tail (cdr tail))))) 333 tail (cdr tail)))))
368 334
369 (setq max-width (+ 2 max-width)) ; at least two chars between cols 335 (setq max-width (+ 2 max-width)) ; at least two chars between cols
370 (setq old-max-width max-width)
371 (let ((rows (let ((cols (min (/ win-width max-width) count))) 336 (let ((rows (let ((cols (min (/ win-width max-width) count)))
372 (if (<= cols 1) 337 (if (<= cols 1)
373 count 338 count
374 (progn 339 (progn
375 ;; re-space the columns 340 ;; re-space the columns
376 (setq max-width (/ win-width cols)) 341 (setq max-width (/ win-width cols))
377 (if (/= (% count cols) 0) ; want ceiling... 342 (if (/= (% count cols) 0) ; want ceiling...
378 (1+ (/ count cols)) 343 (1+ (/ count cols))
379 (/ count cols))))))) 344 (/ count cols)))))))
380 (when 345 (if (stringp cl-completion-string)
381 (and cl-window-height 346 (princ (gettext cl-completion-string)))
382 (> rows cl-window-height))
383 (setq max-width old-max-width)
384 (setq rows cl-window-height))
385 (when (and (stringp cl-completion-string)
386 (> (length cl-completion-string) 0))
387 (princ (gettext cl-completion-string))
388 (terpri))
389 (let ((tail completions) 347 (let ((tail completions)
390 (r 0) 348 (r 0)
391 (regexp-string 349 (regexp-string
392 (if (eq t 350 (if (eq t
393 completion-highlight-first-word-only) 351 completion-highlight-first-word-only)
394 "[ \t]" 352 "[ \t]"
395 completion-highlight-first-word-only))) 353 completion-highlight-first-word-only)))
396 (while (< r rows) 354 (while (< r rows)
397 (and (> r 0) (terpri)) 355 (terpri)
398 (let ((indent 0) 356 (let ((indent 0)
399 (column 0) 357 (column 0)
400 (tail2 tail)) 358 (tail2 tail))
401 (while tail2 359 (while tail2
402 (let ((elt (car tail2))) 360 (let ((elt (car tail2)))
462 ;; (funcall completion-fixup-function)) 420 ;; (funcall completion-fixup-function))
463 ;; (put-text-property beg (point) 'mouse-face 'highlight) 421 ;; (put-text-property beg (point) 'mouse-face 'highlight)
464 ;; (put-text-property beg (point) 'list-mode-item t) 422 ;; (put-text-property beg (point) 'list-mode-item t)
465 ;; (goto-char end))))) 423 ;; (goto-char end)))))
466 )) 424 ))
467 (save-excursion 425 (run-hooks 'completion-setup-hook)))
468 (set-buffer standard-output)
469 (run-hooks 'completion-setup-hook))))
470 426
471 (defvar completion-display-completion-list-function 'display-completion-list 427 (defvar completion-display-completion-list-function 'display-completion-list
472 "Function to set up the list of completions in the completion buffer. 428 "Function to set up the list of completions in the completion buffer.
473 The function is called with one argument, the sorted list of completions. 429 The function is called with one argument, the sorted list of completions.
474 Particular minibuffer interface functions (e.g. `read-file-name') may 430 Particular minibuffer interface functions (e.g. `read-file-name') may
500 (sort completions #'string-lessp)))))) 456 (sort completions #'string-lessp))))))
501 457
502 (define-derived-mode completion-list-mode list-mode 458 (define-derived-mode completion-list-mode list-mode
503 "Completion List" 459 "Completion List"
504 "Major mode for buffers showing lists of possible completions. 460 "Major mode for buffers showing lists of possible completions.
505 \\{completion-list-mode-map}" 461 Type \\<completion-list-mode-map>\\[choose-completion] in the completion list\
462 to select the completion near point.
463 Use \\<completion-list-mode-map>\\[mouse-choose-completion] to select one\
464 with the mouse."
506 (make-local-variable 'completion-base-size) 465 (make-local-variable 'completion-base-size)
507 (setq completion-base-size nil)) 466 (setq completion-base-size nil))
508 467
509 (let ((map completion-list-mode-map)) 468 (let ((map completion-list-mode-map))
510 (define-key map 'button2up 'mouse-choose-completion)
511 (define-key map 'button2 'undefined)
512 (define-key map "\C-m" 'choose-completion)
513 (define-key map "\e\e\e" 'delete-completion-window) 469 (define-key map "\e\e\e" 'delete-completion-window)
514 (define-key map "\C-g" 'minibuffer-keyboard-quit) 470 (define-key map "\C-g" 'minibuffer-keyboard-quit)
515 (define-key map "q" 'completion-list-mode-quit) 471 (define-key map "q" 'abort-recursive-edit)
516 (define-key map " " 'completion-switch-to-minibuffer) 472 (define-key map " " (lambda () (interactive)
517 ;; [Tab] used to switch to the minibuffer but since [space] does that and 473 (select-window (minibuffer-window))))
518 ;; since most applications in the world use [Tab] to select the next item 474 (define-key map "\t" (lambda () (interactive)
519 ;; in a list, do that in the *Completions* buffer too. -- Bob Weiner, 475 (select-window (minibuffer-window)))))
520 ;; BeOpen.com, 06/23/1999.
521 (define-key map "\t" 'next-list-mode-item))
522 476
523 (defvar completion-reference-buffer nil 477 (defvar completion-reference-buffer nil
524 "Record the buffer that was current when the completion list was requested. 478 "Record the buffer that was current when the completion list was requested.
525 This is a local variable in the completion list buffer. 479 This is a local variable in the completion list buffer.
526 Initial value is nil to avoid some compiler warnings.") 480 Initial value is nil to avoid some compiler warnings.")
529 "Number of chars at beginning of minibuffer not involved in completion. 483 "Number of chars at beginning of minibuffer not involved in completion.
530 This is a local variable in the completion list buffer 484 This is a local variable in the completion list buffer
531 but it talks about the buffer in `completion-reference-buffer'. 485 but it talks about the buffer in `completion-reference-buffer'.
532 If this is nil, it means to compare text to determine which part 486 If this is nil, it means to compare text to determine which part
533 of the tail end of the buffer's text is involved in completion.") 487 of the tail end of the buffer's text is involved in completion.")
534
535 ;; These names are referenced in the doc string for `completion-list-mode'.
536 (defalias 'choose-completion 'list-mode-item-keyboard-selected)
537 (defalias 'mouse-choose-completion 'list-mode-item-mouse-selected)
538 488
539 (defun delete-completion-window () 489 (defun delete-completion-window ()
540 "Delete the completion list window. 490 "Delete the completion list window.
541 Go to the window from which completion was requested." 491 Go to the window from which completion was requested."
542 (interactive) 492 (interactive)
543 (let ((buf completion-reference-buffer)) 493 (let ((buf completion-reference-buffer))
544 (delete-window (selected-window)) 494 (delete-window (selected-window))
545 (if (get-buffer-window buf) 495 (if (get-buffer-window buf)
546 (select-window (get-buffer-window buf))))) 496 (select-window (get-buffer-window buf)))))
547
548 (defun completion-switch-to-minibuffer ()
549 "Move from a completions buffer to the active minibuffer window."
550 (interactive)
551 (select-window (minibuffer-window)))
552
553 (defun completion-list-mode-quit ()
554 "Abort any recursive edit and bury the completions buffer."
555 (interactive)
556 (condition-case ()
557 (abort-recursive-edit)
558 (error nil))
559 ;; If there was no recursive edit to abort, simply bury the completions
560 ;; list buffer.
561 (if (eq major-mode 'completion-list-mode) (bury-buffer)))
562 497
563 (defun completion-do-in-minibuffer () 498 (defun completion-do-in-minibuffer ()
564 (interactive "_") 499 (interactive "_")
565 (save-excursion 500 (save-excursion
566 (set-buffer (window-buffer (minibuffer-window))) 501 (set-buffer (window-buffer (minibuffer-window)))