1 ;;; hui-mouse.el --- Use key or mouse key for many functions, e.g. Hypb menus.
3 ;; Copyright (C) 1989-1995, 2006, 2008 Free Software Foundation, Inc.
4 ;; Developed with support from Motorola Inc.
6 ;; Author: Bob Weiner, Brown U.
7 ;; Maintainer: Mats Lidell <matsl@contactor.se>
8 ;; Keywords: hypermedia, mouse
10 ;; This file is part of GNU Hyperbole.
12 ;; GNU Hyperbole is free software; you can redistribute it and/or
13 ;; modify it under the terms of the GNU General Public License as
14 ;; published by the Free Software Foundation; either version 3, or (at
15 ;; your option) any later version.
17 ;; GNU Hyperbole is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;; General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
29 ;; This code is machine independent. It works best with a pointing device but
30 ;; may also be used from a keyboard. When used with a pointing device it
31 ;; requires an Emacs command that sets point to the location of the pointing
34 ;; If you want to use your shift-middle mouse button to select Hyperbole menu
35 ;; items and Hyperbole buttons, follow these instructions.
37 ;; If you plan to use a mouse only with X windows (Lucid Emacs, GNU Emacs
38 ;; 19, or Epoch), NEXTSTEP, SunView, Apollo's DM, and you want to use the
39 ;; shift-middle and shift-right buttons, you need not do any mouse
40 ;; configuration. Your Emacs executable must have been built so as to
41 ;; include the mouse support files for your window system, however. These
42 ;; are in the Emacs "src" directory: for X "x*.c", for SunView "sunfns.c",
43 ;; and for Apollo DM "apollo.c" and "apollo.el".
45 ;; To use a different mouse key or a different window system, modify the
46 ;; mouse key bindings in "hmouse-key.el".
48 ;; Using the Action Mouse Key to browse through and delete files from
49 ;; Dired listings is exceptionally nice, just as it is when reading mail.
58 (defvar hmouse-set-point-command nil
59 "*Command that sets point to mouse cursor position.")
61 (defvar action-key-default-function 'hui:menu
62 "*Symbol name of function run by the Action Key in an unspecified context.")
64 (defvar assist-key-default-function 'hkey-summarize
65 "*Symbol name of function run by the Assist Key in an unspecified context.")
68 ;;; Hyperbole context-sensitive keys dispatch table
71 (defvar hkey-value nil
72 "Communicates a value between a Smart Key predicate and its actions.")
77 ;; If click in the minibuffer and reading an argument,
78 ;; accept argument or give completion help.
79 ((and (> (minibuffer-depth) 0)
80 (eq (selected-window) (minibuffer-window))
81 (not (eq hargs:reading-p 'hmenu))) .
82 ((exit-minibuffer) . (smart-completion-help)))
84 ;; If reading a Hyperbole menu item or a Hyperbole completion-based
85 ;; argument, allow selection of an item at point.
86 ((if (> (minibuffer-depth) 0) (setq hkey-value (hargs:at-p))) .
87 ((hargs:select-p hkey-value) .
88 (hargs:select-p hkey-value 'assist)))
91 (or (eolp) (if selective-display
92 (= (following-char) ?\^M)))) .
93 ((smart-scroll-up) . (smart-scroll-down)))
95 ((eq major-mode 'smart-menu-mode) .
96 ((smart-menu-select) . (smart-menu-help)))
98 ;; If on a Hyperbole button, perform action or give help.
99 ((if (fboundp 'hbut:at-p) (or (hbut:at-p) (hbut:label-p))) .
100 ((hui:hbut-act 'hbut:current) . (hui:hbut-help 'hbut:current)))
102 ;; The Smart Menu system provides menus within Emacs running on a dumb
103 ;; terminal. It is part of InfoDock and is not available separately.
104 ((and (fboundp 'smart-menu-choose-menu)
105 (setq hkey-value (and hkey-always-display-menu
106 (smart-menu-choose-menu)))
107 (not (and (get-buffer-window *smart-menu-buffer*)
108 (eq hkey-value *smart-menu-curr*)))) .
109 ((smart-menu hkey-value) .
110 (smart-menu hkey-value)))
114 ((if (boundp 'view-minor-mode)
115 (and view-minor-mode (not (eq major-mode 'Manual-mode)))) .
116 ((cond ((last-line-p)
118 ((pos-visible-in-window-p (point-max))
119 (goto-char (point-max)))
124 ((eq major-mode 'view-mode) .
125 ((View-scroll-lines-forward) . (View-scroll-lines-backward)))
127 ((eq major-mode 'kotl-mode) .
128 ((kotl-mode:action-key) . (kotl-mode:help-key)))
130 ;; Support direct selection and viewing on in-memory relational databases.
131 ;; Rdb-mode has not been publicly released.
132 ;; It is not included with Hyperbole.
133 ((eq major-mode 'rdb-mode) . ((smart-rdb) . (smart-rdb-assist)))
135 ;; Restore window config and hide help buffer when click at buffer end.
136 ((if (= (point) (point-max)) (string-match "Help\\(\\|:.*\\)\\*$" (buffer-name))) .
137 ((hkey-help-hide) . (hkey-help-hide)))
139 ;; Support the OO-Browser, a part of InfoDock, XEmacs, and soon to be a
141 ((or (br-in-browser) (eq major-mode 'br-mode)) .
142 ((smart-br-dispatch) . (smart-br-assist-dispatch)))
144 ((and (memq major-mode '(c-mode c++-c-mode))
145 buffer-file-name (setq hkey-value (smart-c-at-tag-p))) .
146 ((smart-c) . (smart-c nil 'next-tag)))
148 ((and (eq major-mode 'asm-mode)
149 buffer-file-name (setq hkey-value (smart-asm-at-tag-p))) .
150 ((smart-asm) . (smart-asm nil 'next-tag)))
152 ((if (smart-lisp-mode-p) (smart-lisp-at-tag-p)) .
153 ((smart-lisp) . (smart-lisp 'next-tag)))
155 ((and (eq major-mode 'c++-mode) buffer-file-name
156 ;; Don't use smart-c++-at-tag-p here since it will prevent #include
157 ;; lines from matching.
158 (setq hkey-value (smart-c-at-tag-p))) .
159 ( ;; Only fboundp if OO-Browser has been loaded.
160 (if (fboundp 'c++-to-definition)
161 (smart-c++-oobr) (smart-c++)) .
162 (if (fboundp 'c++-to-definition)
164 (smart-c++ nil 'next-tag))))
166 ((and (eq major-mode 'objc-mode) buffer-file-name
167 (setq hkey-value (smart-objc-at-tag-p))) .
168 ( ;; Only fboundp if OO-Browser has been loaded.
169 (if (fboundp 'objc-to-definition)
170 (smart-objc-oobr) (smart-objc)) .
171 (if (fboundp 'objc-to-definition)
173 (smart-objc nil 'next-tag))))
175 ((and (eq major-mode 'fortran-mode)
176 buffer-file-name (setq hkey-value (smart-fortran-at-tag-p))) .
177 ((smart-fortran) . (smart-fortran nil 'next-tag)))
179 ((eq major-mode 'occur-mode) .
180 ((occur-mode-goto-occurrence) . (occur-mode-goto-occurrence)))
182 ((eq major-mode 'moccur-mode) .
183 ((moccur-mode-goto-occurrence) . (moccur-mode-goto-occurrence)))
185 ((eq major-mode 'calendar-mode) .
186 ((smart-calendar) . (smart-calendar-assist)))
188 ((eq major-mode 'unix-apropos-mode) .
189 ((smart-apropos) . (smart-apropos-assist)))
191 ((eq major-mode 'outline-mode) .
192 ((smart-outline) . (smart-outline-assist)))
194 ((eq major-mode 'Info-mode) .
195 ((smart-info) . (smart-info-assist)))
197 ((if (boundp 'hmail:reader)
198 (or (eq major-mode hmail:reader)
199 (eq major-mode hmail:lister))) .
200 ((smart-hmail) . (smart-hmail-assist)))
202 ((eq major-mode 'gnus-group-mode)
203 (smart-gnus-group) . (smart-gnus-group-assist))
205 ((eq major-mode 'gnus-summary-mode)
206 (smart-gnus-summary) . (smart-gnus-summary-assist))
208 ((eq major-mode 'gnus-article-mode)
209 (smart-gnus-article) . (smart-gnus-article-assist))
211 ((eq major-mode 'Buffer-menu-mode) .
212 ((smart-buffer-menu) . (smart-buffer-menu-assist)))
214 ((eq major-mode 'ibuffer-mode) .
215 ((smart-ibuffer-menu) . (smart-ibuffer-menu-assist)))
217 ((eq major-mode 'dired-mode) .
218 ((smart-dired) . (smart-dired-assist)))
220 ((eq major-mode 'tar-mode) .
221 ((smart-tar) . (smart-tar-assist)))
223 ;; Follow references in man pages.
224 ((setq hkey-value (smart-man-entry-ref)) .
225 ((smart-man-display hkey-value) .
226 (smart-man-display hkey-value)))
228 ((eq major-mode 'w3-mode) .
229 ((w3-follow-link) . (w3-goto-last-buffer)))
231 ((if (boundp 'rolo-display-buffer)
232 (equal (buffer-name) rolo-display-buffer)) .
233 ((smart-wrolo) . (smart-wrolo-assist)))
236 ((eq major-mode 'gomoku-mode) .
237 ((gomoku-human-plays) . (gomoku-human-takes-back)))
240 ((eq major-mode 'change-log-mode) .
241 ((smart-change-log) . (smart-change-log)))
244 ((eq major-mode 'bookmark-bmenu-mode) .
245 ((smart-bookmark-menu) . (smart-bookmark-menu-assist)))
247 ;; Outline minor mode is on and usable.
249 ((smart-outline) . (smart-outline-assist)))
251 "Alist of predicates and form-conses for Action and Assist Keys.
252 When the Action or Assist Key is pressed, the first or second form,
253 respectively, associated with the first non-nil predicate is evaluated.")
259 ;; The following autoload is needed if another subsystem besides
260 ;; Hyperbole uses this mouse handling code.
261 (autoload 'var:append "hvar" "Append to a list variable." nil)
264 (require 'hmouse-key)
265 (if hyperb:window-system
267 (defvar hmouse-alist hkey-alist
268 "Alist of predicates and form-conses for context-sensitive smart key mouse actions.
269 When the action-key or the assist-key is pressed, the first or
270 second form, respectively, associated with the first non-nil predicate is
272 (load "hui-window")))
278 ;; The 'load' line below loads any local Smart Key function definitions.
279 ;; The public distribution contains none. You may leave it commented out if
281 ;; (load "smart-local" t)
284 ;;; Required Init functions
287 (defun first-line-p ()
288 "Returns true if point is on the first line of the buffer."
289 (save-excursion (beginning-of-line) (bobp)))
291 (defun last-line-p ()
292 "Returns true if point is on the last line of the buffer."
293 (save-excursion (end-of-line) (eobp)))
295 (defun smart-completion-help ()
296 "Offer completion help for current minibuffer argument, if any."
297 (if (where-is-internal 'minibuffer-completion-help (current-local-map))
298 (minibuffer-completion-help)))
300 (defun smart-symlink-expand (path)
301 "Returns referent for possible symbolic link, PATH."
302 (if (not (fboundp 'symlink-referent))
304 (let ((start 0) (len (length path)) (ref) (part))
305 (while (and (< start len) (setq part (string-match "/[^/]*" path start)))
306 (setq part (concat ref
307 (substring path start (setq start (match-end 0))))
308 ref (symlink-referent part)))
312 ;;; smart-buffer-menu functions
315 (defun smart-buffer-menu (&optional in-browser)
316 "Uses a single key or mouse key to manipulate buffer-menu entries.
318 Invoked via a key press when in Buffer-menu-mode. It assumes that its
319 caller has already checked that the key was pressed in an appropriate buffer
320 and has moved the cursor there.
322 Optional non-nil IN-BROWSER indicates use within the OO-Browser.
325 (1) on the first column of an entry, the selected buffer is marked for
327 (2) on the second column of an entry, the selected buffer is marked to be
329 (3) anywhere else within an entry line, all saves and deletes are done, and
330 selected buffers are displayed, including the one just clicked on (if
331 IN-BROWSER, only the selected buffer is displayed);
332 (4) on or after the last line in the buffer, all saves and deletes are done."
335 (cond ((last-line-p) (Buffer-menu-execute))
336 ((bolp) (Buffer-menu-mark))
338 (goto-char (1- (point)))
341 (in-browser (br-buffer-menu-select))
342 (t (Buffer-menu-select))))
344 (defun smart-buffer-menu-assist ()
345 "Uses a single assist-key or mouse assist-key to manipulate buffer-menu entries.
347 Invoked via an assist-key press when in Buffer-menu-mode. It assumes that its
348 caller has already checked that the assist-key was pressed in an appropriate
349 buffer and has moved the cursor there.
351 If assist-key is pressed:
352 (1) on the first or second column of an entry, the selected buffer is unmarked
353 for display and for saving or deletion;
354 (2) anywhere else within an entry line, the selected buffer is marked for
356 (3) on or after the last line in the buffer, all display, save, and delete
357 marks on all entries are undone."
360 (cond ((last-line-p) (progn (list-buffers) (forward-line 3)))
361 ((bolp) (Buffer-menu-unmark))
363 (goto-char (1- (point)))
365 (Buffer-menu-unmark))
366 (t (Buffer-menu-delete))))
369 ;;; smart-ibuffer-menu functions
372 (defun smart-ibuffer-menu (&optional in-browser)
373 "Uses a single key or mouse key to manipulate ibuffer entries.
375 Invoked via a key press when in ibuffer-mode. It assumes that its
376 caller has already checked that the key was pressed in an appropriate buffer
377 and has moved the cursor there.
379 Optional non-nil IN-BROWSER indicates use within the OO-Browser.
382 (1) on the first or second column of an entry, the selected buffer is
384 (3) anywhere else within an entry line, all selected buffers are
385 displayed, including the one just clicked on (if IN-BROWSER, only
386 the selected buffer is displayed);
387 (4) on or after the last line in the buffer, all deletes are done."
390 (cond ((last-line-p) (progn (ibuffer-do-kill-on-deletion-marks)))
391 ((first-line-p) (progn (ibuffer-filter-disable)))
392 ((bolp) (ibuffer-mark-forward 1))
394 (goto-char (1- (point)))
396 (ibuffer-mark-forward 1))
397 (in-browser (br-buffer-menu-select))
398 (t (ibuffer-do-view))))
400 (defun smart-ibuffer-menu-assist ()
401 "Uses a single assist-key or mouse assist-key to manipulate buffer-menu entries.
403 Invoked via an assist-key press when in ibuffer-mode. It assumes that
404 its caller has already checked that the assist-key was pressed in an
405 appropriate buffer and has moved the cursor there.
407 If assist-key is pressed:
408 (1) on the first or second column of an entry, the selected buffer is unmarked
409 for display or deletion;
410 (2) anywhere else within an entry line, the selected buffer is marked for
412 (3) on or after the last line in the buffer, all display, save, and delete
413 marks on all entries are undone."
416 (cond ((last-line-p) (ibuffer-unmark-all 0))
417 ((bolp) (ibuffer-unmark-forward 1))
419 (goto-char (1- (point)))
421 (ibuffer-unmark-forward 1))
422 (t (ibuffer-mark-for-delete 1))))
425 ;;; smart-calendar functions
428 (defun smart-calendar ()
429 "Uses a single key or mouse key to manipulate the scrolling calendar.
431 Invoked via a key press when in calendar-mode. It assumes that its
432 caller has already checked that the key was pressed in an appropriate buffer
433 and has moved the cursor there.
436 (1) at the end of the buffer, the calendar is scrolled forward 3 months;
437 (2) to the left of any dates on a calendar line, the calendar is scrolled
439 (3) on a date, the diary entries for the date, if any, are displayed."
442 (cond ((eobp) (calendar-cursor-to-nearest-date)
443 (scroll-calendar-left-three-months 1))
444 ((< (current-column) 5) (calendar-cursor-to-nearest-date)
445 (scroll-calendar-right-three-months 1))
446 (t (calendar-cursor-to-nearest-date)
447 (view-diary-entries 1))))
449 (defun smart-calendar-assist ()
450 "Uses a single assist-key or mouse assist-key to manipulate the scrolling calendar.
452 Invoked via an assist-key press when in calendar-mode. It assumes that its
453 caller has already checked that the assist-key was pressed in an appropriate
454 buffer and has moved the cursor there.
456 If assist-key is pressed:
457 (1) at the end of the buffer, the calendar is scrolled backward 3 months;
458 (2) to the left of any dates on a calendar line, the calendar is scrolled
460 (3) anywhere else, all dates with marking diary entries are marked in the
464 (cond ((eobp) (calendar-cursor-to-nearest-date)
465 (scroll-calendar-right-three-months 1))
466 ((< (current-column) 5) (calendar-cursor-to-nearest-date)
467 (scroll-calendar-left-three-months 1))
468 (t (mark-diary-entries))))
472 ;;; smart-dired functions
475 (defun smart-dired ()
476 "Uses a single key or mouse key to manipulate directory entries.
478 Invoked via a key press when in dired-mode. It assumes that its
479 caller has already checked that the key was pressed in an appropriate buffer
480 and has moved the cursor there.
483 (1) within an entry line, the selected file/directory is displayed for
484 editing in the other window;
485 (2) on or after the last line in the buffer, if any deletes are to be
486 performed, they are executed after user verification, otherwise, this
487 dired invocation is quit."
494 (setq flagged (re-search-forward "^D" nil t)))
496 (cond ((fboundp 'dired-do-deletions)
497 (dired-do-deletions))
498 ;; For Tree-dired compatibility
499 ((fboundp 'dired-do-flagged-delete)
500 (dired-do-flagged-delete))
501 (t (error "(smart-dired): No Dired expunge function.")))
503 (t (hpath:find-other-window (dired-get-filename)))))
505 (defun smart-dired-assist ()
506 "Uses a single assist-key or mouse assist-key to manipulate directory entries.
508 Invoked via an assist-key press when in dired-mode. It assumes that its
509 caller has already checked that the assist-key was pressed in an appropriate
510 buffer and has moved the cursor there.
512 If assist-key is pressed:
513 (1) on a '~' character, all backup files in the directory are marked for
515 (2) on a '#' character, all auto-save files in the directory are marked for
517 (3) anywhere else within an entry line, the current entry is marked for
519 (4) on or after the last line in the buffer, all delete marks on all entries
524 (dired-unmark-all-files dired-del-marker))
525 ((looking-at "~") (dired-flag-backup-files))
526 ((looking-at "#") (dired-flag-auto-save-files))
527 (t (if (fboundp 'dired-flag-file-deleted) (dired-flag-file-deleted 1) (dired-flag-file-deletion 1)))))
530 ;;; smart-gnus functions
533 (defun smart-gnus-group ()
534 "Uses a key or mouse key to move through Gnus Newsgroup listings.
535 Invoked via a key press when in gnus-group-mode. It assumes that its caller
536 has already checked that the key was pressed in an appropriate buffer and has
537 moved the cursor to the selected buffer.
539 If key is pressed within:
540 (1) a GNUS-GROUP line, that newsgroup is read. If gnus-topic-mode is
541 active topics are expanded and collapsed as well on a key press;
542 (2) to the left of any GNUS-GROUP line, on any of the whitespace, the current
543 group is unsubscribed or resubscribed;
544 (3) at the end of the GNUS-GROUP buffer, after all lines, checks for new
548 (cond ((last-line-p) (gnus-group-get-new-news))
549 ((progn (skip-chars-backward " U") (bolp))
550 (gnus-group-unsubscribe-current-group))
551 ((gnus-topic-mode-p) (gnus-topic-read-group))
552 (t (gnus-group-read-group))))
554 (defun smart-gnus-group-assist ()
555 "Uses an assist-key or assist-mouse key to move through Gnus Newsgroup listings.
556 Invoked via an assist-key press when in gnus-group-mode. It assumes that its
557 caller has already checked that the key was pressed in an appropriate buffer
558 and has moved the cursor to the selected buffer.
560 If key is pressed within:
561 (1) a GNUS-GROUP line, that newsgroup is read;
562 (2) to the left of any GNUS-GROUP line, on any of the whitespace, the user is
563 prompted for a group name to subscribe or unsubscribe to;
564 (3) at the end of the GNUS-GROUP buffer, after all lines, quits from the
568 (cond ((last-line-p) (gnus-group-exit))
569 ((progn (skip-chars-backward " U") (bolp))
570 (call-interactively 'gnus-group-unsubscribe-group))
571 (t (gnus-group-read-group nil))))
573 (defun smart-gnus-summary ()
574 "Uses a key or mouse key to move through Gnus News article listings.
575 Invoked via a key press when in gnus-summary-mode. It assumes that its caller
576 has already checked that the key was pressed in an appropriate buffer and has
577 moved the cursor to the selected buffer.
579 If key is pressed within:
580 (1) to the left of an article number, that article is marked as unread;
581 (2) a GNUS-SUMMARY line, that article is read, marked deleted, and scrolled
583 (3) at the end of the GNUS-SUMMARY buffer, the next undeleted article
584 is read or the next group is entered."
588 (if gnus-current-article
589 (progn (goto-char (point-min))
591 (format "^.[ ]+%d:" gnus-current-article) nil t)
592 (setq this-command 'gnus-summary-next-page)
593 (call-interactively 'gnus-summary-next-page))
594 (goto-char (point-min))
595 (setq this-command 'gnus-summary-first-unread-article)
596 (call-interactively 'gnus-summary-first-unread-article)))
597 ((save-excursion (skip-chars-backward " D") (bolp))
598 (gnus-summary-mark-as-unread-forward 1))
599 (t (setq this-command 'gnus-summary-next-page)
600 (call-interactively 'gnus-summary-next-page))))
602 (defun smart-gnus-summary-assist ()
603 "Uses an assist-key or assist-mouse key to move through Gnus News articles.
604 Invoked via an assist-key press when in gnus-summary-mode. It assumes that its
605 caller has already checked that the key was pressed in an appropriate buffer
606 and has moved the cursor to the selected buffer.
608 If key is pressed within:
609 (1) to the left of an article number, that article is marked as unread;
610 (2) a GNUS-SUMMARY line, that article is read and scrolled backward;
611 (3) at the end of the GNUS-SUMMARY buffer, the summary is exited, the user
612 is returned to group mode."
616 (setq this-command 'gnus-summary-prev-page)
617 (call-interactively 'gnus-summary-exit))
618 ((save-excursion (skip-chars-backward " D") (bolp))
619 (gnus-summary-mark-as-unread-backward 1))
620 (t (setq this-command 'gnus-summary-prev-page)
621 (call-interactively 'gnus-summary-prev-page))))
623 (defun smart-gnus-article ()
624 "Uses a key or mouse key to move through Gnus netnews articles.
626 Invoked via a key press when in gnus-article-mode.
627 It assumes that its caller has already checked that the key was pressed in an
628 appropriate buffer and has moved the cursor to the selected buffer.
630 If key is pressed within:
631 (1) the first line or end of an article, the next unread message is displayed;
632 (2) the first line of an Info cross reference, the reference is followed;
633 (3) anywhere else, the window is scrolled up a windowful."
635 (cond ((or (last-line-p) (and (not (eolp)) (first-line-p)))
637 (progn (set-buffer gnus-summary-buffer)
638 (setq this-command 'gnus-summary-next-unread-article)
639 (gnus-summary-next-unread-article)
640 (gnus-summary-goto-subject gnus-current-article)
642 (let ((artic (get-buffer-window gnus-article-buffer)))
643 (if artic (select-window artic)))))
644 ((and (not (eolp)) (Info-handle-in-note)))
645 ((gnus-article-press-button))
646 (t (smart-scroll-up))))
648 (defun smart-gnus-article-assist ()
649 "Uses an assist-key or mouse assist-key to move through Gnus netnews articles.
651 Invoked via an assist-key press when ing nus-article-mode.
652 It assumes that its caller has already checked that the assist-key was pressed in
653 an appropriate buffer and has moved the cursor to the selected buffer.
655 If assist-key is pressed within:
656 (1) the first line or end of an article, the previous message is displayed;
657 (2) the first line of an Info cross reference, the reference is followed;
658 (3) anywhere else, the window is scrolled down a windowful."
660 (cond ((or (last-line-p) (and (not (eolp)) (first-line-p)))
662 (progn (set-buffer gnus-summary-buffer)
663 (setq this-command 'gnus-summary-prev-article)
664 (gnus-summary-prev-article nil)
665 (gnus-summary-goto-subject gnus-current-article)
667 (let ((artic (get-buffer-window gnus-summary-buffer)))
668 (if artic (select-window artic)))))
669 ((and (not (eolp)) (Info-handle-in-note)))
670 (t (smart-scroll-down))))
673 ;;; smart-hmail functions
676 (defun smart-hmail ()
677 "Uses a key or mouse key to move through e-mail messages and summaries.
679 Invoked via a key press when in hmail:reader or hmail:lister mode.
680 It assumes that its caller has already checked that the key was pressed in an
681 appropriate buffer and has moved the cursor to the selected buffer.
683 If key is pressed within:
684 (1) a msg buffer, within the first line or at the end of a message,
685 the next undeleted message is displayed;
686 (2) a msg buffer within the first line of an Info cross reference, the
687 reference is followed;
688 (3) anywhere else in a msg buffer, the window is scrolled up a windowful;
689 (4) a msg summary buffer on a header entry, the message corresponding to
690 the header is displayed in the msg window;
691 (5) a msg summary buffer, on or after the last line, the messages marked
692 for deletion are expunged."
696 ;; Branch on buffer type
698 (cond ((eq major-mode hmail:reader)
699 (cond ((or (last-line-p) (and (not (eolp)) (first-line-p)))
701 ((and (not (eolp)) (Info-handle-in-note)))
702 ((smart-scroll-up))))
704 ;; Assume are in msg summary buffer
706 ((last-line-p) (lmail:expunge))
709 (defun smart-hmail-assist ()
710 "Uses an assist key or mouse key to move through e-mail messages and summaries.
712 Invoked via an assist key press when in hmail:reader or hmail:lister mode.
713 It assumes that its caller has already checked that the assist-key was pressed in
714 an appropriate buffer and has moved the cursor to the selected buffer.
716 If assist-key is pressed within:
717 (1) a msg buffer, within the first line or at the end of a message,
718 the previous undeleted message is displayed;
719 (2) a msg buffer within the first line of an Info cross reference, the
720 reference is followed;
721 (3) anywhere else in a msg buffer, the window is scrolled down a windowful;
722 (4) a msg summary buffer on a header entry, the message corresponding to
723 the header is marked as deleted;
724 (5) a msg summary buffer, on or after the last line, all messages are
729 ;; Branch on buffer type
731 (cond ((eq major-mode hmail:reader)
732 (cond ((or (last-line-p) (and (not (eolp)) (first-line-p)))
734 ((and (not (eolp)) (Info-handle-in-note)))
735 ((smart-scroll-down))))
737 ;; Assume are in msg summary buffer
739 ((last-line-p) (lmail:undelete-all))
744 ;;; smart-info functions
746 ;;; Autoloaded in "hyperbole.el".
749 ;;; smart-man functions
752 ;; "unix-apropos.el" is a publicly available Emacs Lisp package that
753 ;; allows man page browsing from apropos listings. "superman.el" is a
754 ;; newer, much more complete package that you would probably prefer at
755 ;; this point, but there is no Smart Key apropos support for it. There
756 ;; is smart key support within the man page buffers it produces, however.
759 (defun smart-apropos ()
760 "Moves through UNIX man apropos listings by using one key or mouse key.
762 Invoked via a key press when in unix-apropos-mode. It assumes that
763 its caller has already checked that the key was pressed in an appropriate
764 buffer and has moved the cursor to the selected buffer.
767 (1) on a UNIX man apropos entry, the man page for that entry is displayed in
769 (2) on or after the last line, the buffer in the other window is scrolled up
774 (scroll-other-window)
775 (unix-apropos-get-man)))
777 (defun smart-apropos-assist ()
778 "Moves through UNIX man apropos listings by using one assist-key or mouse assist-key.
780 Invoked via an assist-key press when in unix-apropos-mode. It assumes that
781 its caller has already checked that the assist-key was pressed in an appropriate
782 buffer and has moved the cursor to the selected buffer.
784 If assist-key is pressed:
785 (1) on a UNIX man apropos entry, the man page for that entry is displayed in
787 (2) on or after the last line, the buffer in the other window is scrolled down
792 (scroll-other-window (- 3 (window-height)))
793 (unix-apropos-get-man)))
795 (defun smart-man-display (lisp-form)
796 "Evaluates LISP-FORM returned from 'smart-man-entry-ref' to display a man page."
799 (defun smart-man-follow-xref ()
800 "Get `manual-entry' from the cross-reference under the mouse."
802 (extent (and p (extent-at p (current-buffer) 'highlight)))
803 (data (and extent (extent-property extent 'man))))
804 (if (eq (car-safe data) 'Manual-follow-xref)
807 (defun smart-man-entry-ref ()
808 "Returns form which displays referenced manual entry that point is on or nil.
809 Handles references in sections: NAME, SEE ALSO, or PACKAGES USED. Also can
810 display C routine definitions selected in a man page, see
811 'smart-man-c-routine-ref'.
813 Man page buffer must either have an attached file or else a `man-path'
814 local variable containing its pathname."
817 (if (not (or (if (string-match "Manual Entry\\|\\*man \\|Man: "
818 (buffer-name (current-buffer)))
819 (progn (and (boundp 'man-path) man-path
820 (setq ref (smart-symlink-expand man-path)))
823 (string-match "/man/" (setq ref (smart-symlink-expand
824 buffer-file-name))))))
826 (or (setq ref (or (smart-man-file-ref)
827 (smart-man-c-routine-ref)))
829 (let ((opoint (point))
832 (re-search-backward "^[.A-Z]" nil t)
834 "\\(\\.SH[ \t]+\\)?\\(SEE ALSO\\|NAME\\|PACKAGES USED\\)")
835 (progn (goto-char opoint)
836 (skip-chars-backward "-_a-zA-Z0-9?.(")
837 (let ((start (point)))
838 (skip-chars-forward "-_a-zA-Z0-9?.()")
839 (setq ref (buffer-substring start (point)))
840 ;; Leave only one char within ref parens
842 (if (string-match "(\\(.\\)\\(.+\\))" ref)
843 (setq ref (concat (substring ref 0 (match-end 1))
846 (cond ((and hyperb:xemacs-p (setq xref (smart-man-follow-xref))) xref)
848 ((stringp ref) (list 'manual-entry ref))
851 (defun smart-man-c-routine-ref ()
852 "Returns form to jump to def of C function whose name is at point, if any.
853 Valid sections within the man page are: ROUTINES, MACROS or FUNCTIONS.
854 Uses (smart-tags-file) function to determine etags file from which to
855 locate the definition.
857 Returns etags file name if point is on an identifier in the appropriate
858 section and the jump is done, otherwise, returns nil."
863 (and (re-search-backward "^[.A-Z]" nil t)
864 (looking-at "^\\(FUNCTIONS\\|ROUTINES\\|MACROS\\)[ \t\n]")
865 (progn (goto-char opoint)
866 (skip-chars-backward "_~<>:a-zA-Z0-9(")
867 (if (or (looking-at "\\([_~<>:a-zA-Z0-9]+\\)[ \t\n]*(")
868 (looking-at "\\([_~<:A-Z][_<>:A-Z0-9]+\\)"))
869 (setq ref (buffer-substring
870 (match-beginning 1) (match-end 1))
873 (let ((tags-file-name
874 (smart-tags-file (if (and (boundp 'man-path) man-path)
876 default-directory))))
877 (and (file-exists-p tags-file-name)
878 (file-readable-p tags-file-name)
879 (list 'let (list (list 'tags-file-name tags-file-name))
880 (list (if (br-in-browser)
881 'find-tag 'find-tag-other-window)
884 (defun smart-man-file-ref ()
885 "Returns form to eval to display file whose name point is on, within a FILES man page section.
886 If not on a file name, returns nil."
891 (and (re-search-backward "^[.A-Z]" nil t)
892 (looking-at "^FILES[ \t\n]")
893 (progn (goto-char opoint)
894 (skip-chars-backward "^ \t")
895 (if (looking-at "/[^ \t\n]+")
896 (setq ref (buffer-substring
897 (match-beginning 0) (match-end 0))
900 (list (if (br-in-browser)
901 'find-file 'find-file-other-window)
905 ;;; smart-outline functions
908 ;; The functions in this section require InfoDock's version of outline.el
909 ;; in order to work properly.
911 (defvar smart-outline-cut nil
912 "Non-nil means outline region was cut and is ready to be pasted at point.")
916 (make-local-variable 'smart-outline-cut)
917 ;; Non-nil means outline region was cut and is available to be
919 (setq smart-outline-cut nil)
921 (if (boundp 'outline-mode-map)
923 (var:append 'outline-mode-hook proc)))
925 (defun smart-outline ()
926 "Collapses, expands, and moves outline entries.
927 Invoked via a key press when in outline-mode. It assumes that
928 its caller has already checked that the key was pressed in an appropriate
929 buffer and has moved the cursor to the selected buffer.
932 (1) after an outline heading has been cut via the Action Key, then paste the
933 cut heading at point;
934 (2) at the end of buffer, show all buffer text
935 (3) at the beginning of a heading line, cut the headings subtree from the
937 (4) on a header line but not at the beginning or end, if headings subtree is
938 hidden then show it, otherwise hide it;
939 (5) anywhere else, scroll up a windowful."
942 (cond (smart-outline-cut
943 (setq smart-outline-cut nil) (yank))
945 ((and (bolp) (looking-at outline-regexp))
946 (setq smart-outline-cut t)
949 (or (outline-get-next-sibling)
950 ;; Skip past start of current entry
951 (progn (re-search-forward outline-regexp nil t)
952 (smart-outline-to-entry-end t (outline-level))))))
954 ((or (eolp) (zerop (save-excursion (beginning-of-line)
957 ;; On an outline header line but not at the start/end of line.
958 ((smart-outline-subtree-hidden-p)
963 (defun smart-outline-assist ()
964 "Collapses, expands, and moves outline entries.
965 Invoked via an assist-key press when in outline-mode. It assumes that
966 its caller has already checked that the assist-key was pressed in an appropriate
967 buffer and has moved the cursor to the selected buffer.
969 If assist-key is pressed:
970 (1) after an outline heading has been cut via the action-key, allow multiple
971 pastes throughout the buffer (last paste should be done with the Action Key,
973 (2) at the end of buffer, hide all bodies in buffer;
974 (3) at the beginning of a heading line, cut the current heading (sans
975 subtree) from the buffer;
976 (4) on a header line but not at the beginning or end, if heading body is
977 hidden then show it, otherwise hide it;
978 (5) anywhere else, scroll down a windowful."
981 (cond (smart-outline-cut (yank))
982 ((eobp) (hide-body ))
983 ((and (bolp) (looking-at outline-regexp))
984 (setq smart-outline-cut t)
986 ;; Skip past start of current entry
987 (progn (re-search-forward outline-regexp nil t)
988 (smart-outline-to-entry-end
989 nil (outline-level)))))
990 ((or (eolp) (zerop (save-excursion (beginning-of-line)
993 ;; On an outline header line but not at the start/end of line.
994 ((smart-outline-subtree-hidden-p)
998 (defun smart-outline-to-entry-end
999 (&optional include-sub-entries curr-entry-level)
1000 "Goes to end of whole entry if optional INCLUDE-SUB-ENTRIES is non-nil.
1001 CURR-ENTRY-LEVEL is an integer representing the length of the current level
1002 string which matched to 'outline-regexp'. If INCLUDE-SUB-ENTRIES is nil,
1003 CURR-ENTRY-LEVEL is not needed."
1004 (let (next-entry-exists)
1005 (while (and (setq next-entry-exists
1006 (re-search-forward outline-regexp nil t))
1011 curr-entry-level))))
1012 (if next-entry-exists
1013 (progn (beginning-of-line) (point))
1014 (goto-char (point-max)))))
1016 (defun smart-outline-subtree-hidden-p ()
1017 "Returns t if at least initial subtree of heading is hidden, else nil."
1019 (if (re-search-forward "[\n\^M]" nil t) (= (preceding-char) ?\^M))))
1022 ;;; smart-tar functions
1026 "Uses a single key or mouse key to manipulate tar file entries.
1028 Invoked via a key press when in tar-mode. It assumes that its
1029 caller has already checked that the key was pressed in an appropriate buffer
1030 and has moved the cursor there.
1033 (1) within an entry line, the selected file/directory is displayed for
1034 editing in the other window;
1035 (2) on or after the last line in the buffer, if any deletes are to be
1036 performed, they are executed after user verification, otherwise, this
1037 tar file browser is quit."
1040 (cond ((last-line-p)
1044 (setq flagged (re-search-forward "^D" nil t)))
1047 (kill-buffer nil))))
1048 (t (tar-extract-other-window))))
1050 (defun smart-tar-assist ()
1051 "Uses a single assist-key or mouse assist-key to manipulate tar file entries.
1053 Invoked via an assist-key press when in dired-mode. It assumes that its
1054 caller has already checked that the assist-key was pressed in an appropriate
1055 buffer and has moved the cursor there.
1057 If assist-key is pressed:
1058 (1) on an entry line, the current entry is marked for deletion;
1059 (2) on or after the last line in the buffer, all delete marks on all entries
1063 (cond ((last-line-p)
1064 (tar-unflag (- (count-lines (point-min) (point-max))))
1065 (goto-char (point-max)))
1066 (t (tar-flag-deleted 1))))
1069 ;;; smart-wrolo functions
1072 (defun smart-wrolo ()
1073 "In wrolo match buffer, edits current entry.
1074 Uses one key or mouse key.
1076 Invoked via a key press when in the 'rolo-display-buffer'. It assumes that
1077 its caller has already checked that the key was pressed in an appropriate
1078 buffer and has moved the cursor to the selected buffer."
1082 (fset 'smart-wrolo-assist 'smart-wrolo)
1084 ;;; Smart change log functions
1085 (defun smart-change-log ()
1086 "In Change Log buffers."
1089 (re-search-backward "^\\s-+\\*\\s-+")
1090 (looking-at "^\\s-+\\*\\s-+\\(.*?\\)\\(:\\|\\s-+(\\)")
1091 (hact 'link-to-file (buffer-substring (match-beginning 1) (match-end 1))))))
1093 ;;; smart-bookmark-menu functions
1094 (defun smart-bookmark-menu ()
1095 "Uses a single key or mouse key to manipulate bookmark entries.
1097 Invoked via a key press when in bookmark-bmenu-mode. It assumes that its
1098 caller has already checked that the key was pressed in an appropriate buffer
1099 and has moved the cursor there.
1102 (1) on the first column of an entry, the selected buffer is marked for
1104 (2) on the second column of an entry, the selected buffer is marked to be
1106 (3) anywhere else within an entry line, all saves and deletes are done, and
1107 selected buffers are displayed, including the one just clicked on.
1108 (4) on or after the last line in the buffer, all saves and deletes are done."
1111 (cond ((last-line-p) (bookmark-bmenu-execute-deletions))
1112 ((bolp) (bookmark-bmenu-mark))
1114 (goto-char (1- (point)))
1116 (if (looking-at "\\*")
1117 (bookmark-bmenu-show-annotation)
1118 (bookmark-bmenu-edit-annotation)))
1119 (t (bookmark-bmenu-select))))
1121 (defun smart-bookmark-menu-assist ()
1122 "Uses a single assist-key or mouse assist-key to manipulate buffer-menu entries.
1124 Invoked via an assist-key press when in bookmark-bmenu-mode. It assumes that its
1125 caller has already checked that the assist-key was pressed in an appropriate
1126 buffer and has moved the cursor there.
1128 If assist-key is pressed:
1129 (1) on the first or second column of an entry, the selected buffer is unmarked
1130 for display and for saving or deletion;
1131 (2) anywhere else within an entry line, the selected buffer is marked for
1133 (3) on or after the last line in the buffer, all display, save, and delete
1134 marks on all entries are undone."
1137 (cond ((last-line-p) (bookmark-bmenu-quit))
1138 ((bolp) (bookmark-bmenu-unmark))
1140 (goto-char (1- (point)))
1142 (bookmark-bmenu-edit-annotation))
1143 (t (bookmark-bmenu-delete))))
1145 (provide 'hui-mouse)
1147 ;;; hui-mouse.el ends here