1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-02-06 20:49:33 +00:00

(proced-sort-header): New face.

(proced-sort-header-face): New variable.
(proced-format): Allow format value nil.  Use
proced-sort-header-face for header of sort column.
(proced-format-args): New function.
(proced-grammar-alist, proced-timer-flag, proced-process-alist)
(proced-header-help-echo, proced-field-help-echo, proced-timer)
(proced-toggle-timer-flag, proced, proced-mode): Doc fix.
(proced-refine): Renamed from proced-filter-attribute.  Doc fix.
(proced-sort-header): Bind also to mouse-1.
(proced-move-to-goal-column): Return position of point.
(proced-filter-interactive): Always revert listing.
(proced-format-ttname): Simplify.
(proced-update): Do not keep undo information.  Put point at
beginning of buffer if we generate the first listing.
This commit is contained in:
Roland Winkler 2008-09-12 16:59:57 +00:00
parent ce82d57e1c
commit da64319085
2 changed files with 199 additions and 92 deletions

View File

@ -1,3 +1,21 @@
2008-09-12 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de>
* proced.el (proced-sort-header): New face.
(proced-sort-header-face): New variable.
(proced-format): Allow format value nil. Use
proced-sort-header-face for header of sort column.
(proced-format-args): New function.
(proced-grammar-alist, proced-timer-flag, proced-process-alist)
(proced-header-help-echo, proced-field-help-echo, proced-timer)
(proced-toggle-timer-flag, proced, proced-mode): Doc fix.
(proced-refine): Renamed from proced-filter-attribute. Doc fix.
(proced-sort-header): Bind also to mouse-1.
(proced-move-to-goal-column): Return position of point.
(proced-filter-interactive): Always revert listing.
(proced-format-ttname): Simplify.
(proced-update): Do not keep undo information. Put point at
beginning of buffer if we generate the first listing.
2008-09-12 Tassilo Horn <tassilo@member.fsf.org>
* doc-view.el (doc-view-scroll-up-or-next-page)

View File

