comparison lisp/proced.el @ 100735:8ec0632b600c

(proced-grammar-alist): Allow predicate nil. New attribute tree. (proced-format-alist): Use attribute tree. (proced-tree-flag, proced-tree-indent): New variables. (proced-children-alist): Renamed from proced-process-tree. PPID must refer to a process in process-alist. Ignore PPIDs that equal PID. Children alist inherits sorting order from process-alist. (proced-process-tree): New variable. New function. (proced-process-tree-internal, proced-toggle-tree) (proced-tree, proced-tree-insert, proced-format-tree): New functions. (proced-mark-process-alist): Add docstring. (proced-filter-parents): PPID must refer to a process in process-alist. Ignore PPIDs that equal PID. (proced-sort): Throw error if attribute is not sortable. (proced-sort-interactive): Restrict completion to sortable attributes. (proced-format): Include tree in standard attributes if proced-tree-flag is non-nil. Make header clickable only if corresponding predicate is non-nil. (proced-update): Use proced-tree.
author Roland Winkler <Roland.Winkler@physik.uni-erlangen.de>
date Sun, 28 Dec 2008 13:54:41 +0000
parents 496de5bd1f6d
children 9fcd5ffe18c5
comparison
equal deleted inserted replaced
100734:72f33d657eb7 100735:8ec0632b600c
135 ((lambda (ppid) (proced-filter-children proced-process-alist ppid)) . 135 ((lambda (ppid) (proced-filter-children proced-process-alist ppid)) .
136 "refine to process children")) 136 "refine to process children"))
137 ;; time: sum of utime and stime 137 ;; time: sum of utime and stime
138 (time "TIME" proced-format-time right proced-time-lessp t (time pid) (nil t t)) 138 (time "TIME" proced-format-time right proced-time-lessp t (time pid) (nil t t))
139 ;; ctime: sum of cutime and cstime 139 ;; ctime: sum of cutime and cstime
140 (ctime "CTIME" proced-format-time right proced-time-lessp t (ctime pid) (nil t t))) 140 (ctime "CTIME" proced-format-time right proced-time-lessp t (ctime pid) (nil t t))
141 ;; process tree
142 (tree "TREE" proced-format-tree left nil nil nil nil))
141 "Alist of rules for handling Proced attributes. 143 "Alist of rules for handling Proced attributes.
142 144
143 Each element has the form 145 Each element has the form
144 146
145 (KEY NAME FORMAT JUSTIFY PREDICATE REVERSE SORT-SCHEME REFINER). 147 (KEY NAME FORMAT JUSTIFY PREDICATE REVERSE SORT-SCHEME REFINER).
162 PREDICATE is the predicate for sorting and filtering the process listing 164 PREDICATE is the predicate for sorting and filtering the process listing
163 based on attribute KEY. PREDICATE takes two arguments P1 and P2, 165 based on attribute KEY. PREDICATE takes two arguments P1 and P2,
164 the corresponding attribute values of two processes. PREDICATE should 166 the corresponding attribute values of two processes. PREDICATE should
165 return 'equal if P1 has same rank like P2. Any other non-nil value says 167 return 'equal if P1 has same rank like P2. Any other non-nil value says
166 that P1 is \"less than\" P2, or nil if not. 168 that P1 is \"less than\" P2, or nil if not.
169 If PREDICATE is nil the attribute cannot be sorted.
167 170
168 PREDICATE defines an ascending sort order. REVERSE is non-nil if the sort 171 PREDICATE defines an ascending sort order. REVERSE is non-nil if the sort
169 order is descending. 172 order is descending.
170 173
171 SORT-SCHEME is a list (KEY1 KEY2 ...) defining a hierarchy of rules 174 SORT-SCHEME is a list (KEY1 KEY2 ...) defining a hierarchy of rules
199 (function :tag "Formatting Function")) 202 (function :tag "Formatting Function"))
200 (choice :tag "Justification" 203 (choice :tag "Justification"
201 (const :tag "left" left) 204 (const :tag "left" left)
202 (const :tag "right" right) 205 (const :tag "right" right)
203 (integer :tag "width")) 206 (integer :tag "width"))
204 (function :tag "Predicate") 207 (choice :tag "Predicate"
208 (const :tag "None" nil)
209 (function :tag "Function"))
205 (boolean :tag "Descending Sort Order") 210 (boolean :tag "Descending Sort Order")
206 (repeat :tag "Sort Scheme" (symbol :tag "Key")) 211 (repeat :tag "Sort Scheme" (symbol :tag "Key"))
207 (choice :tag "Refiner" 212 (choice :tag "Refiner"
213 (const :tag "None" nil)
208 (list :tag "Refine Flags" 214 (list :tag "Refine Flags"
209 (boolean :tag "Less") 215 (boolean :tag "Less")
210 (boolean :tag "Equal") 216 (boolean :tag "Equal")
211 (boolean :tag "Larger")) 217 (boolean :tag "Larger"))
212 (cons (function :tag "Refinement Function") 218 (cons (function :tag "Refinement Function")
213 (string :tag "Help echo")) 219 (string :tag "Help echo"))))))
214 (const :tag "None" nil)))))
215 220
216 (defcustom proced-custom-attributes nil 221 (defcustom proced-custom-attributes nil
217 "List of functions defining custom attributes. 222 "List of functions defining custom attributes.
218 This variable extends the functionality of `proced-process-attributes'. 223 This variable extends the functionality of `proced-process-attributes'.
219 Each function is called with one argument, the list of attributes 224 Each function is called with one argument, the list of attributes
230 ;; sorting can use them consistently. (Are there exceptions to this rule? 235 ;; sorting can use them consistently. (Are there exceptions to this rule?
231 ;; Would it be advantageous to have yet more general methods available?) 236 ;; Would it be advantageous to have yet more general methods available?)
232 ;; Sorting can also be based on attributes that are invisible in the listing. 237 ;; Sorting can also be based on attributes that are invisible in the listing.
233 238
234 (defcustom proced-format-alist 239 (defcustom proced-format-alist
235 '((short user pid pcpu pmem start time (args comm)) 240 '((short user pid tree pcpu pmem start time (args comm))
236 (medium user pid pcpu pmem vsize rss ttname state start time (args comm)) 241 (medium user pid tree pcpu pmem vsize rss ttname state start time (args comm))
237 (long user euid group pid pri nice pcpu pmem vsize rss ttname state 242 (long user euid group pid tree pri nice pcpu pmem vsize rss ttname state
238 start time (args comm)) 243 start time (args comm))
239 (verbose user euid group egid pid ppid pgrp sess pri nice pcpu pmem 244 (verbose user euid group egid pid ppid tree pgrp sess pri nice pcpu pmem
240 state thcount vsize rss ttname tpgid minflt majflt cminflt cmajflt 245 state thcount vsize rss ttname tpgid minflt majflt cminflt cmajflt
241 start time utime stime ctime cutime cstime etime (args comm))) 246 start time utime stime ctime cutime cstime etime (args comm)))
242 "Alist of formats of listing. 247 "Alist of formats of listing.
243 The car of each element is a symbol, the name of the format. 248 The car of each element is a symbol, the name of the format.
244 The cdr is a list of attribute keys appearing in `proced-grammar-alist'. 249 The cdr is a list of attribute keys appearing in `proced-grammar-alist'.
341 Can be changed interactively via `proced-toggle-auto-update'." 346 Can be changed interactively via `proced-toggle-auto-update'."
342 :group 'proced 347 :group 'proced
343 :type 'boolean) 348 :type 'boolean)
344 (make-variable-buffer-local 'proced-auto-update-flag) 349 (make-variable-buffer-local 'proced-auto-update-flag)
345 350
351 (defcustom proced-tree-flag nil
352 "Non-nil for display of Proced-buffer as process tree."
353 :group 'proced
354 :type 'boolean)
355 (make-variable-buffer-local 'proced-tree-flag)
356
346 ;; Internal variables 357 ;; Internal variables
347 358
348 (defvar proced-available (not (null (list-system-processes))) 359 (defvar proced-available (not (null (list-system-processes)))
349 "Non-nil means Proced is known to work on this system.") 360 "Non-nil means Proced is known to work on this system.")
350 361
389 400
390 (defvar proced-header-line nil 401 (defvar proced-header-line nil
391 "Headers in Proced buffer as a string.") 402 "Headers in Proced buffer as a string.")
392 (make-variable-buffer-local 'proced-header-line) 403 (make-variable-buffer-local 'proced-header-line)
393 404
405 (defvar proced-children-alist nil
406 "Children alist of process listing (internal variable).")
407
394 (defvar proced-process-tree nil 408 (defvar proced-process-tree nil
395 "Process tree of listing (internal variable).") 409 "Proced process tree (internal variable).")
410
411 (defvar proced-tree-indent nil
412 "Internal variable for indentation of Proced process tree.")
396 413
397 (defvar proced-auto-update-timer nil 414 (defvar proced-auto-update-timer nil
398 "Stores if Proced auto update timer is already installed.") 415 "Stores if Proced auto update timer is already installed.")
399 416
400 (defvar proced-log-buffer "*Proced log*" 417 (defvar proced-log-buffer "*Proced log*"
454 (define-key km "st" 'proced-sort-time) 471 (define-key km "st" 'proced-sort-time)
455 (define-key km "su" 'proced-sort-user) 472 (define-key km "su" 'proced-sort-user)
456 ;; similar to `Buffer-menu-sort-by-column' 473 ;; similar to `Buffer-menu-sort-by-column'
457 (define-key km [header-line mouse-1] 'proced-sort-header) 474 (define-key km [header-line mouse-1] 'proced-sort-header)
458 (define-key km [header-line mouse-2] 'proced-sort-header) 475 (define-key km [header-line mouse-2] 'proced-sort-header)
476 (define-key km "T" 'proced-toggle-tree)
459 ;; formatting 477 ;; formatting
460 (define-key km "F" 'proced-format-interactive) 478 (define-key km "F" 'proced-format-interactive)
461 ;; operate 479 ;; operate
462 (define-key km "o" 'proced-omit-processes) 480 (define-key km "o" 'proced-omit-processes)
463 (define-key km "x" 'proced-send-signal) ; Dired compatibility 481 (define-key km "x" 'proced-send-signal) ; Dired compatibility
517 `[,(symbol-name format) 535 `[,(symbol-name format)
518 (proced-format-interactive ',format) 536 (proced-format-interactive ',format)
519 :style radio 537 :style radio
520 :selected (eq proced-format ',format)])) 538 :selected (eq proced-format ',format)]))
521 proced-format-alist)) 539 proced-format-alist))
540 ["Tree Display" proced-toggle-tree
541 :style toggle
542 :selected (eval proced-tree-flag)
543 :help "Display Proced Buffer as Process Tree"]
522 "--" 544 "--"
523 ["Omit Marked Processes" proced-omit-processes 545 ["Omit Marked Processes" proced-omit-processes
524 :help "Omit Marked Processes in Process Listing."] 546 :help "Omit Marked Processes in Process Listing."]
525 "--" 547 "--"
526 ["Revert" revert-buffer 548 ["Revert" revert-buffer
592 614
593 The sort order of Proced listings is defined by the variable `proced-sort'. 615 The sort order of Proced listings is defined by the variable `proced-sort'.
594 Type \\[proced-sort-interactive] or click on a header in the header line 616 Type \\[proced-sort-interactive] or click on a header in the header line
595 to change the sort scheme. The current sort scheme is indicated in the 617 to change the sort scheme. The current sort scheme is indicated in the
596 mode line, using \"+\" or \"-\" for ascending or descending sort order. 618 mode line, using \"+\" or \"-\" for ascending or descending sort order.
619
620 Type \\[proced-toggle-tree] to toggle whether the listing is
621 displayed as process tree.
597 622
598 An existing Proced listing can be refined by typing \\[proced-refine]. 623 An existing Proced listing can be refined by typing \\[proced-refine].
599 Refining an existing listing does not update the variable `proced-filter'. 624 Refining an existing listing does not update the variable `proced-filter'.
600 625
601 The attribute-specific rules for formatting, filtering, sorting, and refining 626 The attribute-specific rules for formatting, filtering, sorting, and refining
766 (interactive (list (proced-pid-at-point) current-prefix-arg)) 791 (interactive (list (proced-pid-at-point) current-prefix-arg))
767 (proced-mark-process-alist 792 (proced-mark-process-alist
768 (proced-filter-parents proced-process-alist cpid omit-cpid))) 793 (proced-filter-parents proced-process-alist cpid omit-cpid)))
769 794
770 (defun proced-mark-process-alist (process-alist &optional quiet) 795 (defun proced-mark-process-alist (process-alist &optional quiet)
796 "Mark processes in PROCESS-ALIST.
797 If QUIET is non-nil suppress status message."
771 (let ((count 0)) 798 (let ((count 0))
772 (if process-alist 799 (if process-alist
773 (let (buffer-read-only) 800 (let (buffer-read-only)
774 (save-excursion 801 (save-excursion
775 (goto-char (point-min)) 802 (goto-char (point-min))
874 ;; only update if necessary 901 ;; only update if necessary
875 (unless (eq proced-filter scheme) 902 (unless (eq proced-filter scheme)
876 (setq proced-filter scheme) 903 (setq proced-filter scheme)
877 (proced-update t))) 904 (proced-update t)))
878 905
906 (defun proced-children-alist (process-alist)
907 "Return children alist for PROCESS-ALIST.
908 The children alist has elements (PPID PID1 PID2 ...).
909 PPID is a parent PID. PID1, PID2, ... are the child processes of PPID.
910 The children alist inherits the sorting order from PROCESS-ALIST.
911 The list of children does not include grandchildren."
912 ;; The PPIDs inherit the sorting order of PROCESS-ALIST.
913 (let ((process-tree (mapcar (lambda (a) (list (car a))) process-alist))
914 ppid)
915 (dolist (process process-alist)
916 (setq ppid (cdr (assq 'ppid (cdr process))))
917 (if (and ppid
918 ;; Ignore a PPID that equals PID.
919 (/= ppid (car process))
920 ;; Accept only PPIDs that correspond to members in PROCESS-ALIST.
921 (assq ppid process-alist))
922 (let ((temp-alist process-tree) elt)
923 (while (setq elt (pop temp-alist))
924 (when (eq ppid (car elt))
925 (setq temp-alist nil)
926 (setcdr elt (cons (car process) (cdr elt))))))))
927 ;; The child processes inherit the sorting order of PROCESS-ALIST.
928 (setq process-tree
929 (mapcar (lambda (a) (cons (car a) (nreverse (cdr a))))
930 process-tree))))
931
879 (defun proced-process-tree (process-alist) 932 (defun proced-process-tree (process-alist)
880 "Return process tree for PROCESS-ALIST. 933 "Return process tree for PROCESS-ALIST."
881 The process tree is an alist with elements (PPID PID1 PID2 ...). 934 (let ((proced-children-alist (proced-children-alist process-alist))
882 PPID is a parent PID. PID1, PID2, ... are the child processes of PPID. 935 pid-alist proced-process-tree)
883 The list of children does not include grandchildren." 936 (while (setq pid-alist (pop proced-children-alist))
884 (let (children-list ppid cpids) 937 (push (proced-process-tree-internal pid-alist) proced-process-tree))
885 (dolist (process process-alist children-list) 938 (nreverse proced-process-tree)))
886 (setq ppid (cdr (assq 'ppid (cdr process)))) 939
887 (if ppid 940 (defun proced-process-tree-internal (pid-alist)
888 (setq children-list 941 "Helper function for `proced-process-tree'."
889 (if (setq cpids (assq ppid children-list)) 942 (let ((cpid-list (cdr pid-alist)) cpid-alist cpid)
890 (cons (cons ppid (cons (car process) (cdr cpids))) 943 (while (setq cpid (car cpid-list))
891 (assq-delete-all ppid children-list)) 944 (if (setq cpid-alist (assq cpid proced-children-alist))
892 (cons (list ppid (car process)) 945 ;; Unprocessed part of process tree that needs to be
893 children-list))))))) 946 ;; analyzed recursively.
947 (progn
948 (setq proced-children-alist
949 (assq-delete-all cpid proced-children-alist))
950 (setcar cpid-list (proced-process-tree-internal cpid-alist)))
951 ;; We already processed this subtree and take it "as is".
952 (setcar cpid-list (assq cpid proced-process-tree))
953 (setq proced-process-tree
954 (assq-delete-all cpid proced-process-tree)))
955 (pop cpid-list)))
956 pid-alist)
957
958 (defun proced-toggle-tree (arg)
959 "Change whether this Proced buffer is displayed as process tree.
960 With prefix ARG, display as process tree if ARG is positive, otherwise
961 do not display as process tree. Sets the variable `proced-tree-flag'."
962 (interactive (list (or current-prefix-arg 'toggle)))
963 (setq proced-tree-flag
964 (cond ((eq arg 'toggle) (not proced-tree-flag))
965 (arg (> (prefix-numeric-value arg) 0))
966 (t (not proced-tree-flag))))
967 (proced-update)
968 (message "Proced process tree display %s"
969 (if proced-tree-flag "enabled" "disabled")))
970
971 (defun proced-tree (process-alist)
972 "Display Proced buffer as process tree if `proced-tree-flag' is non-nil.
973 If `proced-tree-flag' is non-nil, convert PROCESS-ALIST into a linear
974 process tree with a time attribute. Otherwise, remove the tree attribute."
975 (if proced-tree-flag
976 ;; add tree attribute
977 (let ((process-tree (proced-process-tree process-alist))
978 (proced-tree-indent 0)
979 proced-process-tree pt)
980 (while (setq pt (pop process-tree))
981 (proced-tree-insert pt))
982 (nreverse proced-process-tree))
983 (let (new-alist)
984 ;; remove tree attribute
985 (dolist (process process-alist)
986 (push (assq-delete-all 'tree process) new-alist))
987 (nreverse new-alist))))
988
989 (defun proced-tree-insert (process-tree)
990 "Helper function for `proced-tree'."
991 (let ((pprocess (assq (car process-tree) proced-process-alist)))
992 (push (append (list (car pprocess))
993 (list (cons 'tree proced-tree-indent))
994 (cdr pprocess))
995 proced-process-tree)
996 (if (cdr process-tree)
997 (let ((proced-tree-indent (1+ proced-tree-indent)))
998 (mapc 'proced-tree-insert (cdr process-tree))))))
894 999
895 (defun proced-filter-children (process-alist ppid &optional omit-ppid) 1000 (defun proced-filter-children (process-alist ppid &optional omit-ppid)
896 "For PROCESS-ALIST return list of child processes of PPID. 1001 "For PROCESS-ALIST return list of child processes of PPID.
897 This list includes PPID unless OMIT-PPID is non-nil." 1002 This list includes PPID unless OMIT-PPID is non-nil."
898 (let ((proced-process-tree (proced-process-tree process-alist)) 1003 (let ((proced-children-alist (proced-children-alist process-alist))
899 new-alist) 1004 new-alist)
900 (dolist (pid (proced-children-pids ppid)) 1005 (dolist (pid (proced-children-pids ppid))
901 (push (assq pid process-alist) new-alist)) 1006 (push (assq pid process-alist) new-alist))
902 (if omit-ppid 1007 (if omit-ppid
903 (assq-delete-all ppid new-alist) 1008 (assq-delete-all ppid new-alist)
904 new-alist))) 1009 new-alist)))
905 1010
906 ;; helper function
907 (defun proced-children-pids (ppid) 1011 (defun proced-children-pids (ppid)
908 "Return list of children PIDs of PPID (including PPID)." 1012 "Return list of children PIDs of PPID (including PPID)."
909 (let ((cpids (cdr (assq ppid proced-process-tree)))) 1013 (let ((cpids (cdr (assq ppid proced-children-alist))))
910 (if cpids 1014 (if cpids
911 (cons ppid (apply 'append (mapcar 'proced-children-pids cpids))) 1015 (cons ppid (apply 'append (mapcar 'proced-children-pids cpids)))
912 (list ppid)))) 1016 (list ppid))))
913 1017
914 (defun proced-filter-parents (process-alist pid &optional omit-pid) 1018 (defun proced-filter-parents (process-alist pid &optional omit-pid)
915 "For PROCESS-ALIST return list of parent processes of PID. 1019 "For PROCESS-ALIST return list of parent processes of PID.
916 This list includes PID unless OMIT-PID is non-nil." 1020 This list includes PID unless OMIT-PID is non-nil."
917 (let ((parent-list (unless omit-pid (list (assq pid process-alist))))) 1021 (let ((parent-list (unless omit-pid (list (assq pid process-alist))))
918 (while (setq pid (cdr (assq 'ppid (cdr (assq pid process-alist))))) 1022 (process (assq pid process-alist))
919 (push (assq pid process-alist) parent-list)) 1023 ppid)
1024 (while (and (setq ppid (cdr (assq 'ppid (cdr process))))
1025 ;; Ignore a PPID that equals PID.
1026 (/= ppid pid)
1027 ;; Accept only PPIDs that correspond to members in PROCESS-ALIST.
1028 (setq process (assq ppid process-alist)))
1029 (setq pid ppid)
1030 (push process parent-list))
920 parent-list)) 1031 parent-list))
921 1032
922 ;; Refining 1033 ;; Refining
923 1034
924 ;; Filters are used to select the processes in a new listing. 1035 ;; Filters are used to select the processes in a new listing.
1053 Return the sorted process list." 1164 Return the sorted process list."
1054 ;; translate SORTER into a list of lists (KEY PREDICATE REVERSE) 1165 ;; translate SORTER into a list of lists (KEY PREDICATE REVERSE)
1055 (setq proced-sort-internal 1166 (setq proced-sort-internal
1056 (mapcar (lambda (arg) 1167 (mapcar (lambda (arg)
1057 (let ((grammar (assq arg proced-grammar-alist))) 1168 (let ((grammar (assq arg proced-grammar-alist)))
1169 (unless (nth 4 grammar)
1170 (error "Attribute %s not sortable" (car grammar)))
1058 (list arg (nth 4 grammar) (nth 5 grammar)))) 1171 (list arg (nth 4 grammar) (nth 5 grammar))))
1059 (cond ((listp sorter) sorter) 1172 (cond ((listp sorter) sorter)
1060 ((and (symbolp sorter) 1173 ((and (symbolp sorter)
1061 (nth 6 (assq sorter proced-grammar-alist)))) 1174 (nth 6 (assq sorter proced-grammar-alist))))
1062 ((symbolp sorter) (list sorter)) 1175 ((symbolp sorter) (list sorter))
1082 adopt the sorting order defined for SCHEME in `proced-grammar-alist'. 1195 adopt the sorting order defined for SCHEME in `proced-grammar-alist'.
1083 1196
1084 Set variable `proced-sort' to SCHEME. The current sort scheme is displayed 1197 Set variable `proced-sort' to SCHEME. The current sort scheme is displayed
1085 in the mode line, using \"+\" or \"-\" for ascending or descending order." 1198 in the mode line, using \"+\" or \"-\" for ascending or descending order."
1086 (interactive 1199 (interactive
1087 (let ((scheme (completing-read "Sort attribute: " 1200 (let* (choices
1088 proced-grammar-alist nil t))) 1201 (scheme (completing-read "Sort attribute: "
1202 (dolist (grammar proced-grammar-alist choices)
1203 (if (nth 4 grammar)
1204 (push (list (car grammar)) choices)))
1205 nil t)))
1089 (list (if (string= "" scheme) nil (intern scheme)) 1206 (list (if (string= "" scheme) nil (intern scheme))
1090 ;; like 'toggle in `define-derived-mode' 1207 ;; like 'toggle in `define-derived-mode'
1091 (or current-prefix-arg 'no-arg)))) 1208 (or current-prefix-arg 'no-arg))))
1092 1209
1093 (setq proced-descend 1210 (setq proced-descend
1198 "Format attribute TTNAME, omitting path \"/dev/\"." 1315 "Format attribute TTNAME, omitting path \"/dev/\"."
1199 ;; Does this work for all systems? 1316 ;; Does this work for all systems?
1200 (substring ttname (if (string-match "\\`/dev/" ttname) 1317 (substring ttname (if (string-match "\\`/dev/" ttname)
1201 (match-end 0) 0))) 1318 (match-end 0) 0)))
1202 1319
1320 (defun proced-format-tree (tree)
1321 "Format attribute TREE."
1322 (concat (make-string tree ?\s) (number-to-string tree)))
1323
1203 ;; Proced assumes that every process occupies only one line in the listing. 1324 ;; Proced assumes that every process occupies only one line in the listing.
1204 (defun proced-format-args (args) 1325 (defun proced-format-args (args)
1205 "Format attribute ARGS. 1326 "Format attribute ARGS.
1206 Replace newline characters by \"^J\" (two characters)." 1327 Replace newline characters by \"^J\" (two characters)."
1207 (replace-regexp-in-string "\n" "^J" args)) 1328 (replace-regexp-in-string "\n" "^J" args))
1217 ;; If none of the alternatives is non-nil, the attribute is ignored 1338 ;; If none of the alternatives is non-nil, the attribute is ignored
1218 ;; in the listing. 1339 ;; in the listing.
1219 (let ((standard-attributes 1340 (let ((standard-attributes
1220 (car (proced-process-attributes (list (emacs-pid))))) 1341 (car (proced-process-attributes (list (emacs-pid)))))
1221 new-format fmi) 1342 new-format fmi)
1343 (if proced-tree-flag (push (cons 'tree 0) standard-attributes))
1222 (dolist (fmt format) 1344 (dolist (fmt format)
1223 (if (symbolp fmt) 1345 (if (symbolp fmt)
1224 (if (assq fmt standard-attributes) 1346 (if (assq fmt standard-attributes)
1225 (push fmt new-format)) 1347 (push fmt new-format))
1226 (while (setq fmi (pop fmt)) 1348 (while (setq fmi (pop fmt))
1244 ;; Text properties: 1366 ;; Text properties:
1245 ;; We use the text property `proced-key' to store in each 1367 ;; We use the text property `proced-key' to store in each
1246 ;; field the corresponding key. 1368 ;; field the corresponding key.
1247 ;; Of course, the sort predicate appearing in help-echo 1369 ;; Of course, the sort predicate appearing in help-echo
1248 ;; is only part of the story. But it gives the main idea. 1370 ;; is only part of the story. But it gives the main idea.
1249 (hprops (let ((descend (if (eq key sort-key) proced-descend (nth 5 grammar)))) 1371 (hprops
1250 `(proced-key ,key mouse-face highlight 1372 (if (nth 4 grammar)
1251 help-echo ,(format proced-header-help-echo 1373 (let ((descend (if (eq key sort-key) proced-descend (nth 5 grammar))))
1252 (if descend "-" "+") 1374 `(proced-key ,key mouse-face highlight
1253 (nth 1 grammar) 1375 help-echo ,(format proced-header-help-echo
1254 (if descend "descending" "ascending"))))) 1376 (if descend "-" "+")
1377 (nth 1 grammar)
1378 (if descend "descending" "ascending"))))))
1255 (refiner (nth 7 grammar)) 1379 (refiner (nth 7 grammar))
1256 (fprops 1380 (fprops
1257 (cond ((functionp (car refiner)) 1381 (cond ((functionp (car refiner))
1258 `(proced-key ,key mouse-face highlight 1382 `(proced-key ,key mouse-face highlight
1259 help-echo ,(format "mouse-2, RET: %s" 1383 help-echo ,(format "mouse-2, RET: %s"
1392 (setq proced-process-alist (proced-process-attributes))) 1516 (setq proced-process-alist (proced-process-attributes)))
1393 ;; filtering and sorting 1517 ;; filtering and sorting
1394 (setq proced-process-alist 1518 (setq proced-process-alist
1395 (proced-sort (proced-filter proced-process-alist proced-filter) 1519 (proced-sort (proced-filter proced-process-alist proced-filter)
1396 proced-sort proced-descend)) 1520 proced-sort proced-descend))
1521
1522 ;; display as process tree?
1523 (setq proced-process-alist
1524 (proced-tree proced-process-alist))
1397 1525
1398 ;; It is useless to keep undo information if we revert, filter, or 1526 ;; It is useless to keep undo information if we revert, filter, or
1399 ;; refine the listing so that `proced-process-alist' has changed. 1527 ;; refine the listing so that `proced-process-alist' has changed.
1400 ;; We could keep the undo information if we only re-sort the buffer. 1528 ;; We could keep the undo information if we only re-sort the buffer.
1401 ;; Would that be useful? Re-re-sorting is easy, too. 1529 ;; Would that be useful? Re-re-sorting is easy, too.