]> code.delx.au - gnu-emacs/blobdiff - lisp/man.el
Replace lisp-indent-hook with lisp-indent-function throughout.
[gnu-emacs] / lisp / man.el
index 5a07045dda92ae8b0889873aeffdfc6c81dc4caa..02661c55517f4bec4508bb7f73e2f466bae03404 100644 (file)
@@ -1,6 +1,7 @@
 ;;; man.el --- browse UNIX manual pages -*- coding: iso-8859-1 -*-
 
-;; Copyright (C) 1993, 1994, 1996, 1997, 2001, 2003, 2004 Free Software Foundation, Inc.
+;; Copyright (C) 1993, 1994, 1996, 1997, 2001, 2003, 2004
+;;           Free Software Foundation, Inc.
 
 ;; Author: Barry A. Warsaw <bwarsaw@cen.com>
 ;; Maintainer: FSF
@@ -94,6 +95,7 @@
 \f
 ;;; Code:
 
+(eval-when-compile (require 'cl))
 (require 'assoc)
 (require 'button)
 
@@ -153,6 +155,11 @@ the manpage buffer."
   :type 'face
   :group 'man)
 
+(defcustom Man-reverse-face 'highlight
+  "*Face to use when fontifying reverse video."
+  :type 'face
+  :group 'man)
+
 ;; Use the value of the obsolete user option Man-notify, if set.
 (defcustom Man-notify-method (if (boundp 'Man-notify) Man-notify 'friendly)
   "*Selects the behavior when manpage is ready.
@@ -408,13 +415,15 @@ Otherwise, the value is whatever the function
 ;; buttons
 (define-button-type 'Man-xref-man-page
   'action (lambda (button) (man-follow (button-label button)))
-  'help-echo "RET, mouse-2: display this man page")
+  'follow-link t
+  'help-echo "mouse-2, RET: display this man page")
 
 (define-button-type 'Man-xref-header-file
     'action (lambda (button)
               (let ((w (button-get button 'Man-target-string)))
                 (unless (Man-view-header-file w)
                   (error "Cannot find header file: %s" w))))
+    'follow-link t
     'help-echo "mouse-2: display this header file")
 
 (define-button-type 'Man-xref-normal-file
@@ -426,7 +435,8 @@ Otherwise, the value is whatever the function
                      (view-file f)
                    (error "Cannot read a file: %s" f))
                (error "Cannot find a file: %s" f))))
-  'help-echo "mouse-2: mouse-2: display this file")
+  'follow-link t
+  'help-echo "mouse-2: display this file")
 
 \f
 ;; ======================================================================
@@ -687,6 +697,7 @@ all sections related to a subject, put something appropriate into the
       (setq buffer (generate-new-buffer bufname))
       (save-excursion
        (set-buffer buffer)
+       (setq buffer-undo-list t)
        (setq Man-original-frame (selected-frame))
        (setq Man-arguments man-args))
       (let ((process-environment (copy-sequence process-environment))
@@ -733,7 +744,9 @@ all sections related to a subject, put something appropriate into the
        (if (fboundp 'start-process)
            (set-process-sentinel
             (start-process manual-program buffer
-                           (if (eq system-type 'cygwin) shell-file-name "sh")
+                           (if (memq system-type '(cygwin windows-nt))
+                               shell-file-name
+                             "sh")
                            shell-command-switch
                            (format (Man-build-man-command) man-args))
             'Man-bgproc-sentinel)
@@ -811,53 +824,81 @@ Same for the ANSI bold and normal escape sequences."
   (interactive)
   (message "Please wait: formatting the %s man page..." Man-arguments)
   (goto-char (point-min))
-  (while (search-forward "\e[1m" nil t)
-    (delete-backward-char 4)
-    (put-text-property (point)
-                      (progn (if (search-forward "\e[0m" nil 'move)
-                                 (delete-backward-char 4))
-                             (point))
-                      'face Man-overstrike-face))
-  (if (< (buffer-size) (position-bytes (point-max)))
-      ;; Multibyte characters exist.
-      (progn
-       (goto-char (point-min))
-       (while (search-forward "__\b\b" nil t)
-         (backward-delete-char 4)
-         (put-text-property (point) (1+ (point)) 'face Man-underline-face))
-       (goto-char (point-min))
-       (while (search-forward "\b\b__" nil t)
-         (backward-delete-char 4)
-         (put-text-property (1- (point)) (point) 'face Man-underline-face))))
-  (goto-char (point-min))
-  (while (search-forward "_\b" nil t)
-    (backward-delete-char 2)
-    (put-text-property (point) (1+ (point)) 'face Man-underline-face))
-  (goto-char (point-min))
-  (while (search-forward "\b_" nil t)
-    (backward-delete-char 2)
-    (put-text-property (1- (point)) (point) 'face Man-underline-face))
-  (goto-char (point-min))
-  (while (re-search-forward "\\(.\\)\\(\b+\\1\\)+" nil t)
-    (replace-match "\\1")
-    (put-text-property (1- (point)) (point) 'face Man-overstrike-face))
-  (goto-char (point-min))
-  (while (re-search-forward "o\b\\+\\|\\+\bo" nil t)
-    (replace-match "o")
-    (put-text-property (1- (point)) (point) 'face 'bold))
-  (goto-char (point-min))
-  (while (re-search-forward "[-|]\\(\b[-|]\\)+" nil t)
-    (replace-match "+")
-    (put-text-property (1- (point)) (point) 'face 'bold))
-  (goto-char (point-min))
-  ;; Try to recognize common forms of cross references.
-  (Man-highlight-references)
-  (Man-softhyphen-to-minus)
-  (goto-char (point-min))
-  (while (re-search-forward Man-heading-regexp nil t)
-    (put-text-property (match-beginning 0)
-                      (match-end 0)
-                      'face Man-overstrike-face))
+  ;; Fontify ANSI escapes.
+  (let ((faces nil)
+       (buffer-undo-list t)
+       (start (point)))
+    ;; http://www.isthe.com/chongo/tech/comp/ansi_escapes.html
+    ;; suggests many codes, but we only handle:
+    ;; ESC [ 00 m      reset to normal display
+    ;; ESC [ 01 m      bold
+    ;; ESC [ 04 m      underline
+    ;; ESC [ 07 m      reverse-video
+    ;; ESC [ 22 m      no-bold
+    ;; ESC [ 24 m      no-underline
+    ;; ESC [ 27 m      no-reverse-video
+    (while (re-search-forward "\e\\[0?\\([1470]\\|2\\([247]\\)\\)m" nil t)
+      (if faces (put-text-property start (match-beginning 0) 'face
+                                  (if (cdr faces) faces (car faces))))
+      (setq faces
+           (cond
+            ((match-beginning 2)
+             (delq (case (char-after (match-beginning 2))
+                     (?2 Man-overstrike-face)
+                     (?4 Man-underline-face)
+                     (?7 Man-reverse-face))
+                   faces))
+            ((eq (char-after (match-beginning 1)) ?0) nil)
+            (t
+             (cons (case (char-after (match-beginning 1))
+                     (?1 Man-overstrike-face)
+                     (?4 Man-underline-face)
+                     (?7 Man-reverse-face))
+                   faces))))
+      (delete-region (match-beginning 0) (match-end 0))
+      (setq start (point))))
+  ;; Other highlighting.
+  (let ((buffer-undo-list t))
+    (if (< (buffer-size) (position-bytes (point-max)))
+       ;; Multibyte characters exist.
+       (progn
+         (goto-char (point-min))
+         (while (search-forward "__\b\b" nil t)
+           (backward-delete-char 4)
+           (put-text-property (point) (1+ (point)) 'face Man-underline-face))
+         (goto-char (point-min))
+         (while (search-forward "\b\b__" nil t)
+           (backward-delete-char 4)
+           (put-text-property (1- (point)) (point) 'face Man-underline-face))))
+    (goto-char (point-min))
+    (while (search-forward "_\b" nil t)
+      (backward-delete-char 2)
+      (put-text-property (point) (1+ (point)) 'face Man-underline-face))
+    (goto-char (point-min))
+    (while (search-forward "\b_" nil t)
+      (backward-delete-char 2)
+      (put-text-property (1- (point)) (point) 'face Man-underline-face))
+    (goto-char (point-min))
+    (while (re-search-forward "\\(.\\)\\(\b+\\1\\)+" nil t)
+      (replace-match "\\1")
+      (put-text-property (1- (point)) (point) 'face Man-overstrike-face))
+    (goto-char (point-min))
+    (while (re-search-forward "o\b\\+\\|\\+\bo" nil t)
+      (replace-match "o")
+      (put-text-property (1- (point)) (point) 'face 'bold))
+    (goto-char (point-min))
+    (while (re-search-forward "[-|]\\(\b[-|]\\)+" nil t)
+      (replace-match "+")
+      (put-text-property (1- (point)) (point) 'face 'bold))
+    (goto-char (point-min))
+    ;; Try to recognize common forms of cross references.
+    (Man-highlight-references)
+    (Man-softhyphen-to-minus)
+    (goto-char (point-min))
+    (while (re-search-forward Man-heading-regexp nil t)
+      (put-text-property (match-beginning 0)
+                        (match-end 0)
+                        'face Man-overstrike-face)))
   (message "%s man page formatted" Man-arguments))
 
 (defun Man-highlight-references ()
@@ -891,12 +932,15 @@ header file(#include <foo.h>) and files in FILES"
         'Man-target-string (match-string target-pos)
         )))))
 
-(defun Man-cleanup-manpage ()
-  "Remove overstriking and underlining from the current buffer."
-  (interactive)
+(defun Man-cleanup-manpage (&optional interactive)
+  "Remove overstriking and underlining from the current buffer.
+Normally skip any jobs that should have been done by the sed script,
+but when called interactively, do those jobs even if the sed
+script would have done them."
+  (interactive "p")
   (message "Please wait: cleaning up the %s man page..."
           Man-arguments)
-  (if (or (interactive-p) (not Man-sed-script))
+  (if (or interactive (not Man-sed-script))
       (progn
        (goto-char (point-min))
        (while (search-forward "_\b" nil t) (backward-delete-char 2))
@@ -1367,5 +1411,5 @@ Specify which REFERENCE to use; default is based on word at point."
 
 (provide 'man)
 
-;;; arch-tag: 587cda76-8e23-4594-b1f3-89b6b09a0d47
+;; arch-tag: 587cda76-8e23-4594-b1f3-89b6b09a0d47
 ;;; man.el ends here