@ -25,12 +25,15 @@
;; Proced makes an Emacs buffer containing a listing of the current
;; system processes. You can use the normal Emacs commands to move around
;; in this buffer, and special Proced commands to operate on the processes
;; listed.
;; listed. See `proced-mode' for getting started.
;;
;; To do:
;; - use defcustom where appropriate
;; - interactive temporary customizability of `proced-grammar-alist'
;; - interactive temporary customizability of flags in `proced-grammar-alist'
;; - allow "sudo kill PID", "renice PID"
;;
;; Wishlist
;; - tree view like pstree(1)
;;; Code:
@ -84,11 +87,11 @@ the external command (usually \"kill\")."
(defvar proced-grammar-alist
'( ;; attributes defined in `system-process-attributes'
(euid "EUID" "%d" right proced-< nil (euid pid) (nil t nil))
(user "USER" "%s" left proced-string-lessp nil (user pid) (nil t nil))
(user "USER" nil left proced-string-lessp nil (user pid) (nil t nil))
(egid "EGID" "%d" right proced-< nil (egid euid pid) (nil t nil))
(group "GROUP" "%s" left proced-string-lessp nil (group user pid) (nil t nil))
(comm "COMMAND" "%s" left proced-string-lessp nil (comm pid) (nil t nil))
(state "STAT" "%s" left proced-string-lessp nil (state pid) (nil t nil))
(group "GROUP" nil left proced-string-lessp nil (group user pid) (nil t nil))
(comm "COMMAND" nil left proced-string-lessp nil (comm pid) (nil t nil))
(state "STAT" nil left proced-string-lessp nil (state pid) (nil t nil))
(ppid "PPID" "%d" right proced-< nil (ppid pid) (nil t nil))
(pgrp "PGRP" "%d" right proced-< nil (pgrp euid pid) (nil t nil))
(sess "SESS" "%d" right proced-< nil (sess pid) (nil t nil))
@ -111,7 +114,7 @@ the external command (usually \"kill\")."
(etime "ETIME" proced-format-time right proced-time-lessp t (etime pid) (nil t t))
(pcpu "%CPU" "%.1f" right proced-< t (pcpu pid) (nil t t))
(pmem "%MEM" "%.1f" right proced-< t (pmem pid) (nil t t))
(args "ARGS" "%s" left proced-string-lessp nil (args pid) (nil t nil))
(args "ARGS" proced-format-args left proced-string-lessp nil (args pid) (nil t nil))
;;
;; attributes defined by proced (see `proced-process-attributes')
(pid "PID" "%d" right proced-< nil (pid) (t t nil))
@ -123,18 +126,18 @@ the external command (usually \"kill\")."
Each element has the form
(KEY NAME FORMAT JUSTIFY PREDICATE REVERSE SORT-SCHEME FILTER-SCHEME).
(KEY NAME FORMAT JUSTIFY PREDICATE REVERSE SORT-SCHEME REFINE-FLAGS).
KEY is the car of a process attribute.
NAME appears in the header line.
FORMAT specifies the format for displaying the attribute values.
It is either a string passed to `format' or a function called with one
argument, the value of the attribute.
It can be a string passed to `format'. It can be a function called
with one argument, the value of the attribute. Nil means take as is.
If JUSTIFY is an integer, its modulus gives the width of the attribute
vales formatted with FORMAT. If JUSTIFY is positive, NAME appears
values formatted with FORMAT. If JUSTIFY is positive, NAME appears
right-justified, otherwise it appears left-justified. If JUSTIFY is 'left
or 'right, the field width is calculated from all field values in the listing.
If JUSTIFY is 'left, the field values are formatted left-justified and
@ -149,16 +152,17 @@ that P1 is \"less than\" P2, or nil if not.
REVERSE is non-nil if the sort order is opposite to the order defined
by PREDICATE.
SORT-SCHEME is a list (KEY1 KEY2 ...) defing a hierarchy of rules
SORT-SCHEME is a list (KEY1 KEY2 ...) defining a hierarchy of rules
for sorting the process listing. KEY1, KEY2, ... are KEYs appearing as cars
of `proced-grammar-alist'. First the PREDICATE of KEY1 is evaluated.
If it yields non-equal, it defines the sorting order for the corresponding
If it yields non-equal, it defines the sort order for the corresponding
processes. If it evaluates to 'equal the PREDICATE of KEY2 is evaluated, etc.
FILTER-SCHEME is a list (LESS-B EQUAL-B LARGER-B) used by the command
`proced-filter-attribute' for filtering KEY (see there). This command
compares the value of attribute KEY of every process with the value
of attribute KEY of the process at the position of point using PREDICATE.
REFINE-FLAGS is a list (LESS-B EQUAL-B LARGER-B) used by the command
`proced-refine' (see there) to refine the listing based on attribute KEY.
This command compares the value of attribute KEY of every process with
the value of attribute KEY of the process at the position of point
using PREDICATE.
If PREDICATE yields non-nil, the process is accepted if LESS-B is non-nil.
If PREDICATE yields 'equal, the process is accepted if EQUAL-B is non-nil.
If PREDICATE yields nil, the process is accepted if LARGER-B is non-nil.")
@ -229,7 +233,7 @@ of `proced-filter-alist'.")
(make-variable-buffer-local 'proced-filter)
(defvar proced-sort 'pcpu
"Current sorting scheme for proced listing.
"Current sort scheme for proced listing.
It must be the KEY of an element of `proced-grammar-alist'.
It can also be a list of KEYs as in the SORT-SCHEMEs of the elements
of `proced-grammar-alist'.")
@ -247,7 +251,7 @@ of `proced-grammar-alist'.")
:type 'integer)
(defcustom proced-timer-flag nil
"Non-nil for regular update of a Proced buffer.
"Non-nil for auto update of a Proced buffer.
Can be changed interactively via `proced-toggle-timer-flag'."
:group 'proced
:type 'boolean)
@ -256,11 +260,13 @@ Can be changed interactively via `proced-toggle-timer-flag'."
;; Internal variables
(defvar proced-process-alist nil
"Alist of PIDs displayed by Proced.")
"Alist of processes displayed by Proced.
The car of each element is the PID, and the cdr is a list of
cons pairs, see `proced-process-attributes'.")
(make-variable-buffer-local 'proced-process-alist)
(defvar proced-sort-internal nil
"Sorting scheme for listing (internal format).")
"Sort scheme for listing (internal format).")
(defvar proced-marker-char ?* ; the answer is 42
"In proced, the current mark character.")
@ -285,6 +291,13 @@ Can be changed interactively via `proced-toggle-timer-flag'."
(defvar proced-marked-face 'proced-marked
"Face name used for marked processes.")
(defface proced-sort-header
'((t (:inherit font-lock-keyword-face)))
"Face used for header of attribute used for sorting."
:group 'proced-faces)
(defvar proced-sort-header-face 'proced-sort-header
"Face name used for header of attribute used for sorting.")
(defvar proced-re-mark "^[^ \n]"
"Regexp matching a marked line.
Important: the match ends just after the marker.")
@ -307,12 +320,12 @@ Important: the match ends just after the marker.")
"Help string for proced.")
(defconst proced-header-help-echo
"mouse-2: sort by attribute %s%s"
"mouse-1, mouse-2: sort by attribute %s%s (%s)"
"Help string shown when mouse is over a sortable header.")
(defconst proced-field-help-echo
"mouse-2, RET: filter by attribute %s %s"
"Help string shown when mouse is over a filterable field.")
"mouse-2, RET: refine by attribute %s %s"
"Help string shown when mouse is over a refinable field.")
(defvar proced-font-lock-keywords
(list
@ -347,8 +360,8 @@ Important: the match ends just after the marker.")
(define-key km "P" 'proced-mark-parents)
;; filtering
(define-key km "f" 'proced-filter-interactive)
(define-key km [mouse-2] 'proced-filter-attribute)
(define-key km "\C-m" 'proced-filter-attribute)
(define-key km [mouse-2] 'proced-refine)
(define-key km "\C-m" 'proced-refine)
;; sorting
(define-key km "sc" 'proced-sort-pcpu)
(define-key km "sm" 'proced-sort-pmem)
@ -357,6 +370,8 @@ Important: the match ends just after the marker.")
(define-key km "sS" 'proced-sort-interactive)
(define-key km "st" 'proced-sort-time)
(define-key km "su" 'proced-sort-user)
;; similar to `Buffer-menu-sort-by-column'
(define-key km [header-line mouse-1] 'proced-sort-header)
(define-key km [header-line mouse-2] 'proced-sort-header)
;; formatting
(define-key km "F" 'proced-format-interactive)
@ -402,7 +417,7 @@ Important: the match ends just after the marker.")
:selected (eq proced-filter ',filter)]))
proced-filter-alist))
("Sorting"
:help "Select Sorting Scheme"
:help "Select Sort Scheme"
["Sort..." proced-sort-interactive
:help "Sort Process List"]
"--"
@ -427,10 +442,10 @@ Important: the match ends just after the marker.")
"--"
["Revert" revert-buffer
:help "Revert Process Listing"]
["Regular Update" proced-toggle-timer-flag
["Auto Update" proced-toggle-timer-flag
:style radio
:selected (eval proced-timer-flag)
:help "Regular Update of Proced buffer"]
:help "Auto Update of Proced Buffer"]
["Send signal" proced-send-signal
:help "Send Signal to Marked Processes"]))
@ -453,12 +468,13 @@ Important: the match ends just after the marker.")
;; to get a well-defined position of point.
(defun proced-move-to-goal-column ()
"Move to `goal-column' if non-nil."
"Move to `goal-column' if non-nil. Return position of point."
(beginning-of-line)
(unless (eobp)
(if goal-column
(forward-char goal-column)
(forward-char 2))))
(forward-char 2)))
(point))
(defun proced-header-line ()
"Return header line for Proced buffer."
@ -481,6 +497,29 @@ Return nil if point is not on a process line."
Type \\<proced-mode-map>\\[proced-mark] to mark a process for later commands.
Type \\[proced-send-signal] to send signals to marked processes.
The initial content of a listing is defined by the variable `proced-filter'
and the variable `proced-format'.
The variable `proced-filter' specifies which system processes are displayed.
The variable `proced-format' specifies which attributes are displayed for
each process. Type \\[proced-filter-interactive] and \\[proced-format-interactive]
to change the values of `proced-filter' and `proced-format'.
The current value of the variable `proced-filter' is indicated in the
mode line.
The sort order of Proced listings is defined by the variable `proced-sort'.
Type \\[proced-sort-interactive] or click on a header in the header line
to change the sort scheme. The current sort scheme is indicated in the
mode line, using \"+\" or \"-\" for ascending or descending sort order.
An existing Proced listing can be refined by typing \\[proced-refine]
with point on the attribute of a process. If point is on the attribute ATTR,
this compares the value of ATTR of every process with the value of ATTR
of the process at the position of point. See `proced-refine' for details.
Refining an existing listing does not update the variable `proced-filter'.
The attribute-specific rules for formatting, filtering, sorting, and refining
are defined in `proced-grammar-alist'.
\\{proced-mode-map}"
(abbrev-mode 0)
(auto-fill-mode 0)
@ -500,14 +539,11 @@ Type \\[proced-send-signal] to send signals to marked processes.
;;;###autoload
(defun proced (&optional arg)
"Mode for displaying UNIX system processes and sending signals to them.
Type \\<proced-mode-map>\\[proced-mark] to mark a process for later commands.
Type \\[proced-send-signal] to send signals to marked processes.
"Generate a listing of UNIX system processes.
If invoked with optional ARG the window displaying the process
information will be displayed but not selected.
\\{proced-mode-map}"
See `proced-mode' for a descreption of features available in Proced buffers."
(interactive "P")
(let ((buffer (get-buffer-create "*Proced*")) new)
(set-buffer buffer)
@ -523,7 +559,7 @@ information will be displayed but not selected.
"Type \\<proced-mode-map>\\[quit-window] to quit, \\[proced-help] for help")))))
(defun proced-timer ()
"Update Proced buffers regularly using `run-at-time'."
"Auto-update Proced buffers using `run-at-time'."
(dolist (buf (buffer-list))
(with-current-buffer buf
(if (and (eq major-mode 'proced-mode)
@ -531,8 +567,8 @@ information will be displayed but not selected.
(proced-update t t)))))
(defun proced-toggle-timer-flag (arg)
"Change whether this Proced buffer is updated regularly.
With prefix ARG, update this buffer regularly if ARG is positive,
"Change whether this Proced buffer is updated automatically.
With prefix ARG, update this buffer automatically if ARG is positive,
otherwise do not update. Sets the variable `proced-timer-flag'.
The time interval for updates is specified via `proced-timer-interval'."
(interactive (list (or current-prefix-arg 'toggle)))
@ -715,7 +751,8 @@ Update `proced-process-alist' accordingly."
;;; Filtering
(defun proced-filter (process-alist filter-list)
"Apply FILTER-LIST to PROCESS-ALIST."
"Apply FILTER-LIST to PROCESS-ALIST.
Return the filtered process list."
(if (symbolp filter-list)
(setq filter-list (cdr (assq filter-list proced-filter-alist))))
(dolist (filter filter-list)
@ -741,17 +778,16 @@ Update `proced-process-alist' accordingly."
(setq process-alist new-alist)))
process-alist)
(defun proced-filter-interactive (scheme &optional revert)
(defun proced-filter-interactive (scheme)
"Filter Proced buffer using SCHEME.
When called interactively, an empty string means nil, i.e., no filtering.
With prefix REVERT non-nil revert listing."
Set variable `proced-filter' to SCHEME. Revert listing."
(interactive
(let ((scheme (completing-read "Filter: "
proced-filter-alist nil t)))
(list (if (string= "" scheme) nil (intern scheme))
current-prefix-arg)))
(list (if (string= "" scheme) nil (intern scheme)))))
(setq proced-filter scheme)
(proced-update revert))
(proced-update t))
(defun proced-process-tree (process-alist)
"Return process tree for PROCESS-ALIST.
@ -796,9 +832,34 @@ This list includes CPID unless OMIT-CPID is non-nil."
(push (assq pid process-alist) parent-list))
parent-list))
(defun proced-filter-attribute (&optional event)
"Filter Proced listing based on the attribute at point.
Optional EVENT is the location of the Proced field."
;; Refining
;; Filters are used to select the processes in a new listing.
;; Refiners are used to narrow down further (interactively) the processes
;; in an existing listing.
(defun proced-refine (&optional event)
"Refine Proced listing by comparing with the attribute value at point.
Optional EVENT is the location of the Proced field.
If point is on the attribute ATTR, this command compares the value of ATTR
of every process with the value of ATTR of the process at the position
of point. One can select processes for which the value of ATTR is
\"less than\", \"equal\", and / or \"larger\" than ATTR of the process
point is on.
The predicate for the comparison of two ATTR values is defined
in `proced-grammar-alist'. For each return value of the predicate
a refine flag is defined in `proced-grammar-alist'. A process is included
in the new listing if the refine flag for the return value of the predicate
is non-nil.
The help-echo string for `proced-refine' uses \"+\" or \"-\" to indicate
the current values of the refine flags.
This command refines an already existing process listing based initially
on the variable `proced-filter'. It does not change this variable.
It does not revert the listing. If you frequently need a certain refinement,
consider defining a new filter in `proced-filter-alist'."
(interactive (list last-input-event))
(if event (posn-set-point (event-end event)))
(let ((key (get-text-property (point) 'proced-key))
@ -806,24 +867,25 @@ Optional EVENT is the location of the Proced field."
(if (and key pid)
(let* ((grammar (assq key proced-grammar-alist))
(predicate (nth 4 grammar))
(filter (nth 7 grammar))
(refiner (nth 7 grammar))
(ref (cdr (assq key (cdr (assq pid proced-process-alist)))))
val new-alist)
(when ref
(dolist (process proced-process-alist)
(setq val (funcall predicate (cdr (assq key (cdr process))) ref))
(if (cond ((not val) (nth 2 filter))
((eq val 'equal) (nth 1 filter))
(val (car filter)))
(if (cond ((not val) (nth 2 refiner))
((eq val 'equal) (nth 1 refiner))
(val (car refiner)))
(push process new-alist)))
(setq proced-process-alist new-alist)
;; Do not revert listing.
(proced-update)))
(message "No filter defined here."))))
(message "No refiner defined here."))))
;; Proced predicates for sorting and filtering are based on a three-valued
;; logic:
;; Predicates takes two arguments P1 and P2, the corresponding attribute
;; values of two processes. Predicate should return 'equal if P1 has
;; Predicates take two arguments P1 and P2, the corresponding attribute
;; values of two processes. Predicates should return 'equal if P1 has
;; same rank like P2. Any other non-nil value says that P1 is "less than" P2,
;; or nil if not.
@ -887,7 +949,7 @@ Return `equal' if T1 equals T2. Return nil otherwise."
(defun proced-sort (process-alist sorter)
"Sort PROCESS-ALIST using scheme SORTER.
Return sorted process list."
Return the sorted process list."
;; translate SORTER into a list of lists (KEY PREDICATE REVERSE)
(setq proced-sort-internal
(mapcar (lambda (arg)
@ -905,9 +967,12 @@ Return sorted process list."
(defun proced-sort-interactive (scheme &optional revert)
"Sort Proced buffer using SCHEME.
When called interactively, an empty string means nil, i.e., no sorting.
With prefix REVERT non-nil revert listing."
With prefix REVERT non-nil revert listing.
Set variable `proced-sort' to SCHEME. The current sort scheme is displayed
in the mode line, using \"+\" or \"-\" for ascending or descending order."
(interactive
(let ((scheme (completing-read "Sorting type: "
(let ((scheme (completing-read "Sort attribute: "
proced-grammar-alist nil t)))
(list (if (string= "" scheme) nil (intern scheme))
current-prefix-arg)))
@ -947,7 +1012,8 @@ With prefix REVERT non-nil revert listing."
(defun proced-sort-header (event &optional revert)
"Sort Proced listing based on an attribute.
EVENT is a mouse event with starting position in the header line.
It is converted in the corresponding attribute key."
It is converted in the corresponding attribute key.
This updates the variable `proced-sort'."
(interactive "e\nP")
(let ((start (event-start event))
col key)
@ -995,11 +1061,15 @@ The return string is always 6 characters wide."
(format-time-string "%b %e" start)))))
(defun proced-format-ttname (ttname)
"Format attribute TTNAME, omitting prefix \"/dev/\"."
"Format attribute TTNAME, omitting path \"/dev/\"."
;; Does this work for all systems?
(format "%s" (substring ttname
(if (string-match "\\`/dev/" ttname)
(match-end 0) 0))))
(substring ttname (if (string-match "\\`/dev/" ttname)
(match-end 0) 0)))
(defun proced-format-args (args)
"Format attribute ARGS.
Replace newline characters by \"^J\" (two characters)."
(replace-regexp-in-string "\n" "^J" args))
(defun proced-format (process-alist format)
"Display PROCESS-ALIST using FORMAT."
@ -1012,9 +1082,10 @@ The return string is always 6 characters wide."
(if (symbolp grammar)
(setq grammar (assq grammar proced-grammar-alist)))
(let* ((key (car grammar))
(fun (if (stringp (nth 2 grammar))
`(lambda (arg) (format ,(nth 2 grammar) arg))
(nth 2 grammar)))
(fun (cond ((stringp (nth 2 grammar))
`(lambda (arg) (format ,(nth 2 grammar) arg)))
((not (nth 2 grammar)) 'identity)
( t (nth 2 grammar))))
(whitespace (if format whitespace ""))
;; Text properties:
;; We use the text property `proced-key' to store in each
@ -1024,7 +1095,8 @@ The return string is always 6 characters wide."
(hprops `(proced-key ,key mouse-face highlight
help-echo ,(format proced-header-help-echo
(if (nth 5 grammar) "-" "+")
(nth 1 grammar))))
(nth 1 grammar)
(if (nth 5 grammar) "descending" "ascending"))))
(fprops `(proced-key ,key mouse-face highlight
help-echo ,(format proced-field-help-echo
(nth 1 grammar)
@ -1033,6 +1105,9 @@ The return string is always 6 characters wide."
(nth 7 grammar) ""))))
value)
;; highlight the header of the sort column
(if (eq key proced-sort)
(setq hprops (append `(face ,proced-sort-header-face) hprops)))
(goto-char (point-min))
(cond ( ;; fixed width of output field
(numberp (nth 3 grammar))
@ -1097,6 +1172,7 @@ The return string is always 6 characters wide."
(defun proced-format-interactive (scheme &optional revert)
"Format Proced buffer using SCHEME.
When called interactively, an empty string means nil, i.e., no formatting.
Set variable `proced-format' to SCHEME.
With prefix REVERT non-nil revert listing."
(interactive
(let ((scheme (completing-read "Format: "
@ -1138,10 +1214,25 @@ Suppress status information if QUIET is nil."
(setq revert (or revert (not proced-process-alist)))
(or quiet (message (if revert "Updating process information..."
"Updating process display...")))
;; If point is on a field, we try to return point to that field.
;; Otherwise we try to return to the same column
(let ((old-pos (let ((key (get-text-property (point) 'proced-key)))
(list (proced-pid-at-point) key
(if revert ;; evaluate all processes
(setq proced-process-alist (proced-process-attributes)))
;; filtering and sorting
(setq proced-process-alist
(proced-sort (proced-filter proced-process-alist
proced-filter) proced-sort))
;; It is useless to keep undo information if we revert, filter, or
;; refine the listing so that `proced-process-alist' has changed.
;; We could keep the undo information if we only re-sort the buffer.
;; Would that be useful? Re-re-sorting is easy, too.
(if (consp buffer-undo-list)
(setq buffer-undo-list nil))
(let ((buffer-undo-list t)
;; If point is on a field, we try to return point to that field.
;; Otherwise we try to return to the same column
(old-pos (let ((pid (proced-pid-at-point))
(key (get-text-property (point) 'proced-key)))
(list pid key ; can both be nil
(if key
(if (get-text-property (1- (point)) 'proced-key)
(- (point) (previous-single-property-change
@ -1154,16 +1245,7 @@ Suppress status information if QUIET is nil."
(while (re-search-forward "^\\(\\S-\\)" nil t)
(push (cons (save-match-data (proced-pid-at-point))
(match-string-no-properties 1)) mp-list))
(when revert
;; all attributes of all processes
(setq proced-process-alist (proced-process-attributes))
;; do not keep undo information
(if (consp buffer-undo-list)
(setq buffer-undo-list nil)))
;; filtering and sorting
(setq proced-process-alist
(proced-sort (proced-filter proced-process-alist
proced-filter) proced-sort))
;; generate listing
(erase-buffer)
(proced-format proced-process-alist proced-format)
@ -1173,6 +1255,7 @@ Suppress status information if QUIET is nil."
(forward-line))
(setq proced-header-line (concat " " proced-header-line))
(if revert (set-buffer-modified-p nil))
;; set `goal-column'
(let ((grammar (assq proced-goal-attribute proced-grammar-alist)))
(setq goal-column ;; set to nil if no match
@ -1183,10 +1266,13 @@ Suppress status information if QUIET is nil."
(if (nth 3 grammar)
(match-beginning 0)
(match-end 0)))))
;; restore process marks and buffer position (if possible)
;; FIXME: sometimes this puts point in the middle of the proced buffer
;; where it is not interesting. Is there a better / more flexible solution?
(goto-char (point-min))
(if (or mp-list old-pos)
(let (pid mark new-pos)
(let (pid mark new-pos)
(if (or mp-list (car old-pos))
(while (not (eobp))
(setq pid (proced-pid-at-point))
(when (setq mark (assq pid mp-list))
@ -1206,18 +1292,21 @@ Suppress status information if QUIET is nil."
(point))))
(setq new-pos (point))))
(unless new-pos
(setq new-pos (if goal-column
(+ (line-beginning-position) goal-column)
(line-beginning-position)))))
;; we found the process, but the field of point
;; is not listed anymore
(setq new-pos (proced-move-to-goal-column))))
(setq new-pos (min (+ (line-beginning-position) (nth 2 old-pos))
(line-end-position)))))
(forward-line))
(if new-pos
(goto-char new-pos)
(proced-move-to-goal-column)))
(proced-move-to-goal-column))
(forward-line)))
(if new-pos
(goto-char new-pos)
(goto-char (point-min))
(proced-move-to-goal-column)))
;; update modeline
;; Does the long mode-name clutter the modeline?
;; Does the long `mode-name' clutter the modeline? It would be nice
;; to have some other location for displaying the values of the various
;; flags that affect the behavior of proced (flags one might want
;; to change on the fly). Where??
(setq mode-name
(concat "Proced"
(if proced-filter