Mercurial > emacs
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. |