| 1 | ;;; man.el --- browse UNIX manual pages -*- coding: iso-8859-1 -*- |
| 2 | |
| 3 | ;; Copyright (C) 1993, 1994, 1996, 1997, 2001, 2002, 2003, |
| 4 | ;; 2004, 2005 Free Software Foundation, Inc. |
| 5 | |
| 6 | ;; Author: Barry A. Warsaw <bwarsaw@cen.com> |
| 7 | ;; Maintainer: FSF |
| 8 | ;; Keywords: help |
| 9 | ;; Adapted-By: ESR, pot |
| 10 | |
| 11 | ;; This file is part of GNU Emacs. |
| 12 | |
| 13 | ;; GNU Emacs is free software; you can redistribute it and/or modify |
| 14 | ;; it under the terms of the GNU General Public License as published by |
| 15 | ;; the Free Software Foundation; either version 2, or (at your option) |
| 16 | ;; any later version. |
| 17 | |
| 18 | ;; GNU Emacs is distributed in the hope that it will be useful, |
| 19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 21 | ;; GNU General Public License for more details. |
| 22 | |
| 23 | ;; You should have received a copy of the GNU General Public License |
| 24 | ;; along with GNU Emacs; see the file COPYING. If not, write to the |
| 25 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 26 | ;; Boston, MA 02110-1301, USA. |
| 27 | |
| 28 | ;;; Commentary: |
| 29 | |
| 30 | ;; This code provides a function, `man', with which you can browse |
| 31 | ;; UNIX manual pages. Formatting is done in background so that you |
| 32 | ;; can continue to use your Emacs while processing is going on. |
| 33 | ;; |
| 34 | ;; The mode also supports hypertext-like following of manual page SEE |
| 35 | ;; ALSO references, and other features. See below or do `?' in a |
| 36 | ;; manual page buffer for details. |
| 37 | |
| 38 | ;; ========== Credits and History ========== |
| 39 | ;; In mid 1991, several people posted some interesting improvements to |
| 40 | ;; man.el from the standard emacs 18.57 distribution. I liked many of |
| 41 | ;; these, but wanted everything in one single package, so I decided |
| 42 | ;; to incorporate them into a single manual browsing mode. While |
| 43 | ;; much of the code here has been rewritten, and some features added, |
| 44 | ;; these folks deserve lots of credit for providing the initial |
| 45 | ;; excellent packages on which this one is based. |
| 46 | |
| 47 | ;; Nick Duffek <duffek@chaos.cs.brandeis.edu>, posted a very nice |
| 48 | ;; improvement which retrieved and cleaned the manpages in a |
| 49 | ;; background process, and which correctly deciphered such options as |
| 50 | ;; man -k. |
| 51 | |
| 52 | ;; Eric Rose <erose@jessica.stanford.edu>, submitted manual.el which |
| 53 | ;; provided a very nice manual browsing mode. |
| 54 | |
| 55 | ;; This package was available as `superman.el' from the LCD package |
| 56 | ;; for some time before it was accepted into Emacs 19. The entry |
| 57 | ;; point and some other names have been changed to make it a drop-in |
| 58 | ;; replacement for the old man.el package. |
| 59 | |
| 60 | ;; Francesco Potorti` <pot@cnuce.cnr.it> cleaned it up thoroughly, |
| 61 | ;; making it faster, more robust and more tolerant of different |
| 62 | ;; systems' man idiosyncrasies. |
| 63 | |
| 64 | ;; ========== Features ========== |
| 65 | ;; + Runs "man" in the background and pipes the results through a |
| 66 | ;; series of sed and awk scripts so that all retrieving and cleaning |
| 67 | ;; is done in the background. The cleaning commands are configurable. |
| 68 | ;; + Syntax is the same as Un*x man |
| 69 | ;; + Functionality is the same as Un*x man, including "man -k" and |
| 70 | ;; "man <section>", etc. |
| 71 | ;; + Provides a manual browsing mode with keybindings for traversing |
| 72 | ;; the sections of a manpage, following references in the SEE ALSO |
| 73 | ;; section, and more. |
| 74 | ;; + Multiple manpages created with the same man command are put into |
| 75 | ;; a narrowed buffer circular list. |
| 76 | |
| 77 | ;; ============= TODO =========== |
| 78 | ;; - Add a command for printing. |
| 79 | ;; - The awk script deletes multiple blank lines. This behaviour does |
| 80 | ;; not allow to understand if there was indeed a blank line at the |
| 81 | ;; end or beginning of a page (after the header, or before the |
| 82 | ;; footer). A different algorithm should be used. It is easy to |
| 83 | ;; compute how many blank lines there are before and after the page |
| 84 | ;; headers, and after the page footer. But it is possible to compute |
| 85 | ;; the number of blank lines before the page footer by heuristics |
| 86 | ;; only. Is it worth doing? |
| 87 | ;; - Allow a user option to mean that all the manpages should go in |
| 88 | ;; the same buffer, where they can be browsed with M-n and M-p. |
| 89 | ;; - Allow completion on the manpage name when calling man. This |
| 90 | ;; requires a reliable list of places where manpages can be found. The |
| 91 | ;; drawback would be that if the list is not complete, the user might |
| 92 | ;; be led to believe that the manpages in the missing directories do |
| 93 | ;; not exist. |
| 94 | |
| 95 | \f |
| 96 | ;;; Code: |
| 97 | |
| 98 | (eval-when-compile (require 'cl)) |
| 99 | (require 'assoc) |
| 100 | (require 'button) |
| 101 | |
| 102 | ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv |
| 103 | ;; empty defvars (keep the compiler quiet) |
| 104 | |
| 105 | (defgroup man nil |
| 106 | "Browse UNIX manual pages." |
| 107 | :prefix "Man-" |
| 108 | :group 'help) |
| 109 | |
| 110 | |
| 111 | (defvar Man-notify) |
| 112 | (defvar Man-current-page) |
| 113 | (defvar Man-page-list) |
| 114 | (defcustom Man-filter-list nil |
| 115 | "*Manpage cleaning filter command phrases. |
| 116 | This variable contains a list of the following form: |
| 117 | |
| 118 | '((command-string phrase-string*)*) |
| 119 | |
| 120 | Each phrase-string is concatenated onto the command-string to form a |
| 121 | command filter. The (standard) output (and standard error) of the Un*x |
| 122 | man command is piped through each command filter in the order the |
| 123 | commands appear in the association list. The final output is placed in |
| 124 | the manpage buffer." |
| 125 | :type '(repeat (list (string :tag "Command String") |
| 126 | (repeat :inline t |
| 127 | (string :tag "Phrase String")))) |
| 128 | :group 'man) |
| 129 | |
| 130 | (defvar Man-original-frame) |
| 131 | (defvar Man-arguments) |
| 132 | (defvar Man-sections-alist) |
| 133 | (defvar Man-refpages-alist) |
| 134 | (defvar Man-uses-untabify-flag t |
| 135 | "Non-nil means use `untabify' instead of `Man-untabify-command'.") |
| 136 | (defvar Man-page-mode-string) |
| 137 | (defvar Man-sed-script nil |
| 138 | "Script for sed to nuke backspaces and ANSI codes from manpages.") |
| 139 | |
| 140 | ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv |
| 141 | ;; user variables |
| 142 | |
| 143 | (defcustom Man-fontify-manpage-flag t |
| 144 | "*Non-nil means make up the manpage with fonts." |
| 145 | :type 'boolean |
| 146 | :group 'man) |
| 147 | |
| 148 | (defcustom Man-overstrike-face 'bold |
| 149 | "*Face to use when fontifying overstrike." |
| 150 | :type 'face |
| 151 | :group 'man) |
| 152 | |
| 153 | (defcustom Man-underline-face 'underline |
| 154 | "*Face to use when fontifying underlining." |
| 155 | :type 'face |
| 156 | :group 'man) |
| 157 | |
| 158 | (defcustom Man-reverse-face 'highlight |
| 159 | "*Face to use when fontifying reverse video." |
| 160 | :type 'face |
| 161 | :group 'man) |
| 162 | |
| 163 | ;; Use the value of the obsolete user option Man-notify, if set. |
| 164 | (defcustom Man-notify-method (if (boundp 'Man-notify) Man-notify 'friendly) |
| 165 | "*Selects the behavior when manpage is ready. |
| 166 | This variable may have one of the following values, where (sf) means |
| 167 | that the frames are switched, so the manpage is displayed in the frame |
| 168 | where the man command was called from: |
| 169 | |
| 170 | newframe -- put the manpage in its own frame (see `Man-frame-parameters') |
| 171 | pushy -- make the manpage the current buffer in the current window |
| 172 | bully -- make the manpage the current buffer and only window (sf) |
| 173 | aggressive -- make the manpage the current buffer in the other window (sf) |
| 174 | friendly -- display manpage in the other window but don't make current (sf) |
| 175 | polite -- don't display manpage, but prints message and beep when ready |
| 176 | quiet -- like `polite', but don't beep |
| 177 | meek -- make no indication that the manpage is ready |
| 178 | |
| 179 | Any other value of `Man-notify-method' is equivalent to `meek'." |
| 180 | :type '(radio (const newframe) (const pushy) (const bully) |
| 181 | (const aggressive) (const friendly) |
| 182 | (const polite) (const quiet) (const meek)) |
| 183 | :group 'man) |
| 184 | |
| 185 | (defcustom Man-width nil |
| 186 | "*Number of columns for which manual pages should be formatted. |
| 187 | If nil, the width of the window selected at the moment of man |
| 188 | invocation is used. If non-nil, the width of the frame selected |
| 189 | at the moment of man invocation is used. The value also can be a |
| 190 | positive integer." |
| 191 | :type '(choice (const :tag "Window width" nil) |
| 192 | (const :tag "Frame width" t) |
| 193 | (integer :tag "Specific width" :value 65)) |
| 194 | :group 'man) |
| 195 | |
| 196 | (defcustom Man-frame-parameters nil |
| 197 | "*Frame parameter list for creating a new frame for a manual page." |
| 198 | :type 'sexp |
| 199 | :group 'man) |
| 200 | |
| 201 | (defcustom Man-downcase-section-letters-flag t |
| 202 | "*Non-nil means letters in sections are converted to lower case. |
| 203 | Some Un*x man commands can't handle uppercase letters in sections, for |
| 204 | example \"man 2V chmod\", but they are often displayed in the manpage |
| 205 | with the upper case letter. When this variable is t, the section |
| 206 | letter (e.g., \"2V\") is converted to lowercase (e.g., \"2v\") before |
| 207 | being sent to the man background process." |
| 208 | :type 'boolean |
| 209 | :group 'man) |
| 210 | |
| 211 | (defcustom Man-circular-pages-flag t |
| 212 | "*Non-nil means the manpage list is treated as circular for traversal." |
| 213 | :type 'boolean |
| 214 | :group 'man) |
| 215 | |
| 216 | (defcustom Man-section-translations-alist |
| 217 | (list |
| 218 | '("3C++" . "3") |
| 219 | ;; Some systems have a real 3x man section, so let's comment this. |
| 220 | ;; '("3X" . "3") ; Xlib man pages |
| 221 | '("3X11" . "3") |
| 222 | '("1-UCB" . "")) |
| 223 | "*Association list of bogus sections to real section numbers. |
| 224 | Some manpages (e.g. the Sun C++ 2.1 manpages) have section numbers in |
| 225 | their references which Un*x `man' does not recognize. This |
| 226 | association list is used to translate those sections, when found, to |
| 227 | the associated section number." |
| 228 | :type '(repeat (cons (string :tag "Bogus Section") |
| 229 | (string :tag "Real Section"))) |
| 230 | :group 'man) |
| 231 | |
| 232 | (defcustom Man-header-file-path |
| 233 | '("/usr/include" "/usr/local/include") |
| 234 | "C Header file search path used in Man." |
| 235 | :type '(repeat string) |
| 236 | :group 'man) |
| 237 | |
| 238 | (defvar manual-program "man" |
| 239 | "The name of the program that produces man pages.") |
| 240 | |
| 241 | (defvar Man-untabify-command "pr" |
| 242 | "Command used for untabifying.") |
| 243 | |
| 244 | (defvar Man-untabify-command-args (list "-t" "-e") |
| 245 | "List of arguments to be passed to `Man-untabify-command' (which see).") |
| 246 | |
| 247 | (defvar Man-sed-command "sed" |
| 248 | "Command used for processing sed scripts.") |
| 249 | |
| 250 | (defvar Man-awk-command "awk" |
| 251 | "Command used for processing awk scripts.") |
| 252 | |
| 253 | (defvar Man-mode-map nil |
| 254 | "Keymap for Man mode.") |
| 255 | |
| 256 | (defvar Man-mode-hook nil |
| 257 | "Hook run when Man mode is enabled.") |
| 258 | |
| 259 | (defvar Man-cooked-hook nil |
| 260 | "Hook run after removing backspaces but before `Man-mode' processing.") |
| 261 | |
| 262 |