Mercurial > hg > xemacs-beta
diff lisp/packages/man-xref.el @ 76:c0c698873ce1 r20-0b33
Import from CVS: tag r20-0b33
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:05:10 +0200 |
parents | b82b59fe008d |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/packages/man-xref.el Mon Aug 13 09:05:10 2007 +0200 @@ -0,0 +1,166 @@ +;;; man-xref.el --- cross reference selection functions for man mode + +;; Author: Mark Hood <hood@eng.sun.com> +;; @(#)man-xref.el 1.15 + +;; This file is part of XEmacs. + +;; XEmacs is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; XEmacs is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with XEmacs; see the file COPYING. If not, write to the Free +;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +;; 02111-1307, USA. + +;;; Synched up with: FSF 19.35. + +;;; Commentary: + +;; This package is an add-on to the man.el that comes with Emacs +;; 19.34. It renders manpage cross references in bold, sets them up +;; for mouse highlighting, and allows selection via keystrokes or +;; mouse. All strings matching Man-reference-regexp in the text of +;; the man page are set up, in addition to the ones in the See Also +;; section. + +;; To use this package, put something like the following in your Emacs +;; initialization file. This example causes tab and M-tab to go to +;; the next and previous manual cross references, causes carriage +;; return to display a man page for the reference under point, and +;; allows mouse button 2 to invoke a man page display. + +;; (add-hook 'Man-mode-hook +;; '(lambda () +;; (Man-mouseify-xrefs) +;; (define-key Man-mode-map "\r" 'Man-do-manual-reference) +;; (define-key Man-mode-map "\t" 'Man-next-manual-reference) +;; (define-key Man-mode-map "\e\t" 'Man-prev-manual-reference) +;; (define-key Man-mode-map [mouse-2] 'Man-mouse-manual-reference) +;; )) +;; +;; (autoload 'Man-mouseify-xrefs "~/emacs/man-xref") + +(eval-when-compile (require 'cl)) + +(defvar Man-word-syntax "w_()" "Syntax for words in a man buffer.") + +(defun Man-current-word () + "Return word under point, using `Man-word-syntax' for word syntax." + (save-excursion + (let ((s (+ (point) (skip-syntax-backward Man-word-syntax)))) + (skip-syntax-forward Man-word-syntax) + (buffer-substring s (point))))) + +(defun Man-prev-word-hyphen-p () + "Return nil if previous word is not hyphenated. +Non-nil value is the buffer position of the beginning of the hyphenated word." + (save-excursion + (skip-syntax-backward Man-word-syntax) + (skip-chars-backward " \t") + (cond ((and (> (point) (1+ (point-min))) + (string-equal "-\n" (buffer-substring (- (point) 2) (point)))) + (backward-char) + (skip-syntax-backward Man-word-syntax) + (point))))) + +(defun Man-next-manual-reference () + "Move point to the beginning of the next manual reference." + (interactive) + (let ((current (point)) + (end (re-search-forward (concat "[ \t]" Man-reference-regexp) nil t)) + (start (or (Man-prev-word-hyphen-p) (1+ (match-beginning 0))))) + (cond ((eq end nil)) + ((> start current) + (goto-char start)) + ;; current is in the pre-hyphen portion of a hyphenated reference + ((re-search-forward Man-reference-regexp nil t) + (goto-char (or (Man-prev-word-hyphen-p) (match-beginning 0)))) + ((goto-char current))))) + +(defun Man-prev-manual-reference () + "Move point to the beginning of the previous manual reference." + (interactive) + (if (re-search-backward (concat "[ \t]" Man-reference-regexp) nil t) + (goto-char (or (Man-prev-word-hyphen-p) (1+ (match-beginning 0)))))) + +(defun Man-mouseify-xrefs () + "Render man cross references in bold font and set up mouse highlighting. +Add these cross references to `Man-refpages-alist'." + (let (start end xref hyphen alist) + (goto-char (point-min)) + (forward-line 1) + (while (re-search-forward Man-reference-regexp nil t) + (setq start (match-beginning 0)) + (setq end (match-end 0)) + (setq xref (buffer-substring start end)) + (cond ((setq hyphen (Man-prev-word-hyphen-p)) + (setq start hyphen) + (goto-char hyphen) + (setq xref (concat (substring (Man-current-word) 0 -1) xref)) + (goto-char end))) + (setq Man-refpages-alist (cons (list xref) Man-refpages-alist)) + (Man-boldify-mouse-region start end)) + (setq Man-refpages-alist + (sort Man-refpages-alist + (function (lambda (a b) (string< (car a) (car b)))))) + ;; delete duplicate entries in the alist + (setq alist Man-refpages-alist) + (while alist + (cond ((string= (car (car alist)) (car (car (cdr alist)))) + (setcdr alist (cdr (cdr alist)))) + ((setq alist (cdr alist))))) + (goto-char (point-min)) + (forward-line 1))) + +(defun Man-mouse-manual-reference (mouse) + "Move point to mouse position and run `Man-getpage-in-background' there." + (interactive "e") + (select-window (car (car (cdr mouse)))) + (goto-char (car (cdr (car (cdr mouse))))) + (Man-do-manual-reference)) + +(defun Man-do-manual-reference () + "Run `Man-getpage-in-background' on cross reference under point. +Word under point is checked for a match with `Man-reference-regexp'. +If point is not over a word, try to use previous word for a match." + (interactive) + (save-excursion + (let ((xref (Man-current-word)) (hyphen (Man-prev-word-hyphen-p))) + (if (and (zerop (length xref)) + (setq xref " ") + (skip-syntax-backward " ") + (not (eq (point) (point-min)))) + (Man-do-manual-reference) + (cond ((string-equal "-" (substring xref -1)) + (skip-syntax-forward Man-word-syntax) + (skip-syntax-forward " ") + (setq xref (concat (substring xref 0 -1) (Man-current-word)))) + (hyphen + (goto-char hyphen) + (setq xref (concat (substring (Man-current-word) 0 -1) xref)))) + (if (string-match Man-reference-regexp xref) + (Man-getpage-in-background + (Man-translate-references + (substring xref (match-beginning 0) (match-end 0)))) + (message "No cross reference found under point.")))))) + +(eval-and-compile + (when (string-match "XEmacs\\|Lucid" emacs-version) + (fset 'make-overlay 'make-extent) + (fset 'overlay-put 'set-extent-property))) + +(defun Man-boldify-mouse-region (beg end) + "Render region text in bold with mouse highlighting." + (let ((overlay (make-overlay beg end))) + (overlay-put overlay 'face 'bold) + (overlay-put overlay 'mouse-face 'highlight) + (overlay-put overlay 'hilit t))) +