aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/ChangeLog28
-rw-r--r--lisp/man.el271
2 files changed, 188 insertions, 111 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 1300cd7b8b8..c35bc73cdc0 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,31 @@
12014-07-01 Juri Linkov <juri@jurta.org>
2
3 * man.el: Display man pages immediately and use process-filter
4 to format them asynchronously.
5 (Man-width): Doc fix.
6 (man): Doc fix.
7 (Man-start-calling): Use `with-selected-window' to get
8 `frame-width' and `window-width'.
9 (Man-getpage-in-background): Call `Man-notify-when-ready'
10 immediately after creating a new buffer. Call `Man-mode' and set
11 `mode-line-process' in the created buffer. Set process-filter to
12 `Man-bgproc-filter' in start-process branch. In call-process branch
13 call either `Man-fontify-manpage' or `Man-cleanup-manpage'.
14 Use `Man-start-calling' inside `with-current-buffer'.
15 (Man-fontify-manpage): Don't print messages. Fix boundary condition.
16 (Man-cleanup-manpage): Don't print messages.
17 (Man-bgproc-filter): New function.
18 (Man-bgproc-sentinel): Add `save-excursion' to keep point when
19 user moved it during asynchronous formatting. Move calls of
20 `Man-fontify-manpage' and `Man-cleanup-manpage' to
21 `Man-bgproc-filter'. Move the call of `Man-mode' to
22 `Man-getpage-in-background'. Use `quit-restore-window'
23 instead of `kill-buffer'. Use `message' instead of `error'
24 because errors are catched by process sentinel.
25 (Man-mode): Move calls of `Man-build-page-list',
26 `Man-strip-page-headers', `Man-unindent', `Man-goto-page' to
27 `Man-bgproc-sentinel'. Doc fix. (Bug#2588, bug#5054, bug#9084, bug#17831)
28
12014-07-01 Mario Lang <mlang@delysid.org> 292014-07-01 Mario Lang <mlang@delysid.org>
2 30
3 * net/gnutls.el (gnutls-negotiate): Prevent destructive modification of 31 * net/gnutls.el (gnutls-negotiate): Prevent destructive modification of
diff --git a/lisp/man.el b/lisp/man.el
index 35fab2040a5..c14231212d0 100644
--- a/lisp/man.el
+++ b/lisp/man.el
@@ -173,13 +173,12 @@ Any other value of `Man-notify-method' is equivalent to `meek'."
173 173
174(defcustom Man-width nil 174(defcustom Man-width nil
175 "Number of columns for which manual pages should be formatted. 175 "Number of columns for which manual pages should be formatted.
176If nil, the width of the window selected at the moment of man 176If nil, use the width of the window where the manpage is displayed.
177invocation is used. If non-nil, the width of the frame selected 177If non-nil, use the width of the frame where the manpage is displayed.
178at the moment of man invocation is used. The value also can be a 178The value also can be a positive integer for a fixed width."
179positive integer."
180 :type '(choice (const :tag "Window width" nil) 179 :type '(choice (const :tag "Window width" nil)
181 (const :tag "Frame width" t) 180 (const :tag "Frame width" t)
182 (integer :tag "Specific width" :value 65)) 181 (integer :tag "Fixed width" :value 65))
183 :group 'man) 182 :group 'man)
184 183
185(defcustom Man-frame-parameters nil 184(defcustom Man-frame-parameters nil
@@ -930,12 +929,14 @@ test/automated/man-tests.el in the emacs bzr repository."
930;;;###autoload 929;;;###autoload
931(defun man (man-args) 930(defun man (man-args)
932 "Get a Un*x manual page and put it in a buffer. 931 "Get a Un*x manual page and put it in a buffer.
933This command is the top-level command in the man package. It 932This command is the top-level command in the man package.
934runs a Un*x command to retrieve and clean a manpage in the 933It runs a Un*x command to retrieve and clean a manpage in the
935background and places the results in a `Man-mode' browsing 934background and places the results in a `Man-mode' browsing
936buffer. See variable `Man-notify-method' for what happens when 935buffer. The variable `Man-width' defines the number of columns in
937the buffer is ready. If a buffer already exists for this man 936formatted manual pages. The buffer is displayed immediately.
938page, it will display immediately. 937The variable `Man-notify-method' defines how the buffer is displayed.
938If a buffer already exists for this man page, it will be displayed
939without running the man command.
939 940
940For a manpage from a particular section, use either of the 941For a manpage from a particular section, use either of the
941following. \"cat(1)\" is how cross-references appear and is 942following. \"cat(1)\" is how cross-references appear and is
@@ -1030,15 +1031,22 @@ names or descriptions. The pattern argument is usually an
1030 ;; ther is available). 1031 ;; ther is available).
1031 (when (or window-system 1032 (when (or window-system
1032 (not (or (getenv "MANWIDTH") (getenv "COLUMNS")))) 1033 (not (or (getenv "MANWIDTH") (getenv "COLUMNS"))))
1033 ;; This isn't strictly correct, since we don't know how 1034 ;; Since the page buffer is displayed beforehand,
1034 ;; the page will actually be displayed, but it seems 1035 ;; we can select its window and get the window/frame width.
1035 ;; reasonable.
1036 (setenv "COLUMNS" (number-to-string 1036 (setenv "COLUMNS" (number-to-string
1037 (cond 1037 (cond
1038 ((and (integerp Man-width) (> Man-width 0)) 1038 ((and (integerp Man-width) (> Man-width 0))
1039 Man-width) 1039 Man-width)
1040 (Man-width (frame-width)) 1040 (Man-width
1041 ((window-width)))))) 1041 (if (window-live-p (get-buffer-window (current-buffer) t))
1042 (with-selected-window (get-buffer-window (current-buffer) t)
1043 (frame-width))
1044 (frame-width)))
1045 (t
1046 (if (window-live-p (get-buffer-window (current-buffer) t))
1047 (with-selected-window (get-buffer-window (current-buffer) t)
1048 (window-width))
1049 (window-width)))))))
1042 ;; Since man-db 2.4.3-1, man writes plain text with no escape 1050 ;; Since man-db 2.4.3-1, man writes plain text with no escape
1043 ;; sequences when stdout is not a tty. In 2.5.0, the following 1051 ;; sequences when stdout is not a tty. In 2.5.0, the following
1044 ;; env-var was added to allow control of this (see Debian Bug#340673). 1052 ;; env-var was added to allow control of this (see Debian Bug#340673).
@@ -1057,33 +1065,45 @@ Return the buffer in which the manpage will appear."
1057 (message "Invoking %s %s in the background" manual-program man-args) 1065 (message "Invoking %s %s in the background" manual-program man-args)
1058 (setq buffer (generate-new-buffer bufname)) 1066 (setq buffer (generate-new-buffer bufname))
1059 (with-current-buffer buffer 1067 (with-current-buffer buffer
1068 (Man-notify-when-ready buffer)
1060 (setq buffer-undo-list t) 1069 (setq buffer-undo-list t)
1061 (setq Man-original-frame (selected-frame)) 1070 (setq Man-original-frame (selected-frame))
1062 (setq Man-arguments man-args)) 1071 (setq Man-arguments man-args)
1063 (Man-start-calling 1072 (Man-mode)
1064 (if (fboundp 'start-process) 1073 (setq mode-line-process
1065 (set-process-sentinel 1074 (concat " " (propertize (if Man-fontify-manpage-flag
1066 (start-process manual-program buffer 1075 "[formatting...]"
1067 (if (memq system-type '(cygwin windows-nt)) 1076 "[cleaning...]")
1068 shell-file-name 1077 'face 'mode-line-emphasis)))
1069 "sh") 1078 (Man-start-calling
1070 shell-command-switch 1079 (if (fboundp 'start-process)
1071 (format (Man-build-man-command) man-args)) 1080 (let ((proc (start-process
1072 'Man-bgproc-sentinel) 1081 manual-program buffer
1073 (let ((exit-status 1082 (if (memq system-type '(cygwin windows-nt))
1074 (call-process shell-file-name nil (list buffer nil) nil 1083 shell-file-name
1075 shell-command-switch 1084 "sh")
1076 (format (Man-build-man-command) man-args))) 1085 shell-command-switch
1077 (msg "")) 1086 (format (Man-build-man-command) man-args))))
1078 (or (and (numberp exit-status) 1087 (set-process-sentinel proc 'Man-bgproc-sentinel)
1079 (= exit-status 0)) 1088 (set-process-filter proc 'Man-bgproc-filter))
1080 (and (numberp exit-status) 1089 (let* ((inhibit-read-only t)
1081 (setq msg 1090 (exit-status
1082 (format "exited abnormally with code %d" 1091 (call-process shell-file-name nil (list buffer nil) nil
1083 exit-status))) 1092 shell-command-switch
1084 (setq msg exit-status)) 1093 (format (Man-build-man-command) man-args)))
1085 (Man-bgproc-sentinel bufname msg))))) 1094 (msg ""))
1086 buffer)) 1095 (or (and (numberp exit-status)
1096 (= exit-status 0))
1097 (and (numberp exit-status)
1098 (setq msg
1099 (format "exited abnormally with code %d"
1100 exit-status)))
1101 (setq msg exit-status))
1102 (if Man-fontify-manpage-flag
1103 (Man-fontify-manpage)
1104 (Man-cleanup-manpage))
1105 (Man-bgproc-sentinel bufname msg))))))
1106 buffer))
1087 1107
1088(defun Man-update-manpage () 1108(defun Man-update-manpage ()
1089 "Reformat current manpage by calling the man command again synchronously." 1109 "Reformat current manpage by calling the man command again synchronously."
@@ -1168,7 +1188,6 @@ See the variable `Man-notify-method' for the different notification behaviors."
1168 "Convert overstriking and underlining to the correct fonts. 1188 "Convert overstriking and underlining to the correct fonts.
1169Same for the ANSI bold and normal escape sequences." 1189Same for the ANSI bold and normal escape sequences."
1170 (interactive) 1190 (interactive)
1171 (message "Please wait: formatting the %s man page..." Man-arguments)
1172 (goto-char (point-min)) 1191 (goto-char (point-min))
1173 ;; Fontify ANSI escapes. 1192 ;; Fontify ANSI escapes.
1174 (let ((ansi-color-apply-face-function 1193 (let ((ansi-color-apply-face-function
@@ -1183,7 +1202,7 @@ Same for the ANSI bold and normal escape sequences."
1183 ;; Multibyte characters exist. 1202 ;; Multibyte characters exist.
1184 (progn 1203 (progn
1185 (goto-char (point-min)) 1204 (goto-char (point-min))
1186 (while (search-forward "__\b\b" nil t) 1205 (while (and (search-forward "__\b\b" nil t) (not (eobp)))
1187 (backward-delete-char 4) 1206 (backward-delete-char 4)
1188 (put-text-property (point) (1+ (point)) 'face 'Man-underline)) 1207 (put-text-property (point) (1+ (point)) 'face 'Man-underline))
1189 (goto-char (point-min)) 1208 (goto-char (point-min))
@@ -1191,7 +1210,7 @@ Same for the ANSI bold and normal escape sequences."
1191 (backward-delete-char 4) 1210 (backward-delete-char 4)
1192 (put-text-property (1- (point)) (point) 'face 'Man-underline)))) 1211 (put-text-property (1- (point)) (point) 'face 'Man-underline))))
1193 (goto-char (point-min)) 1212 (goto-char (point-min))
1194 (while (search-forward "_\b" nil t) 1213 (while (and (search-forward "_\b" nil t) (not (eobp)))
1195 (backward-delete-char 2) 1214 (backward-delete-char 2)
1196 (put-text-property (point) (1+ (point)) 'face 'Man-underline)) 1215 (put-text-property (point) (1+ (point)) 'face 'Man-underline))
1197 (goto-char (point-min)) 1216 (goto-char (point-min))
@@ -1223,8 +1242,7 @@ Same for the ANSI bold and normal escape sequences."
1223 (while (re-search-forward Man-heading-regexp nil t) 1242 (while (re-search-forward Man-heading-regexp nil t)
1224 (put-text-property (match-beginning 0) 1243 (put-text-property (match-beginning 0)
1225 (match-end 0) 1244 (match-end 0)
1226 'face 'Man-overstrike))) 1245 'face 'Man-overstrike))))
1227 (message "%s man page formatted" (Man-page-from-arguments Man-arguments)))
1228 1246
1229(defun Man-highlight-references (&optional xref-man-type) 1247(defun Man-highlight-references (&optional xref-man-type)
1230 "Highlight the references on mouse-over. 1248 "Highlight the references on mouse-over.
@@ -1286,8 +1304,6 @@ Normally skip any jobs that should have been done by the sed script,
1286but when called interactively, do those jobs even if the sed 1304but when called interactively, do those jobs even if the sed
1287script would have done them." 1305script would have done them."
1288 (interactive "p") 1306 (interactive "p")
1289 (message "Please wait: cleaning up the %s man page..."
1290 Man-arguments)
1291 (if (or interactive (not Man-sed-script)) 1307 (if (or interactive (not Man-sed-script))
1292 (progn 1308 (progn
1293 (goto-char (point-min)) 1309 (goto-char (point-min))
@@ -1309,8 +1325,35 @@ script would have done them."
1309 ;; their preceding chars (but don't put Man-overstrike). (Bug#5566) 1325 ;; their preceding chars (but don't put Man-overstrike). (Bug#5566)
1310 (goto-char (point-min)) 1326 (goto-char (point-min))
1311 (while (re-search-forward ".\b" nil t) (backward-delete-char 2)) 1327 (while (re-search-forward ".\b" nil t) (backward-delete-char 2))
1312 (Man-softhyphen-to-minus) 1328 (Man-softhyphen-to-minus))
1313 (message "%s man page cleaned up" Man-arguments)) 1329
1330(defun Man-bgproc-filter (process string)
1331 "Manpage background process filter.
1332When manpage command is run asynchronously, PROCESS is the process
1333object for the manpage command; when manpage command is run
1334synchronously, PROCESS is the name of the buffer where the manpage
1335command is run. Second argument STRING is the entire string of output."
1336 (save-excursion
1337 (let ((Man-buffer (process-buffer process)))
1338 (if (null (buffer-name Man-buffer)) ;; deleted buffer
1339 (set-process-buffer process nil)
1340
1341 (with-current-buffer Man-buffer
1342 (let ((inhibit-read-only t)
1343 (beg (marker-position (process-mark process))))
1344 (save-excursion
1345 (goto-char beg)
1346 (insert string)
1347 (save-restriction
1348 (narrow-to-region
1349 (save-excursion
1350 (goto-char beg)
1351 (line-beginning-position))
1352 (point))
1353 (if Man-fontify-manpage-flag
1354 (Man-fontify-manpage)
1355 (Man-cleanup-manpage)))
1356 (set-marker (process-mark process) (point-max)))))))))
1314 1357
1315(defun Man-bgproc-sentinel (process msg) 1358(defun Man-bgproc-sentinel (process msg)
1316 "Manpage background process sentinel. 1359 "Manpage background process sentinel.
@@ -1329,63 +1372,74 @@ manpage command."
1329 (set-process-buffer process nil)) 1372 (set-process-buffer process nil))
1330 1373
1331 (with-current-buffer Man-buffer 1374 (with-current-buffer Man-buffer
1332 (let ((case-fold-search nil)) 1375 (save-excursion
1333 (goto-char (point-min)) 1376 (let ((case-fold-search nil))
1334 (cond ((or (looking-at "No \\(manual \\)*entry for") 1377 (goto-char (point-min))
1335 (looking-at "[^\n]*: nothing appropriate$")) 1378 (cond ((or (looking-at "No \\(manual \\)*entry for")
1336 (setq err-mess (buffer-substring (point) 1379 (looking-at "[^\n]*: nothing appropriate$"))
1337 (progn 1380 (setq err-mess (buffer-substring (point)
1338 (end-of-line) (point))) 1381 (progn
1339 delete-buff t)) 1382 (end-of-line) (point)))
1340 1383 delete-buff t))
1341 ;; "-k foo", successful exit, but no output (from man-db) 1384
1342 ;; ENHANCE-ME: share the check for -k with 1385 ;; "-k foo", successful exit, but no output (from man-db)
1343 ;; `Man-highlight-references'. The \\s- bits here are 1386 ;; ENHANCE-ME: share the check for -k with
1344 ;; meant to allow for multiple options with -k among them. 1387 ;; `Man-highlight-references'. The \\s- bits here are
1345 ((and (string-match "\\(\\`\\|\\s-\\)-k\\s-" Man-arguments) 1388 ;; meant to allow for multiple options with -k among them.
1346 (eq (process-status process) 'exit) 1389 ((and (string-match "\\(\\`\\|\\s-\\)-k\\s-" Man-arguments)
1347 (= (process-exit-status process) 0) 1390 (eq (process-status process) 'exit)
1348 (= (point-min) (point-max))) 1391 (= (process-exit-status process) 0)
1349 (setq err-mess (format "%s: no matches" Man-arguments) 1392 (= (point-min) (point-max)))
1350 delete-buff t)) 1393 (setq err-mess (format "%s: no matches" Man-arguments)
1351 1394 delete-buff t))
1352 ((or (stringp process) 1395
1353 (not (and (eq (process-status process) 'exit) 1396 ((or (stringp process)
1354 (= (process-exit-status process) 0)))) 1397 (not (and (eq (process-status process) 'exit)
1355 (or (zerop (length msg)) 1398 (= (process-exit-status process) 0))))
1356 (progn 1399 (or (zerop (length msg))
1357 (setq err-mess 1400 (progn
1358 (concat (buffer-name Man-buffer) 1401 (setq err-mess
1359 ": process " 1402 (concat (buffer-name Man-buffer)
1360 (let ((eos (1- (length msg)))) 1403 ": process "
1361 (if (= (aref msg eos) ?\n) 1404 (let ((eos (1- (length msg))))
1362 (substring msg 0 eos) msg)))) 1405 (if (= (aref msg eos) ?\n)
1363 (goto-char (point-max)) 1406 (substring msg 0 eos) msg))))
1364 (insert (format "\nprocess %s" msg)))) 1407 (goto-char (point-max))
1365 )) 1408 (insert (format "\nprocess %s" msg))))
1366 (if delete-buff 1409 ))
1367 (kill-buffer Man-buffer) 1410 (if delete-buff
1368 (if Man-fontify-manpage-flag 1411 (if (window-live-p (get-buffer-window Man-buffer t))
1369 (Man-fontify-manpage) 1412 (quit-restore-window
1370 (Man-cleanup-manpage)) 1413 (get-buffer-window Man-buffer t) 'kill)
1371 1414 (kill-buffer Man-buffer))
1372 (run-hooks 'Man-cooked-hook) 1415
1373 (Man-mode) 1416 (run-hooks 'Man-cooked-hook)
1374 1417
1375 (if (not Man-page-list) 1418 (Man-build-page-list)
1376 (let ((args Man-arguments)) 1419 (Man-strip-page-headers)
1377 (kill-buffer (current-buffer)) 1420 (Man-unindent)
1378 (user-error "Can't find the %s manpage" 1421 (Man-goto-page 1 t)
1379 (Man-page-from-arguments args))) 1422
1380 (set-buffer-modified-p nil)))) 1423 (if (not Man-page-list)
1381 ;; Restore case-fold-search before calling 1424 (let ((args Man-arguments))
1382 ;; Man-notify-when-ready because it may switch buffers. 1425 (if (window-live-p (get-buffer-window (current-buffer) t))
1383 1426 (quit-restore-window
1384 (if (not delete-buff) 1427 (get-buffer-window (current-buffer) t) 'kill)
1385 (Man-notify-when-ready Man-buffer)) 1428 (kill-buffer (current-buffer)))
1429 (message "Can't find the %s manpage"
1430 (Man-page-from-arguments args)))
1431
1432 (if Man-fontify-manpage-flag
1433 (message "%s man page formatted"
1434 (Man-page-from-arguments Man-arguments))
1435 (message "%s man page cleaned up" Man-arguments))
1436 (unless (and (processp process)
1437 (not (eq (process-status process) 'exit)))
1438 (setq mode-line-process nil))
1439 (set-buffer-modified-p nil)))))
1386 1440
1387 (if err-mess 1441 (if err-mess
1388 (error "%s" err-mess)) 1442 (message "%s" err-mess))
1389 )))) 1443 ))))
1390 1444
1391(defun Man-page-from-arguments (args) 1445(defun Man-page-from-arguments (args)
@@ -1429,7 +1483,7 @@ The following man commands are available in the buffer. Try
1429The following variables may be of some use. Try 1483The following variables may be of some use. Try
1430\"\\[describe-variable] <variable-name> RET\" for more information: 1484\"\\[describe-variable] <variable-name> RET\" for more information:
1431 1485
1432`Man-notify-method' What happens when manpage formatting is done. 1486`Man-notify-method' What happens when manpage is ready to display.
1433`Man-downcase-section-letters-flag' Force section letters to lower case. 1487`Man-downcase-section-letters-flag' Force section letters to lower case.
1434`Man-circular-pages-flag' Treat multiple manpage list as circular. 1488`Man-circular-pages-flag' Treat multiple manpage list as circular.
1435`Man-section-translations-alist' List of section numbers and their Un*x equiv. 1489`Man-section-translations-alist' List of section numbers and their Un*x equiv.
@@ -1458,11 +1512,7 @@ The following key bindings are currently in effect in the buffer:
1458 (set (make-local-variable 'outline-regexp) Man-heading-regexp) 1512 (set (make-local-variable 'outline-regexp) Man-heading-regexp)
1459 (set (make-local-variable 'outline-level) (lambda () 1)) 1513 (set (make-local-variable 'outline-level) (lambda () 1))
1460 (set (make-local-variable 'bookmark-make-record-function) 1514 (set (make-local-variable 'bookmark-make-record-function)
1461 'Man-bookmark-make-record) 1515 'Man-bookmark-make-record))
1462 (Man-build-page-list)
1463 (Man-strip-page-headers)
1464 (Man-unindent)
1465 (Man-goto-page 1 t))
1466 1516
1467(defsubst Man-build-section-alist () 1517(defsubst Man-build-section-alist ()
1468 "Build the list of manpage sections." 1518 "Build the list of manpage sections."
@@ -1516,7 +1566,6 @@ The following key bindings are currently in effect in the buffer:
1516 (page-end (point-max)) 1566 (page-end (point-max))
1517 (header "")) 1567 (header ""))
1518 (goto-char page-start) 1568 (goto-char page-start)
1519 ;; (switch-to-buffer (current-buffer))(debug)
1520 (while (not (eobp)) 1569 (while (not (eobp))
1521 (setq header 1570 (setq header
1522 (if (looking-at Man-page-header-regexp) 1571 (if (looking-at Man-page-header-regexp)