comparison lisp/proced.el @ 98249:538f59dc1be8

(proced-grammar-alist, proced-custom-attributes) (proced-format-alist, proced-format, proced-filter-alist) (proced-filter, proced-sort): Use defcustom. (proced-mode): Fix docstring. (proced-process-attributes): Handle return value nil of functions in proced-custom-attributes.
author Roland Winkler <Roland.Winkler@physik.uni-erlangen.de>
date Sat, 20 Sep 2008 03:01:50 +0000
parents 87d64c3d48ac
children 38b176122f90
comparison
equal deleted inserted replaced
98248:215a88f14455 98249:538f59dc1be8
26 ;; system processes. You can use the normal Emacs commands to move around 26 ;; system processes. You can use the normal Emacs commands to move around
27 ;; in this buffer, and special Proced commands to operate on the processes 27 ;; in this buffer, and special Proced commands to operate on the processes
28 ;; listed. See `proced-mode' for getting started. 28 ;; listed. See `proced-mode' for getting started.
29 ;; 29 ;;
30 ;; To do: 30 ;; To do:
31 ;; - use defcustom where appropriate
32 ;; - interactive temporary customizability of flags in `proced-grammar-alist' 31 ;; - interactive temporary customizability of flags in `proced-grammar-alist'
33 ;; - allow "sudo kill PID", "renice PID" 32 ;; - allow "sudo kill PID", "renice PID"
34 ;; 33 ;;
35 ;; Wishlist 34 ;; Wishlist
36 ;; - tree view like pstree(1) 35 ;; - tree view like pstree(1)
82 ;; predicate like `<'. Otherwise, a list of proced predicates can be used 81 ;; predicate like `<'. Otherwise, a list of proced predicates can be used
83 ;; to refine the sort. 82 ;; to refine the sort.
84 ;; 83 ;;
85 ;; It would be neat if one could temporarily override the following 84 ;; It would be neat if one could temporarily override the following
86 ;; predefined rules. 85 ;; predefined rules.
87 (defvar proced-grammar-alist 86 (defcustom proced-grammar-alist
88 '( ;; attributes defined in `system-process-attributes' 87 '( ;; attributes defined in `system-process-attributes'
89 (euid "EUID" "%d" right proced-< nil (euid pid) (nil t nil)) 88 (euid "EUID" "%d" right proced-< nil (euid pid) (nil t nil))
90 (user "USER" nil left proced-string-lessp nil (user pid) (nil t nil)) 89 (user "USER" nil left proced-string-lessp nil (user pid) (nil t nil))
91 (egid "EGID" "%d" right proced-< nil (egid euid pid) (nil t nil)) 90 (egid "EGID" "%d" right proced-< nil (egid euid pid) (nil t nil))
92 (group "GROUP" nil left proced-string-lessp nil (group user pid) (nil t nil)) 91 (group "GROUP" nil left proced-string-lessp nil (group user pid) (nil t nil))
126 125
127 Each element has the form 126 Each element has the form
128 127
129 (KEY NAME FORMAT JUSTIFY PREDICATE REVERSE SORT-SCHEME REFINE-FLAGS). 128 (KEY NAME FORMAT JUSTIFY PREDICATE REVERSE SORT-SCHEME REFINE-FLAGS).
130 129
131 KEY is the car of a process attribute. 130 Symbol KEY is the car of a process attribute.
132 131
133 NAME appears in the header line. 132 String NAME appears in the header line.
134 133
135 FORMAT specifies the format for displaying the attribute values. 134 FORMAT specifies the format for displaying the attribute values.
136 It can be a string passed to `format'. It can be a function called 135 It can be a string passed to `format'. It can be a function called
137 with one argument, the value of the attribute. Nil means take as is. 136 with one argument, the value of the attribute. Nil means take as is.
138 137
163 This command compares the value of attribute KEY of every process with 162 This command compares the value of attribute KEY of every process with
164 the value of attribute KEY of the process at the position of point 163 the value of attribute KEY of the process at the position of point
165 using PREDICATE. 164 using PREDICATE.
166 If PREDICATE yields non-nil, the process is accepted if LESS-B is non-nil. 165 If PREDICATE yields non-nil, the process is accepted if LESS-B is non-nil.
167 If PREDICATE yields 'equal, the process is accepted if EQUAL-B is non-nil. 166 If PREDICATE yields 'equal, the process is accepted if EQUAL-B is non-nil.
168 If PREDICATE yields nil, the process is accepted if LARGER-B is non-nil.") 167 If PREDICATE yields nil, the process is accepted if LARGER-B is non-nil."
169 168 :group 'proced
170 (defvar proced-custom-attributes nil 169 :type '(repeat (list :tag "Attribute"
170 (symbol :tag "Key")
171 (string :tag "Header")
172 (choice :tag "Format"
173 (const :tag "None" nil)
174 (string :tag "Format String")
175 (function :tag "Formatting Function"))
176 (choice :tag "Justification"
177 (const :tag "left" left)
178 (const :tag "right" right)
179 (integer :tag "width"))
180 (function :tag "Predicate")
181 (boolean :tag "Reverse Sort Order")
182 (repeat :tag "Sort Scheme" (symbol :tag "Key"))
183 (list :tag "Refine Flags"
184 (boolean :tag "Less")
185 (boolean :tag "Equal")
186 (boolean :tag "Larger")))))
187
188 (defcustom proced-custom-attributes nil
171 "List of functions defining custom attributes. 189 "List of functions defining custom attributes.
172 This variable extends the functionality of `proced-process-attributes'. 190 This variable extends the functionality of `proced-process-attributes'.
173 Each function is called with one argument, the list of attributes 191 Each function is called with one argument, the list of attributes
174 of a system process. It returns a cons cell of the form (KEY . VALUE) 192 of a system process. It returns a cons cell of the form (KEY . VALUE)
175 like `system-process-attributes'.") 193 like `system-process-attributes'. This cons cell is appended to the list
194 returned by `proced-process-attributes'.
195 If the function returns nil, the value is ignored."
196 :group 'proced
197 :type '(repeat (function :tag "Attribute")))
176 198
177 ;; Formatting and sorting rules are defined "per attribute". If formatting 199 ;; Formatting and sorting rules are defined "per attribute". If formatting
178 ;; and / or sorting should use more than one attribute, it appears more 200 ;; and / or sorting should use more than one attribute, it appears more
179 ;; transparent to define a new derived attribute, so that formatting and 201 ;; transparent to define a new derived attribute, so that formatting and
180 ;; sorting can use them consistently. (Are there exceptions to this rule? 202 ;; sorting can use them consistently. (Are there exceptions to this rule?
181 ;; Would it be advantageous to have yet more general methods available?) 203 ;; Would it be advantageous to have yet more general methods available?)
182 ;; Sorting can also be based on attributes that are invisible in the listing. 204 ;; Sorting can also be based on attributes that are invisible in the listing.
183 205
184 (defvar proced-format-alist 206 (defcustom proced-format-alist
185 '((short user pid pcpu pmem start time args) 207 '((short user pid pcpu pmem start time args)
186 (medium user pid pcpu pmem vsize rss ttname state start time args) 208 (medium user pid pcpu pmem vsize rss ttname state start time args)
187 (long user euid group pid pri nice pcpu pmem vsize rss ttname state 209 (long user euid group pid pri nice pcpu pmem vsize rss ttname state
188 start time args) 210 start time args)
189 (verbose user euid group egid pid ppid pgrp sess comm pri nice pcpu pmem 211 (verbose user euid group egid pid ppid pgrp sess comm pri nice pcpu pmem
190 state thcount vsize rss ttname tpgid minflt majflt cminflt cmajflt 212 state thcount vsize rss ttname tpgid minflt majflt cminflt cmajflt
191 start time utime stime ctime cutime cstime etime args)) 213 start time utime stime ctime cutime cstime etime args))
192 "Alist of formats of listing. 214 "Alist of formats of listing.
193 The car of each element is a symbol, the name of the format. 215 The car of each element is a symbol, the name of the format.
194 The cdr is a list of keys appearing in `proced-grammar-alist'.") 216 The cdr is a list of keys appearing in `proced-grammar-alist'."
195 217 :group 'proced
196 (defvar proced-format 'short 218 :type '(alist :key-type (symbol :tag "Format Name")
219 :value-type (repeat :tag "Keys" (symbol :tag ""))))
220
221 (defcustom proced-format 'short
197 "Current format of Proced listing. 222 "Current format of Proced listing.
198 It can be the car of an element of `proced-format-alist'. 223 It can be the car of an element of `proced-format-alist'.
199 It can also be a list of keys appearing in `proced-grammar-alist'.") 224 It can also be a list of keys appearing in `proced-grammar-alist'."
225 :group 'proced
226 :type '(choice (symbol :tag "Format Name")
227 (repeat :tag "Keys" (symbol :tag ""))))
200 (make-variable-buffer-local 'proced-format) 228 (make-variable-buffer-local 'proced-format)
201 229
202 ;; FIXME: is there a better name for filter `user' that does not coincide 230 ;; FIXME: is there a better name for filter `user' that does not coincide
203 ;; with an attribute key? 231 ;; with an attribute key?
204 (defvar proced-filter-alist 232 (defcustom proced-filter-alist
205 `((user (user . ,(concat "\\`" (user-real-login-name) "\\'"))) 233 `((user (user . ,(concat "\\`" (user-real-login-name) "\\'")))
206 (user-running (user . ,(concat "\\`" (user-real-login-name) "\\'")) 234 (user-running (user . ,(concat "\\`" (user-real-login-name) "\\'"))
207 (state . "\\`[Rr]\\'")) 235 (state . "\\`[Rr]\\'"))
208 (all) 236 (all)
209 (all-running (state . "\\`[Rr]\\'")) 237 (all-running (state . "\\`[Rr]\\'"))
221 \(KEY . FUN) Apply function FUN to attribute KEY. Accept this process, 249 \(KEY . FUN) Apply function FUN to attribute KEY. Accept this process,
222 if FUN returns non-nil. 250 if FUN returns non-nil.
223 \(function . FUN) For each process, apply function FUN to list of attributes 251 \(function . FUN) For each process, apply function FUN to list of attributes
224 of each. Accept the process if FUN returns non-nil. 252 of each. Accept the process if FUN returns non-nil.
225 \(fun-all . FUN) Apply function FUN to entire process list. 253 \(fun-all . FUN) Apply function FUN to entire process list.
226 FUN must return the filtered list.") 254 FUN must return the filtered list."
227 255 :group 'proced
228 (defvar proced-filter 'user 256 :type '(repeat (cons :tag "Filter"
257 (symbol :tag "Filter Name")
258 (repeat :tag "Filters"
259 (choice (cons :tag "Key . Regexp" (symbol :tag "Key") regexp)
260 (cons :tag "Key . Function" (symbol :tag "Key") function)
261 (cons :tag "Function" (const :tag "Key: function" function) function)
262 (cons :tag "Fun-all" (const :tag "Key: fun-all" fun-all) function))))))
263
264 (defcustom proced-filter 'user
229 "Current filter of proced listing. 265 "Current filter of proced listing.
230 It can be the car of an element of `proced-filter-alist'. 266 It can be the car of an element of `proced-filter-alist'.
231 It can also be a list of elementary filters as in the cdrs of the elements 267 It can also be a list of elementary filters as in the cdrs of the elements
232 of `proced-filter-alist'.") 268 of `proced-filter-alist'."
269 :group 'proced
270 :type '(choice (symbol :tag "Filter Name")
271 (repeat :tag "Filters"
272 (choice (cons :tag "Key . Regexp" (symbol :tag "Key") regexp)
273 (cons :tag "Key . Function" (symbol :tag "Key") function)
274 (cons :tag "Function" (const :tag "Key: function" function) function)
275 (cons :tag "Fun-all" (const :tag "Key: fun-all" fun-all) function)))))
233 (make-variable-buffer-local 'proced-filter) 276 (make-variable-buffer-local 'proced-filter)
234 277
235 (defvar proced-sort 'pcpu 278 (defcustom proced-sort 'pcpu
236 "Current sort scheme for proced listing. 279 "Current sort scheme for proced listing.
237 It must be the KEY of an element of `proced-grammar-alist'. 280 It must be the KEY of an element of `proced-grammar-alist'.
238 It can also be a list of KEYs as in the SORT-SCHEMEs of the elements 281 It can also be a list of KEYs as in the SORT-SCHEMEs of the elements
239 of `proced-grammar-alist'.") 282 of `proced-grammar-alist'."
283 :group 'proced
284 :type '(choice (symbol :tag "Sort Scheme")
285 (repeat :tag "Key List" (symbol :tag "Key"))))
240 (make-variable-buffer-local 'proced-format) 286 (make-variable-buffer-local 'proced-format)
241 287
242 (defcustom proced-goal-attribute 'args 288 (defcustom proced-goal-attribute 'args
243 "If non-nil, key of the attribute that defines the `goal-column'." 289 "If non-nil, key of the attribute that defines the `goal-column'."
244 :group 'proced 290 :group 'proced
245 :type '(choice (const :tag "none" nil) 291 :type '(choice (const :tag "none" nil)
246 (symbol :tag "key"))) 292 (symbol :tag "key")))
247 293
248 (defcustom proced-timer-interval 5 294 (defcustom proced-timer-interval 5
249 "Time interval in seconds for updating Proced buffers." 295 "Time interval in seconds for auto updating Proced buffers."
250 :group 'proced 296 :group 'proced
251 :type 'integer) 297 :type 'integer)
252 298
253 (defcustom proced-timer-flag nil 299 (defcustom proced-timer-flag nil
254 "Non-nil for auto update of a Proced buffer. 300 "Non-nil for auto update of a Proced buffer.
299 345
300 (defvar proced-header-line nil 346 (defvar proced-header-line nil
301 "Headers in Proced buffer as a string.") 347 "Headers in Proced buffer as a string.")
302 (make-variable-buffer-local 'proced-header-line) 348 (make-variable-buffer-local 'proced-header-line)
303 349
350 (defvar proced-process-tree nil
351 "Process tree of listing (internal variable).")
352
353 (defvar proced-timer nil
354 "Stores if Proced timer is already installed.")
355
304 (defvar proced-log-buffer "*Proced log*" 356 (defvar proced-log-buffer "*Proced log*"
305 "Name of Proced Log buffer.") 357 "Name of Proced Log buffer.")
306
307 (defvar proced-process-tree nil
308 "Process tree of listing (internal variable).")
309
310 (defvar proced-timer nil
311 "Stores if Proced timer is already installed.")
312 358
313 (defconst proced-help-string 359 (defconst proced-help-string
314 "(n)ext, (p)revious, (m)ark, (u)nmark, (k)ill, (q)uit (type ? for more help)" 360 "(n)ext, (p)revious, (m)ark, (u)nmark, (k)ill, (q)uit (type ? for more help)"
315 "Help string for proced.") 361 "Help string for proced.")
316 362
485 531
486 ;; proced mode 532 ;; proced mode
487 533
488 (define-derived-mode proced-mode nil "Proced" 534 (define-derived-mode proced-mode nil "Proced"
489 "Mode for displaying UNIX system processes and sending signals to them. 535 "Mode for displaying UNIX system processes and sending signals to them.
490 Type \\<proced-mode-map>\\[proced-mark] to mark a process for later commands. 536 Type \\[proced] to start a Proced session. In a Proced buffer
537 type \\<proced-mode-map>\\[proced-mark] to mark a process for later commands.
491 Type \\[proced-send-signal] to send signals to marked processes. 538 Type \\[proced-send-signal] to send signals to marked processes.
492 539
493 The initial content of a listing is defined by the variable `proced-filter' 540 The initial content of a listing is defined by the variable `proced-filter'
494 and the variable `proced-format'. 541 and the variable `proced-format'.
495 The variable `proced-filter' specifies which system processes are displayed. 542 The variable `proced-filter' specifies which system processes are displayed.
1189 (mapcar (lambda (pid) 1236 (mapcar (lambda (pid)
1190 (let* ((attributes (system-process-attributes pid)) 1237 (let* ((attributes (system-process-attributes pid))
1191 (utime (cdr (assq 'utime attributes))) 1238 (utime (cdr (assq 'utime attributes)))
1192 (stime (cdr (assq 'stime attributes))) 1239 (stime (cdr (assq 'stime attributes)))
1193 (cutime (cdr (assq 'cutime attributes))) 1240 (cutime (cdr (assq 'cutime attributes)))
1194 (cstime (cdr (assq 'cstime attributes)))) 1241 (cstime (cdr (assq 'cstime attributes)))
1242 attr)
1195 (setq attributes 1243 (setq attributes
1196 (append (list (cons 'pid pid)) 1244 (append (list (cons 'pid pid))
1197 (if (and utime stime) 1245 (if (and utime stime)
1198 (list (cons 'time (time-add utime stime)))) 1246 (list (cons 'time (time-add utime stime))))
1199 (if (and cutime cstime) 1247 (if (and cutime cstime)
1200 (list (cons 'ctime (time-add cutime cstime)))) 1248 (list (cons 'ctime (time-add cutime cstime))))
1201 attributes)) 1249 attributes))
1202 (dolist (fun proced-custom-attributes) 1250 (dolist (fun proced-custom-attributes)
1203 (push (funcall fun attributes) attributes)) 1251 (if (setq attr (funcall fun attributes))
1252 (push attr attributes)))
1204 (cons pid attributes))) 1253 (cons pid attributes)))
1205 (list-system-processes))) 1254 (list-system-processes)))
1206 1255
1207 (defun proced-update (&optional revert quiet) 1256 (defun proced-update (&optional revert quiet)
1208 "Update the `proced' process information. Preserves point and marks. 1257 "Update the `proced' process information. Preserves point and marks.
1264 proced-header-line)) 1313 proced-header-line))
1265 (if (nth 3 grammar) 1314 (if (nth 3 grammar)
1266 (match-beginning 0) 1315 (match-beginning 0)
1267 (match-end 0))))) 1316 (match-end 0)))))
1268 1317
1269 ;; restore process marks and buffer position (if possible) 1318 ;; Restore process marks and buffer position (if possible).
1270 ;; FIXME: sometimes this puts point in the middle of the proced buffer 1319 ;; Sometimes this puts point in the middle of the proced buffer
1271 ;; where it is not interesting. Is there a better / more flexible solution? 1320 ;; where it is not interesting. Is there a better / more flexible solution?
1272 (goto-char (point-min)) 1321 (goto-char (point-min))
1273 (let (pid mark new-pos) 1322 (let (pid mark new-pos)
1274 (if (or mp-list (car old-pos)) 1323 (if (or mp-list (car old-pos))
1275 (while (not (eobp)) 1324 (while (not (eobp))