-;;; man.el --- browse UNIX manual pages -*- coding: utf-8 -*-
+;;; man.el --- browse UNIX manual pages
-;; Copyright (C) 1993-1994, 1996-1997, 2001-2013 Free Software
+;; Copyright (C) 1993-1994, 1996-1997, 2001-2016 Free Software
;; Foundation, Inc.
;; Author: Barry A. Warsaw <bwarsaw@cen.com>
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
;; Keywords: help
;; Adapted-By: ESR, pot
;; ============= TODO ===========
;; - Add a command for printing.
;; - The awk script deletes multiple blank lines. This behavior does
-;; not allow to understand if there was indeed a blank line at the
+;; not allow one to understand if there was indeed a blank line at the
;; end or beginning of a page (after the header, or before the
;; footer). A different algorithm should be used. It is easy to
;; compute how many blank lines there are before and after the page
;;; Code:
(require 'ansi-color)
+(require 'cl-lib)
(require 'button)
(defgroup man nil
"Manpage cleaning filter command phrases.
This variable contains a list of the following form:
-'((command-string phrase-string*)*)
+ ((command-string phrase-string*)*)
Each phrase-string is concatenated onto the command-string to form a
command filter. The (standard) output (and standard error) of the Un*x
(defcustom Man-width nil
"Number of columns for which manual pages should be formatted.
-If nil, the width of the window selected at the moment of man
-invocation is used. If non-nil, the width of the frame selected
-at the moment of man invocation is used. The value also can be a
-positive integer."
+If nil, use the width of the window where the manpage is displayed.
+If non-nil, use the width of the frame where the manpage is displayed.
+The value also can be a positive integer for a fixed width."
:type '(choice (const :tag "Window width" nil)
(const :tag "Frame width" t)
- (integer :tag "Specific width" :value 65))
+ (integer :tag "Fixed width" :value 65))
:group 'man)
(defcustom Man-frame-parameters nil
"Frame parameter list for creating a new frame for a manual page."
- :type 'sexp
+ :type '(repeat (cons :format "%v"
+ (symbol :tag "Parameter")
+ (sexp :tag "Value")))
:group 'man)
(defcustom Man-downcase-section-letters-flag t
(defvar Man-reference-regexp
(concat "\\(" Man-name-regexp
- "\\(\n[ \t]+" Man-name-regexp "\\)*\\)[ \t]*(\\("
+ "\\(‐?\n[ \t]+" Man-name-regexp "\\)*\\)[ \t]*(\\("
Man-section-regexp "\\))")
"Regular expression describing a reference to another manpage.")
(defvar Man-apropos-regexp
- (concat "\\\[\\(" Man-name-regexp "\\)\\\][ \t]*(\\(" Man-section-regexp "\\))")
+ (concat "\\[\\(" Man-name-regexp "\\)\\][ \t]*(\\(" Man-section-regexp "\\))")
"Regular expression describing a reference to manpages in \"man -k output\".")
(defvar Man-synopsis-regexp "SYNOPSIS"
Otherwise, the value is whatever the function
`Man-support-local-filenames' should return.")
+(defcustom man-imenu-title "Contents"
+ "The title to use if man adds a Contents menu to the menubar."
+ :version "24.4"
+ :type 'string
+ :group 'man)
+
\f
;; other variables and keymap initializations
(defvar Man-original-frame)
(define-key map "s" 'Man-goto-see-also-section)
(define-key map "k" 'Man-kill)
(define-key map "q" 'Man-quit)
+ (define-key map "u" 'Man-update-manpage)
(define-key map "m" 'man)
;; Not all the man references get buttons currently. The text in the
;; manual page can contain references to other man pages
(define-key map "\r" 'man-follow)
(define-key map "?" 'describe-mode)
+
+ (easy-menu-define nil map
+ "`Man-mode' menu."
+ '("Man"
+ ["Next Section" Man-next-section t]
+ ["Previous Section" Man-previous-section t]
+ ["Go To Section..." Man-goto-section t]
+ ["Go To \"SEE ALSO\" Section" Man-goto-see-also-section
+ :active (cl-member Man-see-also-regexp Man--sections
+ :test #'string-match-p)]
+ ["Follow Reference..." Man-follow-manual-reference
+ :active Man--refpages
+ :help "Go to a manpage referred to in the \"SEE ALSO\" section"]
+ "--"
+ ["Next Manpage" Man-next-manpage
+ :active (> (length Man-page-list) 1)]
+ ["Previous Manpage" Man-previous-manpage
+ :active (> (length Man-page-list) 1)]
+ "--"
+ ["Man..." man t]
+ ["Kill Buffer" Man-kill t]
+ ["Quit" Man-quit t]))
map)
"Keymap for Man mode.")
;; `call-process' below sends it to /dev/null,
;; so we don't need `2>' even with DOS shells
;; which do support stderr redirection.
- ((not (fboundp 'start-process)) " %s")
+ ((not (fboundp 'make-process)) " %s")
((concat " %s 2>" null-device)))))
(flist Man-filter-list))
(while (and flist (car flist))
(with-temp-buffer
(let ((default-directory
;; Ensure that `default-directory' exists and is readable.
- (if (and (file-directory-p default-directory)
- (file-readable-p default-directory))
- default-directory
+ (if (file-accessible-directory-p default-directory)
+ default-directory
(expand-file-name "~/"))))
(ignore-errors
(call-process manual-program nil t nil "--help")))
;; Record the distance traveled.
(setq distance (- column (current-column)))
(when (looking-back
- (concat "([ \t]*\\(?:" Man-section-regexp "\\)[ \t]*)"))
+ (concat "([ \t]*\\(?:" Man-section-regexp "\\)[ \t]*)")
+ (line-beginning-position))
;; Skip section number backwards.
(goto-char (match-beginning 0))
(skip-chars-backward " \t"))
;; see this-
;; command-here(1)
;; Note: This code gets executed iff our entry is after POS.
- (when (looking-at "[ \t\r\n]+\\([-a-zA-Z0-9._+:]+\\)([0-9])")
+ (when (looking-at "‐?[ \t\r\n]+\\([-a-zA-Z0-9._+:]+\\)([0-9])")
(setq word (concat word (match-string-no-properties 1)))
;; Make sure the section number gets included by the code below.
(goto-char (match-end 1)))
foo(sec)[, bar(sec) [, ...]] [other stuff] - description
For more details and some regression tests, please see
-test/automated/man-tests.el in the emacs bzr repository."
+test/automated/man-tests.el in the emacs repository."
(goto-char (point-min))
;; See man-tests for data about which systems use which format (hopefully we
;; will be able to simplify the code if/when some of those formats aren't
;;;###autoload
(defun man (man-args)
"Get a Un*x manual page and put it in a buffer.
-This command is the top-level command in the man package. It
-runs a Un*x command to retrieve and clean a manpage in the
+This command is the top-level command in the man package.
+It runs a Un*x command to retrieve and clean a manpage in the
background and places the results in a `Man-mode' browsing
-buffer. See variable `Man-notify-method' for what happens when
-the buffer is ready. If a buffer already exists for this man
-page, it will display immediately.
+buffer. The variable `Man-width' defines the number of columns in
+formatted manual pages. The buffer is displayed immediately.
+The variable `Man-notify-method' defines how the buffer is displayed.
+If a buffer already exists for this man page, it will be displayed
+without running the man command.
For a manpage from a particular section, use either of the
following. \"cat(1)\" is how cross-references appear and is
An \"apropos\" query with -k gives a buffer of matching page
names or descriptions. The pattern argument is usually an
-\"egrep\" style regexp.
+\"grep -E\" style regexp.
-k pattern"
(error "No item under point")
(man man-args)))
+(defmacro Man-start-calling (&rest body)
+ "Start the man command in `body' after setting up the environment"
+ `(let ((process-environment (copy-sequence process-environment))
+ ;; The following is so Awk script gets \n intact
+ ;; But don't prevent decoding of the outside.
+ (coding-system-for-write 'raw-text-unix)
+ ;; We must decode the output by a coding system that the
+ ;; system's locale suggests in multibyte mode.
+ (coding-system-for-read locale-coding-system)
+ ;; Avoid possible error by using a directory that always exists.
+ (default-directory
+ (if (and (file-directory-p default-directory)
+ (not (find-file-name-handler default-directory
+ 'file-directory-p)))
+ default-directory
+ "/")))
+ ;; Prevent any attempt to use display terminal fanciness.
+ (setenv "TERM" "dumb")
+ ;; In Debian Woody, at least, we get overlong lines under X
+ ;; unless COLUMNS or MANWIDTH is set. This isn't a problem on
+ ;; a tty. man(1) says:
+ ;; MANWIDTH
+ ;; If $MANWIDTH is set, its value is used as the line
+ ;; length for which manual pages should be formatted.
+ ;; If it is not set, manual pages will be formatted
+ ;; with a line length appropriate to the current ter-
+ ;; minal (using an ioctl(2) if available, the value of
+ ;; $COLUMNS, or falling back to 80 characters if nei-
+ ;; ther is available).
+ (when (or window-system
+ (not (or (getenv "MANWIDTH") (getenv "COLUMNS"))))
+ ;; Since the page buffer is displayed beforehand,
+ ;; we can select its window and get the window/frame width.
+ (setenv "COLUMNS" (number-to-string
+ (cond
+ ((and (integerp Man-width) (> Man-width 0))
+ Man-width)
+ (Man-width
+ (if (window-live-p (get-buffer-window (current-buffer) t))
+ (with-selected-window (get-buffer-window (current-buffer) t)
+ (frame-width))
+ (frame-width)))
+ (t
+ (if (window-live-p (get-buffer-window (current-buffer) t))
+ (with-selected-window (get-buffer-window (current-buffer) t)
+ (window-width))
+ (window-width)))))))
+ ;; Since man-db 2.4.3-1, man writes plain text with no escape
+ ;; sequences when stdout is not a tty. In 2.5.0, the following
+ ;; env-var was added to allow control of this (see Debian Bug#340673).
+ (setenv "MAN_KEEP_FORMATTING" "1")
+ ,@body))
+
(defun Man-getpage-in-background (topic)
"Use TOPIC to build and fire off the manpage and cleaning command.
Return the buffer in which the manpage will appear."
(message "Invoking %s %s in the background" manual-program man-args)
(setq buffer (generate-new-buffer bufname))
(with-current-buffer buffer
+ (Man-notify-when-ready buffer)
(setq buffer-undo-list t)
(setq Man-original-frame (selected-frame))
- (setq Man-arguments man-args))
- (let ((process-environment (copy-sequence process-environment))
- ;; The following is so Awk script gets \n intact
- ;; But don't prevent decoding of the outside.
- (coding-system-for-write 'raw-text-unix)
- ;; We must decode the output by a coding system that the
- ;; system's locale suggests in multibyte mode.
- (coding-system-for-read
- (if (default-value 'enable-multibyte-characters)
- locale-coding-system 'raw-text-unix))
- ;; Avoid possible error by using a directory that always exists.
- (default-directory
- (if (and (file-directory-p default-directory)
- (not (find-file-name-handler default-directory
- 'file-directory-p)))
- default-directory
- "/")))
- ;; Prevent any attempt to use display terminal fanciness.
- (setenv "TERM" "dumb")
- ;; In Debian Woody, at least, we get overlong lines under X
- ;; unless COLUMNS or MANWIDTH is set. This isn't a problem on
- ;; a tty. man(1) says:
- ;; MANWIDTH
- ;; If $MANWIDTH is set, its value is used as the line
- ;; length for which manual pages should be formatted.
- ;; If it is not set, manual pages will be formatted
- ;; with a line length appropriate to the current ter-
- ;; minal (using an ioctl(2) if available, the value of
- ;; $COLUMNS, or falling back to 80 characters if nei-
- ;; ther is available).
- (when (or window-system
- (not (or (getenv "MANWIDTH") (getenv "COLUMNS"))))
- ;; This isn't strictly correct, since we don't know how
- ;; the page will actually be displayed, but it seems
- ;; reasonable.
- (setenv "COLUMNS" (number-to-string
- (cond
- ((and (integerp Man-width) (> Man-width 0))
- Man-width)
- (Man-width (frame-width))
- ((window-width))))))
- ;; Since man-db 2.4.3-1, man writes plain text with no escape
- ;; sequences when stdout is not a tty. In 2.5.0, the following
- ;; env-var was added to allow control of this (see Debian Bug#340673).
- (setenv "MAN_KEEP_FORMATTING" "1")
- (if (fboundp 'start-process)
- (set-process-sentinel
- (start-process manual-program buffer
- (if (memq system-type '(cygwin windows-nt))
- shell-file-name
- "sh")
- shell-command-switch
- (format (Man-build-man-command) man-args))
- 'Man-bgproc-sentinel)
- (let ((exit-status
- (call-process shell-file-name nil (list buffer nil) nil
- shell-command-switch
- (format (Man-build-man-command) man-args)))
- (msg ""))
- (or (and (numberp exit-status)
- (= exit-status 0))
- (and (numberp exit-status)
- (setq msg
- (format "exited abnormally with code %d"
- exit-status)))
- (setq msg exit-status))
- (Man-bgproc-sentinel bufname msg)))))
+ (setq Man-arguments man-args)
+ (Man-mode)
+ (setq mode-line-process
+ (concat " " (propertize (if Man-fontify-manpage-flag
+ "[formatting...]"
+ "[cleaning...]")
+ 'face 'mode-line-emphasis)))
+ (Man-start-calling
+ (if (fboundp 'make-process)
+ (let ((proc (start-process
+ manual-program buffer
+ (if (memq system-type '(cygwin windows-nt))
+ shell-file-name
+ "sh")
+ shell-command-switch
+ (format (Man-build-man-command) man-args))))
+ (set-process-sentinel proc 'Man-bgproc-sentinel)
+ (set-process-filter proc 'Man-bgproc-filter))
+ (let* ((inhibit-read-only t)
+ (exit-status
+ (call-process shell-file-name nil (list buffer nil) nil
+ shell-command-switch
+ (format (Man-build-man-command) man-args)))
+ (msg ""))
+ (or (and (numberp exit-status)
+ (= exit-status 0))
+ (and (numberp exit-status)
+ (setq msg
+ (format "exited abnormally with code %d"
+ exit-status)))
+ (setq msg exit-status))
+ (if Man-fontify-manpage-flag
+ (Man-fontify-manpage)
+ (Man-cleanup-manpage))
+ (Man-bgproc-sentinel bufname msg))))))
buffer))
+(defun Man-update-manpage ()
+ "Reformat current manpage by calling the man command again synchronously."
+ (interactive)
+ (when (eq Man-arguments nil)
+ ;;this shouldn't happen unless it is not in a Man buffer."
+ (error "Man-arguments not initialized"))
+ (let ((old-pos (point))
+ (text (current-word))
+ (old-size (buffer-size))
+ (inhibit-read-only t)
+ (buffer-read-only nil))
+ (erase-buffer)
+ (Man-start-calling
+ (call-process shell-file-name nil (list (current-buffer) nil) nil
+ shell-command-switch
+ (format (Man-build-man-command) Man-arguments)))
+ (if Man-fontify-manpage-flag
+ (Man-fontify-manpage)
+ (Man-cleanup-manpage))
+ (goto-char old-pos)
+ ;;restore the point, not strictly right.
+ (unless (or (eq text nil) (= old-size (buffer-size)))
+ (let ((case-fold-search nil))
+ (if (> old-size (buffer-size))
+ (search-backward text nil t))
+ (search-forward text nil t)))))
+
(defun Man-notify-when-ready (man-buffer)
"Notify the user when MAN-BUFFER is ready.
See the variable `Man-notify-method' for the different notification behaviors."
"Convert overstriking and underlining to the correct fonts.
Same for the ANSI bold and normal escape sequences."
(interactive)
- (message "Please wait: formatting the %s man page..." Man-arguments)
(goto-char (point-min))
;; Fontify ANSI escapes.
(let ((ansi-color-apply-face-function
;; Multibyte characters exist.
(progn
(goto-char (point-min))
- (while (search-forward "__\b\b" nil t)
+ (while (and (search-forward "__\b\b" nil t) (not (eobp)))
(backward-delete-char 4)
(put-text-property (point) (1+ (point)) 'face 'Man-underline))
(goto-char (point-min))
(backward-delete-char 4)
(put-text-property (1- (point)) (point) 'face 'Man-underline))))
(goto-char (point-min))
- (while (search-forward "_\b" nil t)
+ (while (and (search-forward "_\b" nil t) (not (eobp)))
(backward-delete-char 2)
(put-text-property (point) (1+ (point)) 'face 'Man-underline))
(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)))
- (message "%s man page formatted" (Man-page-from-arguments Man-arguments)))
+ 'face 'Man-overstrike))))
(defun Man-highlight-references (&optional xref-man-type)
"Highlight the references on mouse-over.
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 (not Man-sed-script))
(progn
(goto-char (point-min))
;; their preceding chars (but don't put Man-overstrike). (Bug#5566)
(goto-char (point-min))
(while (re-search-forward ".\b" nil t) (backward-delete-char 2))
- (Man-softhyphen-to-minus)
- (message "%s man page cleaned up" Man-arguments))
+ (Man-softhyphen-to-minus))
+
+(defun Man-bgproc-filter (process string)
+ "Manpage background process filter.
+When manpage command is run asynchronously, PROCESS is the process
+object for the manpage command; when manpage command is run
+synchronously, PROCESS is the name of the buffer where the manpage
+command is run. Second argument STRING is the entire string of output."
+ (save-excursion
+ (let ((Man-buffer (process-buffer process)))
+ (if (null (buffer-name Man-buffer)) ;; deleted buffer
+ (set-process-buffer process nil)
+
+ (with-current-buffer Man-buffer
+ (let ((inhibit-read-only t)
+ (beg (marker-position (process-mark process))))
+ (save-excursion
+ (goto-char beg)
+ (insert string)
+ (save-restriction
+ (narrow-to-region
+ (save-excursion
+ (goto-char beg)
+ (line-beginning-position))
+ (point))
+ (if Man-fontify-manpage-flag
+ (Man-fontify-manpage)
+ (Man-cleanup-manpage)))
+ (set-marker (process-mark process) (point-max)))))))))
(defun Man-bgproc-sentinel (process msg)
"Manpage background process sentinel.
(set-process-buffer process nil))
(with-current-buffer Man-buffer
- (let ((case-fold-search nil))
- (goto-char (point-min))
- (cond ((or (looking-at "No \\(manual \\)*entry for")
- (looking-at "[^\n]*: nothing appropriate$"))
- (setq err-mess (buffer-substring (point)
- (progn
- (end-of-line) (point)))
- delete-buff t))
-
- ;; "-k foo", successful exit, but no output (from man-db)
- ;; ENHANCE-ME: share the check for -k with
- ;; `Man-highlight-references'. The \\s- bits here are
- ;; meant to allow for multiple options with -k among them.
- ((and (string-match "\\(\\`\\|\\s-\\)-k\\s-" Man-arguments)
- (eq (process-status process) 'exit)
- (= (process-exit-status process) 0)
- (= (point-min) (point-max)))
- (setq err-mess (format "%s: no matches" Man-arguments)
- delete-buff t))
-
- ((or (stringp process)
- (not (and (eq (process-status process) 'exit)
- (= (process-exit-status process) 0))))
- (or (zerop (length msg))
- (progn
- (setq err-mess
- (concat (buffer-name Man-buffer)
- ": process "
- (let ((eos (1- (length msg))))
- (if (= (aref msg eos) ?\n)
- (substring msg 0 eos) msg))))
- (goto-char (point-max))
- (insert (format "\nprocess %s" msg))))
- ))
- (if delete-buff
- (kill-buffer Man-buffer)
- (if Man-fontify-manpage-flag
- (Man-fontify-manpage)
- (Man-cleanup-manpage))
-
- (run-hooks 'Man-cooked-hook)
- (Man-mode)
-
- (if (not Man-page-list)
- (let ((args Man-arguments))
- (kill-buffer (current-buffer))
- (user-error "Can't find the %s manpage"
- (Man-page-from-arguments args)))
- (set-buffer-modified-p nil))))
- ;; Restore case-fold-search before calling
- ;; Man-notify-when-ready because it may switch buffers.
-
- (if (not delete-buff)
- (Man-notify-when-ready Man-buffer))
+ (save-excursion
+ (let ((case-fold-search nil))
+ (goto-char (point-min))
+ (cond ((or (looking-at "No \\(manual \\)*entry for")
+ (looking-at "[^\n]*: nothing appropriate$"))
+ (setq err-mess (buffer-substring (point)
+ (progn
+ (end-of-line) (point)))
+ delete-buff t))
+
+ ;; "-k foo", successful exit, but no output (from man-db)
+ ;; ENHANCE-ME: share the check for -k with
+ ;; `Man-highlight-references'. The \\s- bits here are
+ ;; meant to allow for multiple options with -k among them.
+ ((and (string-match "\\(\\`\\|\\s-\\)-k\\s-" Man-arguments)
+ (eq (process-status process) 'exit)
+ (= (process-exit-status process) 0)
+ (= (point-min) (point-max)))
+ (setq err-mess (format "%s: no matches" Man-arguments)
+ delete-buff t))
+
+ ((or (stringp process)
+ (not (and (eq (process-status process) 'exit)
+ (= (process-exit-status process) 0))))
+ (or (zerop (length msg))
+ (progn
+ (setq err-mess
+ (concat (buffer-name Man-buffer)
+ ": process "
+ (let ((eos (1- (length msg))))
+ (if (= (aref msg eos) ?\n)
+ (substring msg 0 eos) msg))))
+ (goto-char (point-max))
+ (insert (format "\nprocess %s" msg))))
+ ))
+ (if delete-buff
+ (if (window-live-p (get-buffer-window Man-buffer t))
+ (quit-restore-window
+ (get-buffer-window Man-buffer t) 'kill)
+ (kill-buffer Man-buffer))
+
+ (run-hooks 'Man-cooked-hook)
+
+ (Man-build-page-list)
+ (Man-strip-page-headers)
+ (Man-unindent)
+ (Man-goto-page 1 t)
+
+ (if (not Man-page-list)
+ (let ((args Man-arguments))
+ (if (window-live-p (get-buffer-window (current-buffer) t))
+ (quit-restore-window
+ (get-buffer-window (current-buffer) t) 'kill)
+ (kill-buffer (current-buffer)))
+ ;; Entries hyphenated due to the window's width
+ ;; won't be found in the man database, so remove
+ ;; the hyphenation -- assuming Groff hyphenates
+ ;; either with hyphen-minus (ASCII 45, #x2d),
+ ;; hyphen (#x2010) or soft hyphen (#xad) -- and
+ ;; look again.
+ (if (string-match "[-‐]" args)
+ (let ((str (replace-match "" nil nil args)))
+ (Man-getpage-in-background str))
+ (message "Can't find the %s manpage"
+ (Man-page-from-arguments args))))
+
+ (if Man-fontify-manpage-flag
+ (message "%s man page formatted"
+ (Man-page-from-arguments Man-arguments))
+ (message "%s man page cleaned up"
+ (Man-page-from-arguments Man-arguments)))
+ (unless (and (processp process)
+ (not (eq (process-status process) 'exit)))
+ (setq mode-line-process nil))
+ (set-buffer-modified-p nil)))))
(if err-mess
- (error "%s" err-mess))
+ (message "%s" err-mess))
))))
(defun Man-page-from-arguments (args)
The following variables may be of some use. Try
\"\\[describe-variable] <variable-name> RET\" for more information:
-`Man-notify-method' What happens when manpage formatting is done.
+`Man-notify-method' What happens when manpage is ready to display.
`Man-downcase-section-letters-flag' Force section letters to lower case.
`Man-circular-pages-flag' Treat multiple manpage list as circular.
`Man-section-translations-alist' List of section numbers and their Un*x equiv.
(buffer-disable-undo)
(auto-fill-mode -1)
(setq imenu-generic-expression (list (list nil Man-heading-regexp 0)))
+ (imenu-add-to-menubar man-imenu-title)
(set (make-local-variable 'outline-regexp) Man-heading-regexp)
(set (make-local-variable 'outline-level) (lambda () 1))
(set (make-local-variable 'bookmark-make-record-function)
- 'Man-bookmark-make-record)
- (Man-build-page-list)
- (Man-strip-page-headers)
- (Man-unindent)
- (Man-goto-page 1 t))
+ 'Man-bookmark-make-record))
(defsubst Man-build-section-alist ()
"Build the list of manpage sections."
(page-end (point-max))
(header ""))
(goto-char page-start)
- ;; (switch-to-buffer (current-buffer))(debug)
(while (not (eobp))
(setq header
(if (looking-at Man-page-header-regexp)