summaryrefslogtreecommitdiff
path: root/lisp/man.el
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@raeburn.org>2001-07-06 08:41:36 +0000
committerKen Raeburn <raeburn@raeburn.org>2001-07-06 08:41:36 +0000
commitad782551325b7c694ee234b5ff4c5688d90e561c (patch)
treef4355f141142b6018183518fa1761b53e295ede2 /lisp/man.el
parentf25cfe53951f57e1b2c3972877297df3d86bb980 (diff)
downloademacs-ad782551325b7c694ee234b5ff4c5688d90e561c.tar.gz
properly mark Attic files as deleted
Diffstat (limited to 'lisp/man.el')
-rw-r--r--lisp/man.el1186
1 files changed, 0 insertions, 1186 deletions
diff --git a/lisp/man.el b/lisp/man.el
deleted file mode 100644
index 2454b48ded9..00000000000
--- a/lisp/man.el
+++ /dev/null
@@ -1,1186 +0,0 @@
-;;; man.el --- browse UNIX manual pages
-
-;; Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
-
-;; Author: Barry A. Warsaw <bwarsaw@cen.com>
-;; Maintainer: FSF
-;; Keywords: help
-;; Adapted-By: ESR, pot
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs 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.
-
-;; GNU Emacs 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 GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; This code provides a function, `man', with which you can browse
-;; UNIX manual pages. Formatting is done in background so that you
-;; can continue to use your Emacs while processing is going on.
-;;
-;; The mode also supports hypertext-like following of manual page SEE
-;; ALSO references, and other features. See below or do `?' in a
-;; manual page buffer for details.
-
-;; ========== Credits and History ==========
-;; In mid 1991, several people posted some interesting improvements to
-;; man.el from the standard emacs 18.57 distribution. I liked many of
-;; these, but wanted everything in one single package, so I decided
-;; to incorporate them into a single manual browsing mode. While
-;; much of the code here has been rewritten, and some features added,
-;; these folks deserve lots of credit for providing the initial
-;; excellent packages on which this one is based.
-
-;; Nick Duffek <duffek@chaos.cs.brandeis.edu>, posted a very nice
-;; improvement which retrieved and cleaned the manpages in a
-;; background process, and which correctly deciphered such options as
-;; man -k.
-
-;; Eric Rose <erose@jessica.stanford.edu>, submitted manual.el which
-;; provided a very nice manual browsing mode.
-
-;; This package was available as `superman.el' from the LCD package
-;; for some time before it was accepted into Emacs 19. The entry
-;; point and some other names have been changed to make it a drop-in
-;; replacement for the old man.el package.
-
-;; Francesco Potorti` <pot@cnuce.cnr.it> cleaned it up thoroughly,
-;; making it faster, more robust and more tolerant of different
-;; systems' man idiosyncrasies.
-
-;; ========== Features ==========
-;; + Runs "man" in the background and pipes the results through a
-;; series of sed and awk scripts so that all retrieving and cleaning
-;; is done in the background. The cleaning commands are configurable.
-;; + Syntax is the same as Un*x man
-;; + Functionality is the same as Un*x man, including "man -k" and
-;; "man <section>", etc.
-;; + Provides a manual browsing mode with keybindings for traversing
-;; the sections of a manpage, following references in the SEE ALSO
-;; section, and more.
-;; + Multiple manpages created with the same man command are put into
-;; a narrowed buffer circular list.
-
-;; ============= TODO ===========
-;; - Add a command for printing.
-;; - The awk script deletes multiple blank lines. This behaviour does
-;; not allow 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
-;; headers, and after the page footer. But it is possible to compute
-;; the number of blank lines before the page footer by euristhics
-;; only. Is it worth doing?
-;; - Allow a user option to mean that all the manpages should go in
-;; the same buffer, where they can be browsed with M-n and M-p.
-;; - Allow completion on the manpage name when calling man. This
-;; requires a reliable list of places where manpages can be found. The
-;; drawback would be that if the list is not complete, the user might
-;; be led to believe that the manpages in the missing directories do
-;; not exist.
-
-
-;;; Code:
-
-(require 'assoc)
-
-;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
-;; empty defvars (keep the compiler quiet)
-
-(defgroup man nil
- "Browse UNIX manual pages."
- :prefix "Man-"
- :group 'help)
-
-
-(defvar Man-notify)
-(defvar Man-current-page)
-(defvar Man-page-list)
-(defcustom Man-filter-list nil
- "*Manpage cleaning filter command phrases.
-This variable contains a list of the following form:
-
-'((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
-man command is piped through each command filter in the order the
-commands appear in the association list. The final output is placed in
-the manpage buffer."
- :type '(repeat (list (string :tag "Command String")
- (repeat :inline t
- (string :tag "Phrase String"))))
- :group 'man)
-
-(defvar Man-original-frame)
-(defvar Man-arguments)
-(defvar Man-sections-alist)
-(defvar Man-refpages-alist)
-(defvar Man-uses-untabify-flag t
- "Non-nil means use `untabify' instead of `Man-untabify-command'.")
-(defvar Man-page-mode-string)
-(defvar Man-sed-script nil
- "Script for sed to nuke backspaces and ANSI codes from manpages.")
-
-;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
-;; user variables
-
-(defcustom Man-fontify-manpage-flag t
- "*Non-nil means make up the manpage with fonts."
- :type 'boolean
- :group 'man)
-
-(defcustom Man-overstrike-face 'bold
- "*Face to use when fontifying overstrike."
- :type 'face
- :group 'man)
-
-(defcustom Man-underline-face 'underline
- "*Face to use when fontifying underlining."
- :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.
-This variable may have one of the following values, where (sf) means
-that the frames are switched, so the manpage is displayed in the frame
-where the man command was called from:
-
-newframe -- put the manpage in its own frame (see `Man-frame-parameters')
-pushy -- make the manpage the current buffer in the current window
-bully -- make the manpage the current buffer and only window (sf)
-aggressive -- make the manpage the current buffer in the other window (sf)
-friendly -- display manpage in the other window but don't make current (sf)
-polite -- don't display manpage, but prints message and beep when ready
-quiet -- like `polite', but don't beep
-meek -- make no indication that the manpage is ready
-
-Any other value of `Man-notify-method' is equivalent to `meek'."
- :type '(radio (const newframe) (const pushy) (const bully)
- (const aggressive) (const friendly)
- (const polite) (const quiet) (const meek))
- :group 'man)
-
-(defcustom Man-frame-parameters nil
- "*Frame parameter list for creating a new frame for a manual page."
- :type 'sexp
- :group 'man)
-
-(defcustom Man-downcase-section-letters-flag t
- "*Non-nil means letters in sections are converted to lower case.
-Some Un*x man commands can't handle uppercase letters in sections, for
-example \"man 2V chmod\", but they are often displayed in the manpage
-with the upper case letter. When this variable is t, the section
-letter (e.g., \"2V\") is converted to lowercase (e.g., \"2v\") before
-being sent to the man background process."
- :type 'boolean
- :group 'man)
-
-(defcustom Man-circular-pages-flag t
- "*Non-nil means the manpage list is treated as circular for traversal."
- :type 'boolean
- :group 'man)
-
-(defcustom Man-section-translations-alist
- (list
- '("3C++" . "3")
- ;; Some systems have a real 3x man section, so let's comment this.
- ;; '("3X" . "3") ; Xlib man pages
- '("3X11" . "3")
- '("1-UCB" . ""))
- "*Association list of bogus sections to real section numbers.
-Some manpages (e.g. the Sun C++ 2.1 manpages) have section numbers in
-their references which Un*x `man' does not recognize. This
-association list is used to translate those sections, when found, to
-the associated section number."
- :type '(repeat (cons (string :tag "Bogus Section")
- (string :tag "Real Section")))
- :group 'man)
-
-(defvar manual-program "man"
- "The name of the program that produces man pages.")
-
-(defvar Man-untabify-command "pr"
- "Command used for untabifying.")
-
-(defvar Man-untabify-command-args (list "-t" "-e")
- "List of arguments to be passed to `Man-untabify-command' (which see).")
-
-(defvar Man-sed-command "sed"
- "Command used for processing sed scripts.")
-
-(defvar Man-awk-command "awk"
- "Command used for processing awk scripts.")
-
-(defvar Man-mode-line-format
- '("-"
- mode-line-mule-info
- mode-line-modified
- mode-line-frame-identification
- mode-line-buffer-identification " "
- global-mode-string
- " " Man-page-mode-string
- " %[(" mode-name mode-line-process minor-mode-alist "%n)%]--"
- (line-number-mode "L%l--")
- (column-number-mode "C%c--")
- (-3 . "%p") "-%-")
- "Mode line format for manual mode buffer.")
-
-(defvar Man-mode-map nil
- "Keymap for Man mode.")
-
-(defvar Man-mode-hook nil
- "Hook run when Man mode is enabled.")
-
-(defvar Man-cooked-hook nil
- "Hook run after removing backspaces but before `Man-mode' processing.")
-
-(defvar Man-name-regexp "[-a-zA-Z0-9_][-a-zA-Z0-9_.]*"
- "Regular expression describing the name of a manpage (without section).")
-
-(defvar Man-section-regexp "[0-9][a-zA-Z+]*\\|[LNln]"
- "Regular expression describing a manpage section within parentheses.")
-
-(defvar Man-page-header-regexp
- (if (and (string-match "-solaris2\\." system-configuration)
- (not (string-match "-solaris2\\.[123435]$" system-configuration)))
- (concat "^[-A-Za-z0-9_].*[ \t]\\(" Man-name-regexp
- "(\\(" Man-section-regexp "\\))\\)$")
- (concat "^[ \t]*\\(" Man-name-regexp
- "(\\(" Man-section-regexp "\\))\\).*\\1"))
- "Regular expression describing the heading of a page.")
-
-(defvar Man-heading-regexp "^\\([A-Z][A-Z ]+\\)$"
- "Regular expression describing a manpage heading entry.")
-
-(defvar Man-see-also-regexp "SEE ALSO"
- "Regular expression for SEE ALSO heading (or your equivalent).
-This regexp should not start with a `^' character.")
-
-(defvar Man-first-heading-regexp "^[ \t]*NAME$\\|^[ \t]*No manual entry fo.*$"
- "Regular expression describing first heading on a manpage.
-This regular expression should start with a `^' character.")
-
-(defvar Man-reference-regexp
- (concat "\\(" Man-name-regexp "\\)(\\(" Man-section-regexp "\\))")
- "Regular expression describing a reference to another manpage.")
-
-;; This includes the section as an optional part to catch hyphenated
-;; refernces to manpages.
-(defvar Man-hyphenated-reference-regexp
- (concat "\\(" Man-name-regexp "\\)\\((\\(" Man-section-regexp "\\))\\)?")
- "Regular expression describing a reference in the SEE ALSO section.")
-
-(defvar Man-switches ""
- "Switches passed to the man command, as a single string.")
-
-(defvar Man-specified-section-option
- (if (string-match "-solaris[0-9.]*$" system-configuration)
- "-s"
- "")
- "Option that indicates a specified a manual section name.")
-
-;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-;; end user variables
-
-;; other variables and keymap initializations
-(make-variable-buffer-local 'Man-sections-alist)
-(make-variable-buffer-local 'Man-refpages-alist)
-(make-variable-buffer-local 'Man-page-list)
-(make-variable-buffer-local 'Man-current-page)
-(make-variable-buffer-local 'Man-page-mode-string)
-(make-variable-buffer-local 'Man-original-frame)
-(make-variable-buffer-local 'Man-arguments)
-
-(setq-default Man-sections-alist nil)
-(setq-default Man-refpages-alist nil)
-(setq-default Man-page-list nil)
-(setq-default Man-current-page 0)
-(setq-default Man-page-mode-string "1 of 1")
-
-(defconst Man-sysv-sed-script "\
-/\b/ { s/_\b//g
- s/\b_//g
- s/o\b+/o/g
- s/+\bo/o/g
- :ovstrk
- s/\\(.\\)\b\\1/\\1/g
- t ovstrk
- }
-/\e\\[[0-9][0-9]*m/ s///g"
- "Script for sysV-like sed to nuke backspaces and ANSI codes from manpages.")
-
-(defconst Man-berkeley-sed-script "\
-/\b/ { s/_\b//g\\
- s/\b_//g\\
- s/o\b+/o/g\\
- s/+\bo/o/g\\
- :ovstrk\\
- s/\\(.\\)\b\\1/\\1/g\\
- t ovstrk\\
- }\\
-/\e\\[[0-9][0-9]*m/ s///g"
- "Script for berkeley-like sed to nuke backspaces and ANSI codes from manpages.")
-
-(defvar man-mode-syntax-table
- (let ((table (copy-syntax-table (standard-syntax-table))))
- (modify-syntax-entry ?. "w" table)
- (modify-syntax-entry ?_ "w" table)
- table)
- "Syntax table used in Man mode buffers.")
-
-(if Man-mode-map
- nil
- (setq Man-mode-map (make-keymap))
- (suppress-keymap Man-mode-map)
- (define-key Man-mode-map " " 'scroll-up)
- (define-key Man-mode-map "\177" 'scroll-down)
- (define-key Man-mode-map "n" 'Man-next-section)
- (define-key Man-mode-map "p" 'Man-previous-section)
- (define-key Man-mode-map "\en" 'Man-next-manpage)
- (define-key Man-mode-map "\ep" 'Man-previous-manpage)
- (define-key Man-mode-map ">" 'end-of-buffer)
- (define-key Man-mode-map "<" 'beginning-of-buffer)
- (define-key Man-mode-map "." 'beginning-of-buffer)
- (define-key Man-mode-map "r" 'Man-follow-manual-reference)
- (define-key Man-mode-map "g" 'Man-goto-section)
- (define-key Man-mode-map "s" 'Man-goto-see-also-section)
- (define-key Man-mode-map "k" 'Man-kill)
- (define-key Man-mode-map "q" 'Man-quit)
- (define-key Man-mode-map "m" 'man)
- (define-key Man-mode-map "\r" 'man-follow)
- (define-key Man-mode-map "?" 'describe-mode)
- )
-
-
-;; ======================================================================
-;; utilities
-
-(defun Man-init-defvars ()
- "Used for initialising variables based on display's color support.
-This is necessary if one wants to dump man.el with Emacs."
-
- ;; Avoid possible error in call-process by using a directory that must exist.
- (let ((default-directory "/"))
- (setq Man-sed-script
- (cond
- (Man-fontify-manpage-flag
- nil)
- ((= 0 (call-process Man-sed-command nil nil nil Man-sysv-sed-script))
- Man-sysv-sed-script)
- ((= 0 (call-process Man-sed-command nil nil nil Man-berkeley-sed-script))
- Man-berkeley-sed-script)
- (t
- nil))))
-
- (setq Man-filter-list
- ;; Avoid trailing nil which confuses customize.
- (apply 'list
- (cons
- Man-sed-command
- (list
- (if Man-sed-script
- (concat "-e '" Man-sed-script "'")
- "")
- "-e '/^[\001-\032][\001-\032]*$/d'"
- "-e '/\e[789]/s///g'"
- "-e '/Reformatting page. Wait/d'"
- "-e '/Reformatting entry. Wait/d'"
- "-e '/^[ \t]*Hewlett-Packard[ \t]Company[ \t]*-[ \t][0-9]*[ \t]-/d'"
- "-e '/^[ \t]*Hewlett-Packard[ \t]*-[ \t][0-9]*[ \t]-.*$/d'"
- "-e '/^[ \t][ \t]*-[ \t][0-9]*[ \t]-[ \t]*Formatted:.*[0-9]$/d'"
- "-e '/^[ \t]*Page[ \t][0-9]*.*(printed[ \t][0-9\\/]*)$/d'"
- "-e '/^Printed[ \t][0-9].*[0-9]$/d'"
- "-e '/^[ \t]*X[ \t]Version[ \t]1[01].*Release[ \t][0-9]/d'"
- "-e '/^[A-Za-z].*Last[ \t]change:/d'"
- "-e '/^Sun[ \t]Release[ \t][0-9].*[0-9]$/d'"
- "-e '/[ \t]*Copyright [0-9]* UNIX System Laboratories, Inc.$/d'"
- "-e '/^[ \t]*Rev\\..*Page [0-9][0-9]*$/d'"
- ))
- (cons
- Man-awk-command
- (list
- "'\n"
- "BEGIN { blankline=0; anonblank=0; }\n"
- "/^$/ { if (anonblank==0) next; }\n"
- "{ anonblank=1; }\n"
- "/^$/ { blankline++; next; }\n"
- "{ if (blankline>0) { print \"\"; blankline=0; } print $0; }\n"
- "'"
- ))
- (if (not Man-uses-untabify-flag)
- ;; The outer list will be stripped off by apply.
- (list (cons
- Man-untabify-command
- Man-untabify-command-args))
- )))
-)
-
-(defsubst Man-match-substring (&optional n string)
- "Return the substring matched by the last search.
-Optional arg N means return the substring matched by the Nth paren
-grouping. Optional second arg STRING means return a substring from
-that string instead of from the current buffer."
- (if (null n) (setq n 0))
- (if string
- (substring string (match-beginning n) (match-end n))
- (buffer-substring (match-beginning n) (match-end n))))
-
-(defsubst Man-make-page-mode-string ()
- "Formats part of the mode line for Man mode."
- (format "%s page %d of %d"
- (or (nth 2 (nth (1- Man-current-page) Man-page-list))
- "")
- Man-current-page
- (length Man-page-list)))
-
-(defsubst Man-build-man-command ()
- "Builds the entire background manpage and cleaning command."
- (let ((command (concat manual-program " " Man-switches
- ; Stock MS-DOS shells cannot redirect stderr;
- ; `call-process' below sends it to /dev/null,
- ; so we don't need `2>' even with DOS shells
- ; which do support stderr redirection.
- (if (not (fboundp 'start-process))
- " %s"
- (concat " %s 2>" null-device))))
- (flist Man-filter-list))
- (while (and flist (car flist))
- (let ((pcom (car (car flist)))
- (pargs (cdr (car flist))))
- (setq command
- (concat command " | " pcom " "
- (mapconcat (lambda (phrase)
- (if (not (stringp phrase))
- (error "Malformed Man-filter-list"))
- phrase)
- pargs " ")))
- (setq flist (cdr flist))))
- command))
-
-(defun Man-translate-references (ref)
- "Translates REF from \"chmod(2V)\" to \"2v chmod\" style.
-Leave it as is if already in that style. Possibly downcase and
-translate the section (see the Man-downcase-section-letters-flag
-and the Man-section-translations-alist variables)."
- (let ((name "")
- (section "")
- (slist Man-section-translations-alist))
- (cond
- ;; "chmod(2V)" case ?
- ((string-match (concat "^" Man-reference-regexp "$") ref)
- (setq name (Man-match-substring 1 ref)
- section (Man-match-substring 2 ref)))
- ;; "2v chmod" case ?
- ((string-match (concat "^\\(" Man-section-regexp
- "\\) +\\(" Man-name-regexp "\\)$") ref)
- (setq name (Man-match-substring 2 ref)
- section (Man-match-substring 1 ref))))
- (if (string= name "")
- ref ; Return the reference as is
- (if Man-downcase-section-letters-flag
- (setq section (downcase section)))
- (while slist
- (let ((s1 (car (car slist)))
- (s2 (cdr (car slist))))
- (setq slist (cdr slist))
- (if Man-downcase-section-letters-flag
- (setq s1 (downcase s1)))
- (if (not (string= s1 section)) nil
- (setq section (if Man-downcase-section-letters-flag
- (downcase s2)
- s2)
- slist nil))))
- (concat Man-specified-section-option section " " name))))
-
-
-;; ======================================================================
-;; default man entry: get word under point
-
-(defsubst Man-default-man-entry ()
- "Make a guess at a default manual entry.
-This guess is based on the text surrounding the cursor."
- (let (word)
- (save-excursion
- ;; Default man entry title is any word the cursor is on, or if
- ;; cursor not on a word, then nearest preceding word.
- (setq word (current-word))
- (if (string-match "[._]+$" word)
- (setq word (substring word 0 (match-beginning 0))))
- ;; If looking at something like ioctl(2) or brc(1M), include the
- ;; section number in the returned value. Remove text properties.
- (forward-word 1)
- ;; Use `format' here to clear any text props from `word'.
- (format "%s%s"
- word
- (if (looking-at
- (concat "[ \t]*([ \t]*\\(" Man-section-regexp "\\)[ \t]*)"))
- (format "(%s)" (Man-match-substring 1))
- "")))))
-
-
-;; ======================================================================
-;; Top level command and background process sentinel
-
-;; For compatibility with older versions.
-;;;###autoload
-(defalias 'manual-entry 'man)
-
-;;;###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 background and places the
-results in a Man mode (manpage 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.
-
-To specify a man page from a certain section, type SUBJECT(SECTION) or
-SECTION SUBJECT when prompted for a manual entry."
- (interactive
- (list (let* ((default-entry (Man-default-man-entry))
- (input (read-string
- (format "Manual entry%s: "
- (if (string= default-entry "")
- ""
- (format " (default %s)" default-entry))))))
- (if (string= input "")
- (if (string= default-entry "")
- (error "No man args given")
- default-entry)
- input))))
-
- ;; Possibly translate the "subject(section)" syntax into the
- ;; "section subject" syntax and possibly downcase the section.
- (setq man-args (Man-translate-references man-args))
-
- (Man-getpage-in-background man-args))
-
-;;;###autoload
-(defun man-follow (man-args)
- "Get a Un*x manual page of the item under point and put it in a buffer."
- (interactive (list (Man-default-man-entry)))
- (if (or (not man-args)
- (string= man-args ""))
- (error "No item under point")
- (man man-args)))
-
-(defun Man-getpage-in-background (topic)
- "Use TOPIC to build and fire off the manpage and cleaning command."
- (let* ((man-args topic)
- (bufname (concat "*Man " man-args "*"))
- (buffer (get-buffer bufname)))
- (if buffer
- (Man-notify-when-ready buffer)
- (require 'env)
- (message "Invoking %s %s in the background" manual-program man-args)
- (setq buffer (generate-new-buffer bufname))
- (save-excursion
- (set-buffer buffer)
- (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-enable-multibyte-characters
- locale-coding-system 'raw-text-unix))
- ;; Avoid possible error by using a directory that always exists.
- (default-directory "/"))
- ;; Prevent any attempt to use display terminal fanciness.
- (setenv "TERM" "dumb")
- (if (fboundp 'start-process)
- (set-process-sentinel
- (start-process manual-program buffer "sh" "-c"
- (format (Man-build-man-command) man-args))
- 'Man-bgproc-sentinel)
- (progn
- (let ((exit-status
- (call-process shell-file-name nil (list buffer nil) nil "-c"
- (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))))))))
-
-(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."
- (let ((saved-frame (save-excursion
- (set-buffer man-buffer)
- Man-original-frame)))
- (cond
- ((eq Man-notify-method 'newframe)
- ;; Since we run asynchronously, perhaps while Emacs is waiting
- ;; for input, we must not leave a different buffer current. We
- ;; can't rely on the editor command loop to reselect the
- ;; selected window's buffer.
- (save-excursion
- (let ((frame (make-frame Man-frame-parameters)))
- (set-window-buffer (frame-selected-window frame) man-buffer)
- (set-window-dedicated-p (frame-selected-window frame) t)
- (or (display-multi-frame-p frame)
- (select-frame frame)))))
- ((eq Man-notify-method 'pushy)
- (switch-to-buffer man-buffer))
- ((eq Man-notify-method 'bully)
- (and (frame-live-p saved-frame)
- (select-frame saved-frame))
- (pop-to-buffer man-buffer)
- (delete-other-windows))
- ((eq Man-notify-method 'aggressive)
- (and (frame-live-p saved-frame)
- (select-frame saved-frame))
- (pop-to-buffer man-buffer))
- ((eq Man-notify-method 'friendly)
- (and (frame-live-p saved-frame)
- (select-frame saved-frame))
- (display-buffer man-buffer 'not-this-window))
- ((eq Man-notify-method 'polite)
- (beep)
- (message "Manual buffer %s is ready" (buffer-name man-buffer)))
- ((eq Man-notify-method 'quiet)
- (message "Manual buffer %s is ready" (buffer-name man-buffer)))
- ((or (eq Man-notify-method 'meek)
- t)
- (message ""))
- )))
-
-(defun Man-softhyphen-to-minus ()
- ;; \255 is some kind of dash in Latin-N. Versions of Debian man, at
- ;; least, emit it even when not in a Latin-N locale.
- (unless (eq t (compare-strings "latin-" 0 nil
- current-language-environment 0 6 t))
- (goto-char (point-min))
- (let ((str "\255"))
- (if enable-multibyte-characters
- (setq str (string-as-multibyte str)))
- (while (search-forward str nil t) (replace-match "-")))))
-
-(defun Man-fontify-manpage ()
- "Convert overstriking and underlining to the correct fonts.
-Same for the ANSI bold and normal escape sequences."
- (interactive)
- (message "Please wait: making up 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))
- (Man-softhyphen-to-minus)
- (message "%s man page made up" Man-arguments))
-
-(defun Man-cleanup-manpage ()
- "Remove overstriking and underlining from the current buffer."
- (interactive)
- (message "Please wait: cleaning up the %s man page..."
- Man-arguments)
- (if (or (interactive-p) (not Man-sed-script))
- (progn
- (goto-char (point-min))
- (while (search-forward "_\b" nil t) (backward-delete-char 2))
- (goto-char (point-min))
- (while (search-forward "\b_" nil t) (backward-delete-char 2))
- (goto-char (point-min))
- (while (re-search-forward "\\(.\\)\\(\b\\1\\)+" nil t)
- (replace-match "\\1"))
- (goto-char (point-min))
- (while (re-search-forward "\e\\[[0-9]+m" nil t) (replace-match ""))
- (goto-char (point-min))
- (while (re-search-forward "o\b\\+\\|\\+\bo" nil t) (replace-match "o"))
- ))
- (goto-char (point-min))
- (while (re-search-forward "[-|]\\(\b[-|]\\)+" nil t) (replace-match "+"))
- (Man-softhyphen-to-minus)
- (message "%s man page cleaned up" Man-arguments))
-
-(defun Man-bgproc-sentinel (process msg)
- "Manpage background process sentinel.
-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 MSG is the exit message of the
-manpage command."
- (let ((Man-buffer (if (stringp process) (get-buffer process)
- (process-buffer process)))
- (delete-buff nil)
- (err-mess nil))
-
- (if (null (buffer-name Man-buffer)) ;; deleted buffer
- (or (stringp process)
- (set-process-buffer process nil))
-
- (save-excursion
- (set-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))
- ((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)
- (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))
-
- (if err-mess
- (error err-mess))
- ))))
-
-
-;; ======================================================================
-;; set up manual mode in buffer and build alists
-
-(defun Man-mode ()
- "A mode for browsing Un*x manual pages.
-
-The following man commands are available in the buffer. Try
-\"\\[describe-key] <key> RET\" for more information:
-
-\\[man] Prompt to retrieve a new manpage.
-\\[Man-follow-manual-reference] Retrieve reference in SEE ALSO section.
-\\[Man-next-manpage] Jump to next manpage in circular list.
-\\[Man-previous-manpage] Jump to previous manpage in circular list.
-\\[Man-next-section] Jump to next manpage section.
-\\[Man-previous-section] Jump to previous manpage section.
-\\[Man-goto-section] Go to a manpage section.
-\\[Man-goto-see-also-section] Jumps to the SEE ALSO manpage section.
-\\[Man-quit] Deletes the manpage window, bury its buffer.
-\\[Man-kill] Deletes the manpage window, kill its buffer.
-\\[describe-mode] Prints this help text.
-
-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-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.
-`Man-filter-list' Background manpage filter command.
-`Man-mode-line-format' Mode line format for Man mode buffers.
-`Man-mode-map' Keymap bindings for Man mode buffers.
-`Man-mode-hook' Normal hook run on entry to Man mode.
-`Man-section-regexp' Regexp describing manpage section letters.
-`Man-heading-regexp' Regexp describing section headers.
-`Man-see-also-regexp' Regexp for SEE ALSO section (or your equiv).
-`Man-first-heading-regexp' Regexp for first heading on a manpage.
-`Man-reference-regexp' Regexp matching a references in SEE ALSO.
-`Man-switches' Background `man' command switches.
-
-The following key bindings are currently in effect in the buffer:
-\\{Man-mode-map}"
- (interactive)
- (setq major-mode 'Man-mode
- mode-name "Man"
- buffer-auto-save-file-name nil
- mode-line-format Man-mode-line-format
- truncate-lines t
- buffer-read-only t)
- (buffer-disable-undo (current-buffer))
- (auto-fill-mode -1)
- (use-local-map Man-mode-map)
- (set-syntax-table man-mode-syntax-table)
- (Man-build-page-list)
- (Man-strip-page-headers)
- (Man-unindent)
- (Man-goto-page 1)
- (run-hooks 'Man-mode-hook))
-
-(defsubst Man-build-section-alist ()
- "Build the association list of manpage sections."
- (setq Man-sections-alist nil)
- (goto-char (point-min))
- (let ((case-fold-search nil))
- (while (re-search-forward Man-heading-regexp (point-max) t)
- (aput 'Man-sections-alist (Man-match-substring 1))
- (forward-line 1))))
-
-(defsubst Man-build-references-alist ()
- "Build the association list of references (in the SEE ALSO section)."
- (setq Man-refpages-alist nil)
- (save-excursion
- (if (Man-find-section Man-see-also-regexp)
- (let ((start (progn (forward-line 1) (point)))
- (end (progn
- (Man-next-section 1)
- (point)))
- hyphenated
- (runningpoint -1))
- (save-restriction
- (narrow-to-region start end)
- (goto-char (point-min))
- (back-to-indentation)
- (while (and (not (eobp)) (/= (point) runningpoint))
- (setq runningpoint (point))
- (if (re-search-forward Man-hyphenated-reference-regexp end t)
- (let* ((word (Man-match-substring 0))
- (len (1- (length word))))
- (if hyphenated
- (setq word (concat hyphenated word)
- hyphenated nil
- ;; Update len, in case a reference spans
- ;; more than two lines (paranoia).
- len (1- (length word))))
- (if (= (aref word len) ?-)
- (setq hyphenated (substring word 0 len)))
- (if (string-match Man-reference-regexp word)
- (aput 'Man-refpages-alist word))))
- (skip-chars-forward " \t\n,"))))))
- (setq Man-refpages-alist (nreverse Man-refpages-alist)))
-
-(defun Man-build-page-list ()
- "Build the list of separate manpages in the buffer."
- (setq Man-page-list nil)
- (let ((page-start (point-min))
- (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)
- (Man-match-substring 1)
- nil))
- ;; Go past both the current and the next Man-first-heading-regexp
- (if (re-search-forward Man-first-heading-regexp nil 'move 2)
- (let ((p (progn (beginning-of-line) (point))))
- ;; We assume that the page header is delimited by blank
- ;; lines and that it contains at most one blank line. So
- ;; if we back by three blank lines we will be sure to be
- ;; before the page header but not before the possible
- ;; previous page header.
- (search-backward "\n\n" nil t 3)
- (if (re-search-forward Man-page-header-regexp p 'move)
- (beginning-of-line))))
- (setq page-end (point))
- (setq Man-page-list (append Man-page-list
- (list (list (copy-marker page-start)
- (copy-marker page-end)
- header))))
- (setq page-start page-end)
- )))
-
-(defun Man-strip-page-headers ()
- "Strip all the page headers but the first from the manpage."
- (let ((buffer-read-only nil)
- (case-fold-search nil)
- (page-list Man-page-list)
- (page ())
- (header ""))
- (while page-list
- (setq page (car page-list))
- (and (nth 2 page)
- (goto-char (car page))
- (re-search-forward Man-first-heading-regexp nil t)
- (setq header (buffer-substring (car page) (match-beginning 0)))
- ;; Since the awk script collapses all successive blank
- ;; lines into one, and since we don't want to get rid of
- ;; the fast awk script, one must choose between adding
- ;; spare blank lines between pages when there were none and
- ;; deleting blank lines at page boundaries when there were
- ;; some. We choose the first, so we comment the following
- ;; line.
- ;; (setq header (concat "\n" header)))
- (while (search-forward header (nth 1 page) t)
- (replace-match "")))
- (setq page-list (cdr page-list)))))
-
-(defun Man-unindent ()
- "Delete the leading spaces that indent the manpage."
- (let ((buffer-read-only nil)
- (case-fold-search nil)
- (page-list Man-page-list))
- (while page-list
- (let ((page (car page-list))
- (indent "")
- (nindent 0))
- (narrow-to-region (car page) (car (cdr page)))
- (if Man-uses-untabify-flag
- (untabify (point-min) (point-max)))
- (if (catch 'unindent
- (goto-char (point-min))
- (if (not (re-search-forward Man-first-heading-regexp nil t))
- (throw 'unindent nil))
- (beginning-of-line)
- (setq indent (buffer-substring (point)
- (progn
- (skip-chars-forward " ")
- (point))))
- (setq nindent (length indent))
- (if (zerop nindent)
- (throw 'unindent nil))
- (setq indent (concat indent "\\|$"))
- (goto-char (point-min))
- (while (not (eobp))
- (if (looking-at indent)
- (forward-line 1)
- (throw 'unindent nil)))
- (goto-char (point-min)))
- (while (not (eobp))
- (or (eolp)
- (delete-char nindent))
- (forward-line 1)))
- (setq page-list (cdr page-list))
- ))))
-
-
-;; ======================================================================
-;; Man mode commands
-
-(defun Man-next-section (n)
- "Move point to Nth next section (default 1)."
- (interactive "p")
- (let ((case-fold-search nil))
- (if (looking-at Man-heading-regexp)
- (forward-line 1))
- (if (re-search-forward Man-heading-regexp (point-max) t n)
- (beginning-of-line)
- (goto-char (point-max)))))
-
-(defun Man-previous-section (n)
- "Move point to Nth previous section (default 1)."
- (interactive "p")
- (let ((case-fold-search nil))
- (if (looking-at Man-heading-regexp)
- (forward-line -1))
- (if (re-search-backward Man-heading-regexp (point-min) t n)
- (beginning-of-line)
- (goto-char (point-min)))))
-
-(defun Man-find-section (section)
- "Move point to SECTION if it exists, otherwise don't move point.
-Returns t if section is found, nil otherwise."
- (let ((curpos (point))
- (case-fold-search nil))
- (goto-char (point-min))
- (if (re-search-forward (concat "^" section) (point-max) t)
- (progn (beginning-of-line) t)
- (goto-char curpos)
- nil)
- ))
-
-(defun Man-goto-section ()
- "Query for section to move point to."
- (interactive)
- (aput 'Man-sections-alist
- (let* ((default (aheadsym Man-sections-alist))
- (completion-ignore-case t)
- chosen
- (prompt (concat "Go to section: (default " default ") ")))
- (setq chosen (completing-read prompt Man-sections-alist))
- (if (or (not chosen)
- (string= chosen ""))
- default
- chosen)))
- (Man-find-section (aheadsym Man-sections-alist)))
-
-(defun Man-goto-see-also-section ()
- "Move point the the \"SEE ALSO\" section.
-Actually the section moved to is described by `Man-see-also-regexp'."
- (interactive)
- (if (not (Man-find-section Man-see-also-regexp))
- (error (concat "No " Man-see-also-regexp
- " section found in the current manpage"))))
-
-(defun Man-possibly-hyphenated-word ()
- "Return a possibly hyphenated word at point.
-If the word starts at the first non-whitespace column, and the
-previous line ends with a hyphen, return the last word on the previous
-line instead. Thus, if a reference to \"tcgetpgrp(3V)\" is hyphenated
-as \"tcgetp-grp(3V)\", and point is at \"grp(3V)\", we return
-\"tcgetp-\" instead of \"grp\"."
- (save-excursion
- (skip-syntax-backward "w()")
- (skip-chars-forward " \t")
- (let ((beg (point))
- (word (current-word)))
- (when (eq beg (save-excursion
- (back-to-indentation)
- (point)))
- (end-of-line 0)
- (if (eq (char-before) ?-)
- (setq word (current-word))))
- word)))
-
-(defun Man-follow-manual-reference (reference)
- "Get one of the manpages referred to in the \"SEE ALSO\" section.
-Specify which REFERENCE to use; default is based on word at point."
- (interactive
- (if (not Man-refpages-alist)
- (error "There are no references in the current man page")
- (list (let* ((default (or
- (car (all-completions
- (let ((word (Man-possibly-hyphenated-word)))
- ;; strip a trailing '-':
- (if (string-match "-$" word)
- (substring word 0
- (match-beginning 0))
- word))
- Man-refpages-alist))
- (aheadsym Man-refpages-alist)))
- chosen
- (prompt (concat "Refer to: (default " default ") ")))
- (setq chosen (completing-read prompt Man-refpages-alist nil t))
- (if (or (not chosen)
- (string= chosen ""))
- default
- chosen)))))
- (if (not Man-refpages-alist)
- (error "Can't find any references in the current manpage")
- (aput 'Man-refpages-alist reference)
- (Man-getpage-in-background
- (Man-translate-references (aheadsym Man-refpages-alist)))))
-
-(defun Man-kill ()
- "Kill the buffer containing the manpage."
- (interactive)
- (quit-window t))
-
-(defun Man-quit ()
- "Bury the buffer containing the manpage."
- (interactive)
- (quit-window))
-
-(defun Man-goto-page (page)
- "Go to the manual page on page PAGE."
- (interactive
- (if (not Man-page-list)
- (let ((args Man-arguments))
- (kill-buffer (current-buffer))
- (error "Can't find the %s manpage" args))
- (if (= (length Man-page-list) 1)
- (error "You're looking at the only manpage in the buffer")
- (list (read-minibuffer (format "Go to manpage [1-%d]: "
- (length Man-page-list)))))))
- (if (not Man-page-list)
- (let ((args Man-arguments))
- (kill-buffer (current-buffer))
- (error "Can't find the %s manpage" args)))
- (if (or (< page 1)
- (> page (length Man-page-list)))
- (error "No manpage %d found" page))
- (let* ((page-range (nth (1- page) Man-page-list))
- (page-start (car page-range))
- (page-end (car (cdr page-range))))
- (setq Man-current-page page
- Man-page-mode-string (Man-make-page-mode-string))
- (widen)
- (goto-char page-start)
- (narrow-to-region page-start page-end)
- (Man-build-section-alist)
- (Man-build-references-alist)
- (goto-char (point-min))))
-
-
-(defun Man-next-manpage ()
- "Find the next manpage entry in the buffer."
- (interactive)
- (if (= (length Man-page-list) 1)
- (error "This is the only manpage in the buffer"))
- (if (< Man-current-page (length Man-page-list))
- (Man-goto-page (1+ Man-current-page))
- (if Man-circular-pages-flag
- (Man-goto-page 1)
- (error "You're looking at the last manpage in the buffer"))))
-
-(defun Man-previous-manpage ()
- "Find the previous manpage entry in the buffer."
- (interactive)
- (if (= (length Man-page-list) 1)
- (error "This is the only manpage in the buffer"))
- (if (> Man-current-page 1)
- (Man-goto-page (1- Man-current-page))
- (if Man-circular-pages-flag
- (Man-goto-page (length Man-page-list))
- (error "You're looking at the first manpage in the buffer"))))
-
-;; Init the man package variables, if not already done.
-(Man-init-defvars)
-
-(add-to-list 'debug-ignored-errors "^No manpage [0-9]* found$")
-(add-to-list 'debug-ignored-errors "^Can't find the .* manpage$")
-
-(provide 'man)
-
-;;; man.el ends here