aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Winkler2008-08-18 00:47:12 +0000
committerRoland Winkler2008-08-18 00:47:12 +0000
commit9f583d141ffe6198a69c57491fb4f1349f020b22 (patch)
treea225c21e8220696d5873fc56e372accad8021d05
parente56d3af5f0f28aea89004fcce2c140c8a4d5b468 (diff)
downloademacs-9f583d141ffe6198a69c57491fb4f1349f020b22.tar.gz
emacs-9f583d141ffe6198a69c57491fb4f1349f020b22.zip
(proced-signal-list): Add POSIX 1003.1-2001 signals.
(proced-mode-map): Add tooltips for menus. Use radio buttons for listing types. (proced-log-buffer): New variable. (proced-mark-all, proced-unmark-all, proced-do-mark-al): Operate on region if transient-mark-mode is turned on and the region is active. (proced-omit-processes): Renamed from proced-hide-processes to avoid key clash with describe-mode (bound to h). Search for marked processes starting from point-min. (proced-header-space): Removed. (proced-send-signal): Handle errors. Operate on current process if no process is marked. (proced-why): New command. (proced-log, proced-log-summary): New functions. (proced-help): Use proced-why.
-rw-r--r--lisp/ChangeLog21
-rw-r--r--lisp/proced.el358
2 files changed, 261 insertions, 118 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 801920d06a4..08cafe3853f 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,24 @@
12008-08-17 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de>
2
3 * proced.el (proced-signal-list): Add POSIX 1003.1-2001 signals.
4 (proced-mode-map): Add tooltips for menus. Use radio buttons for
5 listing types.
6 (proced-log-buffer): New variable.
7 (proced-mark-all, proced-unmark-all, proced-do-mark-al): Operate
8 on region if transient-mark-mode is turned on and the region is
9 active.
10 (proced-omit-processes): Renamed from proced-hide-processes to
11 avoid key clash with describe-mode (bound to h). Search for
12 marked processes starting from point-min.
13 (proced-header-space): Removed.
14 (proced-send-signal): Handle errors. Operate on current process
15 if no process is marked.
16 (proced-why): New command.
17 (proced-log, proced-log-summary): New functions.
18 (proced-help): Use proced-why.
19 * textmodes/bibtex.el (bibtex-entry-format): Mark as safe.
20 (bibtex-autokey-year-title-separator): Fix doscstring.
21
12008-08-17 Michael Albinus <michael.albinus@gmx.de> 222008-08-17 Michael Albinus <michael.albinus@gmx.de>
2 23
3 * net/xesam.el (xesam-vendor, xesam-notify-function): New local 24 * net/xesam.el (xesam-vendor, xesam-notify-function): New local
diff --git a/lisp/proced.el b/lisp/proced.el
index 436189d8f6a..0df3b9a9792 100644
--- a/lisp/proced.el
+++ b/lisp/proced.el
@@ -28,14 +28,15 @@
28;; on the processes listed. 28;; on the processes listed.
29;; 29;;
30;; To do: 30;; To do:
31;; - decompose ps(1) output into columns (for `proced-header-alist') 31;; - use list-system-processes and system-process-attributes
32;; How can we identify columns that may contain whitespace 32;; - sort and filter by user name or other criteria
33;; and that can be either right or left justified? 33;; - make fields clickable for marking / filtering / sorting:
34;; Use a "grammar table"? 34;; clicking on a USER field marks all processes of this user etc
35;; - sort the "cooked" values used in the output format fields 35;; clicking on a %MEM field marks all processes with at least this %MEM.
36;; if ps(1) doesn't support the requested sorting scheme 36;; clicking on a header field sorts according to this header
37;; - filter by user name or other criteria 37;; - mark parent and children PIDs (or both)
38;; - automatic update of process list 38;; - automatic update of process list
39;; - allow "sudo kill PID", "renice PID"
39 40
40;;; Code: 41;;; Code:
41 42
@@ -143,13 +144,20 @@ the external command (usually \"kill\")."
143 (string :tag "command"))) 144 (string :tag "command")))
144 145
145(defcustom proced-signal-list 146(defcustom proced-signal-list
146 '(("HUP (1. Hangup)") 147 '(;; signals supported on all POSIX compliant systems
148 ("HUP (1. Hangup)")
147 ("INT (2. Terminal interrupt)") 149 ("INT (2. Terminal interrupt)")
148 ("QUIT (3. Terminal quit)") 150 ("QUIT (3. Terminal quit)")
149 ("ABRT (6. Process abort)") 151 ("ABRT (6. Process abort)")
150 ("KILL (9. Kill -- cannot be caught or ignored)") 152 ("KILL (9. Kill - cannot be caught or ignored)")
151 ("ALRM (14. Alarm Clock)") 153 ("ALRM (14. Alarm Clock)")
152 ("TERM (15. Termination)")) 154 ("TERM (15. Termination)")
155 ;; POSIX 1003.1-2001
156 ;; Which systems do not support these signals so that we can
157 ;; exclude them from `proced-signal-list'?
158 ("CONT (Continue executing)")
159 ("STOP (Stop executing / pause - cannot be caught or ignored)")
160 ("TSTP (Terminal stop / pause)"))
153 "List of signals, used for minibuffer completion." 161 "List of signals, used for minibuffer completion."
154 :group 'proced 162 :group 'proced
155 :type '(repeat (string :tag "signal"))) 163 :type '(repeat (string :tag "signal")))
@@ -223,7 +231,7 @@ Important: the match ends just after the marker.")
223 (define-key km "sS" 'proced-sort) 231 (define-key km "sS" 'proced-sort)
224 (define-key km "st" 'proced-sort-time) 232 (define-key km "st" 'proced-sort-time)
225 ;; operate 233 ;; operate
226 (define-key km "h" 'proced-hide-processes) 234 (define-key km "o" 'proced-omit-processes)
227 (define-key km "x" 'proced-send-signal) ; Dired compatibility 235 (define-key km "x" 'proced-send-signal) ; Dired compatibility
228 (define-key km "k" 'proced-send-signal) ; kill processes 236 (define-key km "k" 'proced-send-signal) ; kill processes
229 ;; misc 237 ;; misc
@@ -235,29 +243,45 @@ Important: the match ends just after the marker.")
235 (define-key km [remap undo] 'proced-undo) 243 (define-key km [remap undo] 'proced-undo)
236 (define-key km [remap advertised-undo] 'proced-undo) 244 (define-key km [remap advertised-undo] 'proced-undo)
237 km) 245 km)
238 "Keymap for proced commands") 246 "Keymap for proced commands.")
239 247
240(easy-menu-define 248(easy-menu-define
241 proced-menu proced-mode-map "Proced Menu" 249 proced-menu proced-mode-map "Proced Menu"
242 '("Proced" 250 `("Proced"
243 ["Mark" proced-mark t] 251 ["Mark" proced-mark
244 ["Unmark" proced-unmark t] 252 :help "Mark Current Process"]
245 ["Mark All" proced-mark-all t] 253 ["Unmark" proced-unmark
246 ["Unmark All" proced-unmark-all t] 254 :help "Unmark Current Process"]
247 ["Toggle Marks" proced-toggle-marks t] 255 ["Mark All" proced-mark-all
256 :help "Mark All Processes"]
257 ["Unmark All" proced-unmark-all
258 :help "Unmark All Process"]
259 ["Toggle Marks" proced-toggle-marks
260 :help "Marked Processes Become Unmarked, and Vice Versa"]
248 "--" 261 "--"
249 ["Sort" proced-sort t] 262 ["Sort..." proced-sort
263 :help "Sort Process List"]
250 ["Sort by %CPU" proced-sort-pcpu (proced-sorting-scheme-p "%CPU")] 264 ["Sort by %CPU" proced-sort-pcpu (proced-sorting-scheme-p "%CPU")]
251 ["Sort by %MEM" proced-sort-pmem (proced-sorting-scheme-p "%MEM")] 265 ["Sort by %MEM" proced-sort-pmem (proced-sorting-scheme-p "%MEM")]
252 ["Sort by PID" proced-sort-pid (proced-sorting-scheme-p "PID")] 266 ["Sort by PID" proced-sort-pid (proced-sorting-scheme-p "PID")]
253 ["Sort by START" proced-sort-start (proced-sorting-scheme-p "START")] 267 ["Sort by START" proced-sort-start (proced-sorting-scheme-p "START")]
254 ["Sort by TIME" proced-sort-time (proced-sorting-scheme-p "TIME")] 268 ["Sort by TIME" proced-sort-time (proced-sorting-scheme-p "TIME")]
255 "--" 269 "--"
256 ["Hide Marked Processes" proced-hide-processes t] 270 ["Omit Marked Processes" proced-omit-processes
271 :help "Omit Marked Processes in Process Listing."]
257 "--" 272 "--"
258 ["Revert" revert-buffer t] 273 ["Revert" revert-buffer
259 ["Send signal" proced-send-signal t] 274 :help "Revert Process Listing"]
260 ["Change listing" proced-listing-type t])) 275 ["Send signal" proced-send-signal
276 :help "Send Signal to Marked Processes"]
277 ("Listing Type"
278 :help "Select Type of Process Listing"
279 ,@(mapcar (lambda (el)
280 (let ((command (car el)))
281 `[,command (proced-listing-type ,command)
282 :style radio
283 :selected (string= proced-command ,command)]))
284 proced-command-alist))))
261 285
262(defconst proced-help-string 286(defconst proced-help-string
263 "(n)ext, (p)revious, (m)ark, (u)nmark, (k)ill, (q)uit (type ? for more help)" 287 "(n)ext, (p)revious, (m)ark, (u)nmark, (k)ill, (q)uit (type ? for more help)"
@@ -280,6 +304,9 @@ JUSTIFY is 'left or 'right for left or right-justified output of ps(1).")
280 "Regexp to match valid sorting schemes.") 304 "Regexp to match valid sorting schemes.")
281(make-variable-buffer-local 'proced-sorting-schemes-re) 305(make-variable-buffer-local 'proced-sorting-schemes-re)
282 306
307(defvar proced-log-buffer "*Proced log*"
308 "Name of Proced Log buffer.")
309
283;; helper functions 310;; helper functions
284(defun proced-marker-regexp () 311(defun proced-marker-regexp ()
285 "Return regexp matching `proced-marker-char'." 312 "Return regexp matching `proced-marker-char'."
@@ -339,10 +366,8 @@ information will be displayed but not selected.
339 (set-buffer buffer) 366 (set-buffer buffer)
340 (setq new (zerop (buffer-size))) 367 (setq new (zerop (buffer-size)))
341 (if new (proced-mode)) 368 (if new (proced-mode))
342
343 (if (or new arg) 369 (if (or new arg)
344 (proced-update)) 370 (proced-update))
345
346 (if arg 371 (if arg
347 (display-buffer buffer) 372 (display-buffer buffer)
348 (pop-to-buffer buffer) 373 (pop-to-buffer buffer)
@@ -382,7 +407,7 @@ Optional prefix ARG says how many lines to move; default is one line."
382 (proced-do-mark nil (- (or count 1)))) 407 (proced-do-mark nil (- (or count 1))))
383 408
384(defun proced-do-mark (mark &optional count) 409(defun proced-do-mark (mark &optional count)
385 "Mark the current (or next ARG) processes using MARK." 410 "Mark the current (or next COUNT) processes using MARK."
386 (or count (setq count 1)) 411 (or count (setq count 1))
387 (let ((backward (< count 0)) 412 (let ((backward (< count 0))
388 buffer-read-only) 413 buffer-read-only)
@@ -394,22 +419,40 @@ Optional prefix ARG says how many lines to move; default is one line."
394 (proced-move-to-goal-column))) 419 (proced-move-to-goal-column)))
395 420
396(defun proced-mark-all () 421(defun proced-mark-all ()
397 "Mark all processes." 422 "Mark all processes.
423If `transient-mark-mode' is turned on and the region is active,
424mark the region."
398 (interactive) 425 (interactive)
399 (proced-do-mark-all t)) 426 (proced-do-mark-all t))
400 427
401(defun proced-unmark-all () 428(defun proced-unmark-all ()
402 "Unmark all processes." 429 "Unmark all processes.
430If `transient-mark-mode' is turned on and the region is active,
431unmark the region."
403 (interactive) 432 (interactive)
404 (proced-do-mark-all nil)) 433 (proced-do-mark-all nil))
405 434
406(defun proced-do-mark-all (mark) 435(defun proced-do-mark-all (mark)
407 "Mark all processes using MARK." 436 "Mark all processes using MARK.
437If `transient-mark-mode' is turned on and the region is active,
438mark the region."
408 (let (buffer-read-only) 439 (let (buffer-read-only)
409 (save-excursion 440 (save-excursion
410 (goto-char (point-min)) 441 (if (and transient-mark-mode mark-active)
411 (while (not (eobp)) 442 ;; Operate even on those lines that are only partially a part
412 (proced-insert-mark mark))))) 443 ;; of region. This appears most consistent with
444 ;; `proced-move-to-goal-column'.
445 (let ((end (save-excursion
446 (goto-char (region-end))
447 (unless (looking-at "^") (forward-line))
448 (point))))
449 (goto-char (region-beginning))
450 (unless (looking-at "^") (beginning-of-line))
451 (while (< (point) end)
452 (proced-insert-mark mark)))
453 (goto-char (point-min))
454 (while (not (eobp))
455 (proced-insert-mark mark))))))
413 456
414(defun proced-toggle-marks () 457(defun proced-toggle-marks ()
415 "Toggle marks: marked processes become unmarked, and vice versa." 458 "Toggle marks: marked processes become unmarked, and vice versa."
@@ -439,35 +482,36 @@ Otherwise move one line forward after inserting the mark."
439;; However, for negative args the target lines of `dired-do-kill-lines' 482;; However, for negative args the target lines of `dired-do-kill-lines'
440;; include the current line, whereas `dired-mark' for negative args operates 483;; include the current line, whereas `dired-mark' for negative args operates
441;; on the preceding lines. Here we are consistent with `dired-mark'. 484;; on the preceding lines. Here we are consistent with `dired-mark'.
442(defun proced-hide-processes (&optional arg quiet) 485(defun proced-omit-processes (&optional arg quiet)
443 "Hide marked processes. 486 "Omit marked processes.
444With prefix ARG, hide that many lines starting with the current line. 487With prefix ARG, omit that many lines starting with the current line.
445\(A negative argument hides backward.) 488\(A negative argument omits backward.)
446If QUIET is non-nil suppress status message. 489If QUIET is non-nil suppress status message.
447Returns count of hidden lines." 490Returns count of omitted lines."
448 (interactive "P") 491 (interactive "P")
449 (let ((mark-re (proced-marker-regexp)) 492 (let ((mark-re (proced-marker-regexp))
450 (count 0) 493 (count 0)
451 buffer-read-only) 494 buffer-read-only)
452 (save-excursion 495 (if arg
453 (if arg 496 ;; Omit ARG lines starting with the current line.
454 ;; Hide ARG lines starting with the current line. 497 (delete-region (line-beginning-position)
455 (delete-region (line-beginning-position) 498 (save-excursion
456 (save-excursion 499 (if (<= 0 arg)
457 (if (<= 0 arg) 500 (setq count (- arg (forward-line arg)))
458 (setq count (- arg (forward-line arg))) 501 (setq count (min (1- (line-number-at-pos))
459 (setq count (min (1- (line-number-at-pos)) 502 (abs arg)))
460 (abs arg))) 503 (forward-line (- count)))
461 (forward-line (- count))) 504 (point)))
462 (point))) 505 ;; Omit marked lines
463 ;; Hide marked lines 506 (save-excursion
507 (goto-char (point-min))
464 (while (and (not (eobp)) 508 (while (and (not (eobp))
465 (re-search-forward mark-re nil t)) 509 (re-search-forward mark-re nil t))
466 (delete-region (match-beginning 0) 510 (delete-region (match-beginning 0)
467 (save-excursion (forward-line) (point))) 511 (save-excursion (forward-line) (point)))
468 (setq count (1+ count))))) 512 (setq count (1+ count)))))
469 (unless (zerop count) (proced-move-to-goal-column)) 513 (unless (zerop count) (proced-move-to-goal-column))
470 (unless quiet (proced-success-message "Hid" count)) 514 (unless quiet (proced-success-message "Omitted" count))
471 count)) 515 count))
472 516
473(defun proced-listing-type (command) 517(defun proced-listing-type (command)
@@ -477,12 +521,6 @@ Returns count of hidden lines."
477 (setq proced-command command) 521 (setq proced-command command)
478 (proced-update)) 522 (proced-update))
479 523
480;; adopted from `ruler-mode-space'
481(defsubst proced-header-space (width)
482 "Return a single space string of WIDTH times the normal character width."
483 (propertize " " 'display (list 'space :width width)))
484
485;; header line: code inspired by `ruler-mode-ruler'
486(defun proced-header-line () 524(defun proced-header-line ()
487 "Return header line for Proced buffer." 525 "Return header line for Proced buffer."
488 (list (propertize " " 'display '(space :align-to 0)) 526 (list (propertize " " 'display '(space :align-to 0))
@@ -490,7 +528,8 @@ Returns count of hidden lines."
490 "%" "%%" (substring proced-header-line (window-hscroll))))) 528 "%" "%%" (substring proced-header-line (window-hscroll)))))
491 529
492(defun proced-update (&optional quiet) 530(defun proced-update (&optional quiet)
493 "Update the `proced' process information. Preserves point and marks." 531 "Update the `proced' process information. Preserves point and marks.
532Suppress status information if QUIET is nil."
494 ;; This is the main function that generates and updates the process listing. 533 ;; This is the main function that generates and updates the process listing.
495 (interactive) 534 (interactive)
496 (or quiet (message "Updating process information...")) 535 (or quiet (message "Updating process information..."))
@@ -594,6 +633,7 @@ Returns count of hidden lines."
594 633
595(defun proced-send-signal (&optional signal) 634(defun proced-send-signal (&optional signal)
596 "Send a SIGNAL to the marked processes. 635 "Send a SIGNAL to the marked processes.
636If no process is marked, operate on current process.
597SIGNAL may be a string (HUP, INT, TERM, etc.) or a number. 637SIGNAL may be a string (HUP, INT, TERM, etc.) or a number.
598If SIGNAL is nil display marked processes and query interactively for SIGNAL." 638If SIGNAL is nil display marked processes and query interactively for SIGNAL."
599 (interactive) 639 (interactive)
@@ -610,71 +650,153 @@ If SIGNAL is nil display marked processes and query interactively for SIGNAL."
610 ;; and the command name? 650 ;; and the command name?
611 (substring (match-string-no-properties 0) 2)) 651 (substring (match-string-no-properties 0) 2))
612 process-list))) 652 process-list)))
613 (setq process-list (nreverse process-list)) 653 (setq process-list
614 (if (not process-list) 654 (if process-list
615 (message "No processes marked") 655 (nreverse process-list)
616 (unless signal 656 ;; take current process
617 ;; Display marked processes (code taken from `dired-mark-pop-up'). 657 (save-excursion
618 (let ((bufname " *Marked Processes*") 658 (line-beginning-position)
619 (header proced-header-line)) ; inherit header line 659 (looking-at (concat "^" (proced-skip-regexp)
620 (with-current-buffer (get-buffer-create bufname) 660 "\\s-+\\([0-9]+\\>\\).*$"))
621 (setq truncate-lines t 661 (list (cons (match-string-no-properties 1)
622 proced-header-line header 662 (substring (match-string-no-properties 0) 2))))))
623 header-line-format '(:eval (proced-header-line))) 663 (unless signal
624 (add-hook 'post-command-hook 'force-mode-line-update nil t) 664 ;; Display marked processes (code taken from `dired-mark-pop-up').
625 (erase-buffer) 665 (let ((bufname " *Marked Processes*")
626 (dolist (process process-list) 666 (header proced-header-line)) ; inherit header line
627 (insert " " (cdr process) "\n")) 667 (with-current-buffer (get-buffer-create bufname)
628 (save-window-excursion 668 (setq truncate-lines t
629 (dired-pop-to-buffer bufname) ; all we need 669 proced-header-line header
630 (let* ((completion-ignore-case t) 670 header-line-format '(:eval (proced-header-line)))
631 (pnum (if (= 1 (length process-list)) 671 (add-hook 'post-command-hook 'force-mode-line-update nil t)
632 "1 process" 672 (erase-buffer)
633 (format "%d processes" (length process-list)))) 673 (dolist (process process-list)
634 ;; The following is an ugly hack. Is there a better way 674 (insert " " (cdr process) "\n"))
635 ;; to help people like me to remember the signals and 675 (save-window-excursion
636 ;; their meanings? 676 (dired-pop-to-buffer bufname) ; all we need
637 (tmp (completing-read (concat "Send signal [" pnum 677 (let* ((completion-ignore-case t)
638 "] (default TERM): ") 678 (pnum (if (= 1 (length process-list))
639 proced-signal-list 679 "1 process"
640 nil nil nil nil "TERM"))) 680 (format "%d processes" (length process-list))))
641 (setq signal (if (string-match "^\\(\\S-+\\)\\s-" tmp) 681 ;; The following is an ugly hack. Is there a better way
642 (match-string 1 tmp) tmp)))))) 682 ;; to help people like me to remember the signals and
643 ;; send signal 683 ;; their meanings?
644 (let ((count 0) 684 (tmp (completing-read (concat "Send signal [" pnum
645 err-list) 685 "] (default TERM): ")
646 (if (functionp proced-signal-function) 686 proced-signal-list
647 ;; use built-in `signal-process' 687 nil nil nil nil "TERM")))
648 (let ((signal (if (stringp signal) 688 (setq signal (if (string-match "^\\(\\S-+\\)\\s-" tmp)
649 (if (string-match "\\`[0-9]+\\'" signal) 689 (match-string 1 tmp) tmp))))))
650 (string-to-number signal) 690 ;; send signal
651 (make-symbol signal)) 691 (let ((count 0)
652 signal))) ; number 692 failures)
653 (dolist (process process-list) 693 ;; Why not always use `signal-process'? See
654 (if (zerop (funcall 694 ;; http://lists.gnu.org/archive/html/emacs-devel/2008-03/msg02955.html
655 proced-signal-function 695 (if (functionp proced-signal-function)
656 (string-to-number (car process)) signal)) 696 ;; use built-in `signal-process'
657 (setq count (1+ count)) 697 (let ((signal (if (stringp signal)
658 (push (cdr process) err-list)))) 698 (if (string-match "\\`[0-9]+\\'" signal)
659 ;; use external system call 699 (string-to-number signal)
660 (let ((signal (concat "-" (if (numberp signal) 700 (make-symbol signal))
661 (number-to-string signal) signal)))) 701 signal))) ; number
662 (dolist (process process-list) 702 (dolist (process process-list)
663 (if (zerop (call-process 703 (condition-case err
664 proced-signal-function nil 0 nil 704 (if (zerop (funcall
665 signal (car process))) 705 proced-signal-function
666 (setq count (1+ count)) 706 (string-to-number (car process)) signal))
667 (push (cdr process) err-list))))) 707 (setq count (1+ count))
668 (if err-list 708 (proced-log "%s\n" (cdr process))
669 ;; FIXME: that's not enough to display the errors. 709 (push (cdr process) failures))
670 (message "%s: %s" signal err-list) 710 (error ;; catch errors from failed signals
671 (proced-success-message "Sent signal to" count))) 711 (proced-log "%s\n" err)
672 ;; final clean-up 712 (proced-log "%s\n" (cdr process))
673 (run-hooks 'proced-after-send-signal-hook))))) 713 (push (cdr process) failures)))))
714 ;; use external system call
715 (let ((signal (concat "-" (if (numberp signal)
716 (number-to-string signal) signal))))
717 (dolist (process process-list)
718 (with-temp-buffer
719 (condition-case err
720 (if (zerop (call-process
721 proced-signal-function nil t nil
722 signal (car process)))
723 (setq count (1+ count))
724 (proced-log (current-buffer))
725 (proced-log "%s\n" (cdr process))
726 (push (cdr process) failures))
727 (error ;; catch errors from failed signals
728 (proced-log (current-buffer))
729 (proced-log "%s\n" (cdr process))
730 (push (cdr process) failures)))))))
731 (if failures
732 (proced-log-summary
733 signal
734 (format "%d of %d signal%s failed"
735 (length failures) (length process-list)
736 (if (= 1 (length process-list)) "" "s")))
737 (proced-success-message "Sent signal to" count)))
738 ;; final clean-up
739 (run-hooks 'proced-after-send-signal-hook))))
740
741;; just like `dired-why'
742(defun proced-why ()
743 "Pop up a buffer with error log output from Proced.
744A group of errors from a single command ends with a formfeed.
745Thus, use \\[backward-page] to find the beginning of a group of errors."
746 (interactive)
747 (if (get-buffer proced-log-buffer)
748 (let ((owindow (selected-window))
749 (window (display-buffer (get-buffer proced-log-buffer))))
750 (unwind-protect
751 (progn
752 (select-window window)
753 (goto-char (point-max))
754 (forward-line -1)
755 (backward-page 1)
756 (recenter 0))
757 (select-window owindow)))))
758
759;; similar to `dired-log'
760(defun proced-log (log &rest args)
761 "Log a message or the contents of a buffer.
762If LOG is a string and there are more args, it is formatted with
763those ARGS. Usually the LOG string ends with a \\n.
764End each bunch of errors with (proced-log t signal):
765this inserts the current time, buffer and signal at the start of the page,
766and \f (formfeed) at the end."
767 (let ((obuf (current-buffer)))
768 (with-current-buffer (get-buffer-create proced-log-buffer)
769 (goto-char (point-max))
770 (let ((inhibit-read-only t))
771 (cond ((stringp log)
772 (insert (if args
773 (apply 'format log args)
774 log)))
775 ((bufferp log)
776 (insert-buffer-substring log))
777 ((eq t log)
778 (backward-page 1)
779 (unless (bolp)
780 (insert "\n"))
781 (insert (current-time-string)
782 "\tBuffer `" (buffer-name obuf) "', "
783 (format "signal `%s'\n" (car args)))
784 (goto-char (point-max))
785 (insert "\f\n")))))))
786
787;; similar to `dired-log-summary'
788(defun proced-log-summary (signal string)
789 "State a summary of SIGNAL's failures, in echo area and log buffer.
790STRING is an overall summary of the failures."
791 (message "Signal %s: %s--type ? for details" signal string)
792 ;; Log a summary describing a bunch of errors.
793 (proced-log (concat "\n" string "\n"))
794 (proced-log t signal))
674 795
675(defun proced-help () 796(defun proced-help ()
676 "Provide help for the `proced' user." 797 "Provide help for the `proced' user."
677 (interactive) 798 (interactive)
799 (proced-why)
678 (if (eq last-command 'proced-help) 800 (if (eq last-command 'proced-help)
679 (describe-mode) 801 (describe-mode)
680 (message proced-help-string))) 802 (message proced-help-string)))
@@ -747,4 +869,4 @@ SCHEME must be a string or nil."
747(provide 'proced) 869(provide 'proced)
748 870
749;; arch-tag: a6e312ad-9032-45aa-972d-31a8cfc545af 871;; arch-tag: a6e312ad-9032-45aa-972d-31a8cfc545af
750;;; proced.el ends here. 872;;; proced.el ends here