diff options
| author | Roland Winkler | 2008-12-28 13:58:10 +0000 |
|---|---|---|
| committer | Roland Winkler | 2008-12-28 13:58:10 +0000 |
| commit | f1d2765346cbb70a6ad6e505a86df503573ab2ae (patch) | |
| tree | 5f63e3d992bfffa59dca41737c1d9a841ff1c73e | |
| parent | 39791e03e1c888f0f7efb029a58561987a8c1b51 (diff) | |
| download | emacs-f1d2765346cbb70a6ad6e505a86df503573ab2ae.tar.gz emacs-f1d2765346cbb70a6ad6e505a86df503573ab2ae.zip | |
(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.
| -rw-r--r-- | lisp/ChangeLog | 24 | ||||
| -rw-r--r-- | lisp/proced.el | 198 |
2 files changed, 187 insertions, 35 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 5e0526e1aa0..6db7705e538 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,27 @@ | |||
| 1 | 2008-12-28 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de> | ||
| 2 | |||
| 3 | * proced.el (proced-grammar-alist): Allow predicate nil. New | ||
| 4 | attribute tree. | ||
| 5 | (proced-format-alist): Use attribute tree. | ||
| 6 | (proced-tree-flag, proced-tree-indent): New variables. | ||
| 7 | (proced-children-alist): Renamed from proced-process-tree. PPID | ||
| 8 | must refer to a process in process-alist. Ignore PPIDs that equal | ||
| 9 | PID. Children alist inherits sorting order from process-alist. | ||
| 10 | (proced-process-tree): New variable. New function. | ||
| 11 | (proced-process-tree-internal, proced-toggle-tree) | ||
| 12 | (proced-tree, proced-tree-insert, proced-format-tree): New | ||
| 13 | functions. | ||
| 14 | (proced-mark-process-alist): Add docstring. | ||
| 15 | (proced-filter-parents): PPID must refer to a process in | ||
| 16 | process-alist. Ignore PPIDs that equal PID. | ||
| 17 | (proced-sort): Throw error if attribute is not sortable. | ||
| 18 | (proced-sort-interactive): Restrict completion to sortable | ||
| 19 | attributes. | ||
| 20 | (proced-format): Include tree in standard attributes if | ||
| 21 | proced-tree-flag is non-nil. Make header clickable only if | ||
| 22 | corresponding predicate is non-nil. | ||
| 23 | (proced-update): Use proced-tree. | ||
| 24 | |||
| 1 | 2008-12-28 Chong Yidong <cyd@stupidchicken.com> | 25 | 2008-12-28 Chong Yidong <cyd@stupidchicken.com> |
| 2 | 26 | ||
| 3 | * diff.el (diff): Doc fix. | 27 | * diff.el (diff): Doc fix. |
diff --git a/lisp/proced.el b/lisp/proced.el index 9590e921bf0..2004410a17b 100644 --- a/lisp/proced.el +++ b/lisp/proced.el | |||
| @@ -137,7 +137,9 @@ the external command (usually \"kill\")." | |||
| 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 |
| @@ -164,6 +166,7 @@ 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. |
| @@ -201,17 +204,19 @@ If REFINER is nil no refinement is done." | |||
| 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. |
| @@ -232,11 +237,11 @@ If the function returns nil, the value is ignored." | |||
| 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. |
| @@ -343,6 +348,12 @@ Can be changed interactively via `proced-toggle-auto-update'." | |||
| 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))) |
| @@ -391,8 +402,14 @@ Important: the match ends just after the marker.") | |||
| 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.") |
| @@ -456,6 +473,7 @@ Important: the match ends just after the marker.") | |||
| 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 |
| @@ -519,6 +537,10 @@ Important: the match ends just after the marker.") | |||
| 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."] |
| @@ -595,6 +617,9 @@ 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. |
| 597 | 619 | ||
| 620 | Type \\[proced-toggle-tree] to toggle whether the listing is | ||
| 621 | displayed as process tree. | ||
| 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 | ||
| @@ -768,6 +793,8 @@ Also mark CPID unless prefix OMIT-CPID is non-nil." | |||
| 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) |
| @@ -876,26 +903,104 @@ Set variable `proced-filter' to SCHEME. Revert listing." | |||
| 876 | (setq proced-filter scheme) | 903 | (setq proced-filter scheme) |
| 877 | (proced-update t))) | 904 | (proced-update t))) |
| 878 | 905 | ||
| 879 | (defun proced-process-tree (process-alist) | 906 | (defun proced-children-alist (process-alist) |
| 880 | "Return process tree for PROCESS-ALIST. | 907 | "Return children alist for PROCESS-ALIST. |
| 881 | The process tree is an alist with elements (PPID PID1 PID2 ...). | 908 | The children alist has elements (PPID PID1 PID2 ...). |
| 882 | PPID is a parent PID. PID1, PID2, ... are the child processes of PPID. | 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. | ||
| 883 | The list of children does not include grandchildren." | 911 | The list of children does not include grandchildren." |
| 884 | (let (children-list ppid cpids) | 912 | ;; The PPIDs inherit the sorting order of PROCESS-ALIST. |
| 885 | (dolist (process process-alist children-list) | 913 | (let ((process-tree (mapcar (lambda (a) (list (car a))) process-alist)) |
| 914 | ppid) | ||
| 915 | (dolist (process process-alist) | ||
| 886 | (setq ppid (cdr (assq 'ppid (cdr process)))) | 916 | (setq ppid (cdr (assq 'ppid (cdr process)))) |
| 887 | (if ppid | 917 | (if (and ppid |
| 888 | (setq children-list | 918 | ;; Ignore a PPID that equals PID. |
| 889 | (if (setq cpids (assq ppid children-list)) | 919 | (/= ppid (car process)) |
| 890 | (cons (cons ppid (cons (car process) (cdr cpids))) | 920 | ;; Accept only PPIDs that correspond to members in PROCESS-ALIST. |
| 891 | (assq-delete-all ppid children-list)) | 921 | (assq ppid process-alist)) |
| 892 | (cons (list ppid (car process)) | 922 | (let ((temp-alist process-tree) elt) |
| 893 | children-list))))))) | 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 | |||
| 932 | (defun proced-process-tree (process-alist) | ||
| 933 | "Return process tree for PROCESS-ALIST." | ||
| 934 | (let ((proced-children-alist (proced-children-alist process-alist)) | ||
| 935 | pid-alist proced-process-tree) | ||
| 936 | (while (setq pid-alist (pop proced-children-alist)) | ||
| 937 | (push (proced-process-tree-internal pid-alist) proced-process-tree)) | ||
| 938 | (nreverse proced-process-tree))) | ||
| 939 | |||
| 940 | (defun proced-process-tree-internal (pid-alist) | ||
| 941 | "Helper function for `proced-process-tree'." | ||
| 942 | (let ((cpid-list (cdr pid-alist)) cpid-alist cpid) | ||
| 943 | (while (setq cpid (car cpid-list)) | ||
| 944 | (if (setq cpid-alist (assq cpid proced-children-alist)) | ||
| 945 | ;; Unprocessed part of process tree that needs to be | ||
| 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)) |
| @@ -903,10 +1008,9 @@ This list includes PPID unless OMIT-PPID is non-nil." | |||
| 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)))) |
| @@ -914,9 +1018,16 @@ This list includes PPID unless OMIT-PPID is non-nil." | |||
| 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 |
| @@ -1055,6 +1166,8 @@ Return the sorted process list." | |||
| 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) |
| @@ -1084,8 +1197,12 @@ Prefix ARG controls sort order: | |||
| 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)))) |
| @@ -1200,6 +1317,10 @@ The return string is always 6 characters wide." | |||
| 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. |
| @@ -1219,6 +1340,7 @@ Replace newline characters by \"^J\" (two characters)." | |||
| 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) |
| @@ -1246,12 +1368,14 @@ Replace newline characters by \"^J\" (two characters)." | |||
| 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)) |
| @@ -1395,6 +1519,10 @@ Suppress status information if QUIET is nil." | |||
| 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)) |
| 1397 | 1521 | ||
| 1522 | ;; display as process tree? | ||
| 1523 | (setq proced-process-alist | ||
| 1524 | (proced-tree proced-process-alist)) | ||
| 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. |