comparison lisp/modes/view-process-mode.el @ 165:5a88923fcbfe r20-3b9

Import from CVS: tag r20-3b9
author cvs
date Mon, 13 Aug 2007 09:44:42 +0200
parents
children
comparison
equal deleted inserted replaced
164:4e0740e5aab2 165:5a88923fcbfe
1 ;;; view-process-mode.el --- Display current running processes
2
3 ;; Copyright (C) 1994, 1995, 1996 Heiko Muenkel
4
5 ;; Author: Heiko Muenkel <muenkel@tnt.uni-hannover.de>
6 ;; Keywords: processes
7
8 ;; This file is part of XEmacs.
9
10 ;; XEmacs is free software; you can redistribute it and/or modify it
11 ;; under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your
13 ;; option) any later version.
14
15 ;; XEmacs is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ;; General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with XEmacs; See the file COPYING. if not, write to the Free
22 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 ;; 02111-1307, USA.
24
25 ;;; Synched up with: Emacs 20.1
26
27 ;;; Commentary:
28
29 ;; DollarId: view-process-mode.el,v 1.113 1996/08/17 15:12:01 muenkel Exp $
30 ;; This file defines the the view-process-mode, a mode for displaying
31 ;; the current processes with ps on UNIX systems. There are also
32 ;; commands to sort and filter the output and to send signals to the
33 ;; processes.
34
35 ;; You can display the processes with the command `view-processes'.
36 ;; If you are familar with the UNIX ps command and its switches,
37 ;; then you can also use the command `View-process-status' or
38 ;; it's short cut `ps', which are asking for the command
39 ;; switches. You can also run the commands on a remote system
40 ;; via rsh. For that you must give a prefix arg to the
41 ;; commands. This leads to a question for the remote host name.
42
43 ;; You need also the files: adapt.el
44 ;; view-process-system-specific.el
45 ;; view-process-xemacs.el
46 ;; view-process-emacs-19.el
47 ;;
48 ;; Installation:
49 ;;
50 ;; Put this file and the file adapt.el
51 ;; in one of your your load-path directories and
52 ;; the following line in your ~/.emacs (without leading ;;;):
53 ;; (autoload 'ps "view-process-mode"
54 ;; "Prints a list with processes in the buffer `View-process-buffer-name'.
55 ;; COMMAND-SWITCHES is a string with the command switches (ie: -aux).
56 ;; IF the optional argument REMOTE-HOST is given, then the command will
57 ;; be executed on the REMOTE-HOST. If an prefix arg is given, then the
58 ;; function asks for the name of the remote host."
59 ;; t)
60 ;;
61 ;; In the FSF Emacs 19 you should (but must not) put the following
62 ;; line in your ~/.emacs:
63 ;;; (transient-mark-mode nil)
64
65 ;;; Code:
66
67 (provide 'view-process-mode)
68 (require 'view-process-system-specific)
69
70 (defconst View-process-package-version "2.4")
71
72 (defconst View-process-package-name "hm--view-process")
73
74 (defconst View-process-package-maintainer "muenkel@tnt.uni-hannover.de")
75
76 (defun View-process-xemacs-p ()
77 "Returns non nil if the editor is the XEmacs or lemacs."
78 (or (string-match "Lucid" emacs-version)
79 (string-match "XEmacs" emacs-version)))
80
81 (defun View-process-lemacs-p ()
82 "Returns non nil if the editor is the lemacs."
83 (string-match "Lucid" emacs-version))
84
85 (if (not (View-process-xemacs-p))
86 (require 'view-process-adapt)
87 )
88
89 (defvar View-process-status-command "ps"
90 "*Command which reports process status (ps).
91 The variable is buffer local.")
92
93 (make-variable-buffer-local 'View-process-status-command)
94
95 (defvar View-process-status-command-switches-bsd "-auxw"
96 "*Switches for the command `view-processes' on BSD systems.
97 Switches which suppresses the header line are not allowed here.")
98
99 (defvar View-process-status-command-switches-system-v "-edaf"
100 "*Switches for the command `view-processes' on System V systems.
101 Switches which suppresses the header line are not allowed here.")
102
103 (defvar View-process-status-last-command-switches nil
104 "Switches of the last `View-process-status-command'.
105 The variable is buffer local.")
106
107 (make-variable-buffer-local 'View-process-status-last-command-switches)
108
109 (defvar View-process-signal-command "kill"
110 "*Command which sends a signal to a process (kill).
111 The variable is buffer local.")
112
113 (make-variable-buffer-local 'View-process-signal-command)
114
115 (defvar View-process-renice-command "renice"
116 "*Command which alter priority of running processes.")
117
118 (make-variable-buffer-local 'View-process-renice-command)
119
120 (defvar View-process-default-nice-value "4"
121 "*Default nice value for altering the priority of running processes.")
122
123 (defvar View-process-rsh-command "rsh"
124 "*Remote shell command (rsh).
125 The variable is buffer local.")
126
127 (make-variable-buffer-local 'View-process-rsh-command)
128
129 (defvar View-process-uname-command "uname"
130 "*The uname command (It returns the system name).
131 The variable is buffer local.")
132
133 (make-variable-buffer-local 'View-process-uname-command)
134
135 (defvar View-process-uname-switches "-sr"
136 "*Switches for uname, so that it returns the sysname and the release.")
137
138 (defvar View-process-test-command "test"
139 "*The test command.")
140
141 (make-variable-buffer-local 'View-process-test-command)
142
143 (defvar View-process-test-switches "-x"
144 "*Switches for test, to test if an executable exists.")
145
146 (defvar View-process-uptime-command "uptime"
147 "*The uptime command.
148 No idea at the moment, if this exists on all systems.
149 It should return some informations over the system.")
150
151 (make-variable-buffer-local 'View-process-uptime-command)
152
153 (defvar View-process-buffer-name "*ps*"
154 "Name of the output buffer for the 'View-process-mode'.
155 The variable is buffer local.")
156
157 (make-variable-buffer-local 'View-process-buffer-name)
158
159 (defvar View-process-mode-hook nil
160 "*This hook is run after reading in the processes.")
161
162 (defvar View-process-motion-help t
163 "*If non nil, then help messages are displayed during mouse motion.
164 The variable is buffer local.")
165
166 (make-variable-buffer-local 'View-process-motion-help)
167
168 (defvar View-process-display-with-2-windows t
169 "*Determines the display type of the `View-process-mode'.
170 If it is non nil, then 2 windows are used instead of one window.
171 In the second window are the header lines displayed.")
172
173 (defvar View-process-hide-header t
174 "*The header lines in the view processes buffer are hide, if this is t.")
175
176 (make-variable-buffer-local 'View-process-hide-header)
177
178 (defvar View-process-truncate-lines t
179 "*Truncates the liens in the view process buffer if t.")
180
181 (make-variable-buffer-local 'View-process-truncate-lines)
182
183 (defvar View-process-display-short-key-descriptions t
184 "*Controls, whether short key descriptions are displayed or not.")
185
186 (defvar View-process-display-uptime t
187 "*Controls, whether the uptime is displayed or not.")
188
189 (defvar View-process-use-font-lock t
190 "*Determines, if the `font-lock-mode' should be used or not.")
191
192 (defvar View-process-ps-header-window-offset 2
193 "Offset for the size of the ps header window.")
194
195 (defvar View-process-ps-header-window-size 0
196 "Internal variable. The size of the window with the *ps header* buffer.")
197
198 (make-variable-buffer-local 'View-process-ps-header-window-size)
199
200 (defvar View-process-stop-motion-help nil
201 "Internal variable. Stops motion help temporarily.")
202
203 (defvar View-process-deleted-lines nil
204 "Internal variable. A list with lines, which are deleted by a filter.")
205
206 (make-variable-buffer-local 'View-process-deleted-lines)
207
208 (defvar View-process-header-buffer-name "*ps header*"
209 "Name of the view process header buffer.")
210
211 (make-variable-buffer-local 'View-process-header-buffer-name)
212
213 (defvar View-process-header-mode-name "psheader"
214 "Name of the `view process header mode'.")
215
216 (defvar View-process-header-mode-hook nil
217 "*This hook is run after building the header buffer.")
218
219 (defvar View-process-header-mode-line-off t
220 "t means do not display modeline in view-process-header-mode.
221 This does only work in the XEmacs 19.12 or higher.")
222
223 (defvar View-process-header-line-detection-list '("PID" "COMMAND" "COMD" "CMD")
224 "*The header line is detected with the help of this list.
225 At least one of these words must be in a header line. Otherwise
226 an error is signaled. YOu must only change this list, if your ps
227 prodices header lines with strings, that are not in this list.")
228
229 (defvar View-process-header-line-background "yellow"
230 "*Background color of the header line.")
231
232 (defvar View-process-header-line-foreground "blue"
233 "*Foreground color of the header line.")
234
235 (defvar View-process-header-line-font (face-font 'bold)
236 "*Font of the header line")
237
238 (defvar View-process-header-line-underline-p t
239 "*T, if the header line should be underlined.")
240
241 (defvar View-process-no-mark ?_
242 "*A character with specifies, that a line isn't marked.")
243
244 (defvar View-process-signaled-line-background nil
245 "*Background color of the line with a signaled or reniced process.")
246
247 (defvar View-process-signaled-line-foreground "grey80"
248 "*Foreground color of the line with a signaled or reniced process.")
249
250 (defvar View-process-signaled-line-font (face-font 'italic)
251 "*Font of the line with a signaled or reniced process.")
252
253 (defvar View-process-signaled-line-underline-p nil
254 "*T, if the \"signaled line\" should be underlined.")
255
256 (defvar View-process-signaled-line-mark ?s
257 "*A character, which is used as a mark for \"signaled lines\".")
258
259 (defvar View-process-signal-line-background nil
260 "*Background color of the line with the process which should be signaled.")
261
262 (defvar View-process-signal-line-foreground "red"
263 "*Foreground color of the line with the process which should be signaled.")
264
265 (defvar View-process-signal-line-font (face-font 'bold)
266 "*Font of the line with the process which should be signaled.")
267
268 (defvar View-process-signal-line-underline-p nil
269 "*T, if the \"signal line\" should be underlined.")
270
271 (defvar View-process-signal-line-mark ?K
272 "*A character, which is used as a mark for \"signal lines\".")
273
274 (defvar View-process-renice-line-background nil
275 "*Background color of the line with the process which should be reniced.")
276
277 (defvar View-process-renice-line-foreground "red"
278 "*Foreground color of the line with the process which should be reniced.")
279
280 (defvar View-process-renice-line-font (face-font 'bold)
281 "*Font of the line with the process which should be reniced.")
282
283 (defvar View-process-renice-line-underline-p nil
284 "*T, if the \"renice line\" should be underlined.")
285
286 (defvar View-process-renice-line-mark ?N
287 "*A character, which is used as a mark for \"renice lines\".")
288
289 (defvar View-process-child-line-background nil
290 "*Background color of a line with a child process.")
291
292 (defvar View-process-child-line-foreground "darkviolet"
293 "*Foreground color of a line with a child process.")
294
295 (defvar View-process-child-line-font (face-font 'italic)
296 "*Font color of a line with a child process.")
297
298 (defvar View-process-child-line-underline-p nil
299 "*T, if the \"line with a child process\" should be underlined.")
300
301 (defvar View-process-child-line-mark ?C
302 "*A character, which is used as a mark for child processes.")
303
304 (defvar View-process-parent-line-background "LightBlue"
305 "*Background color of a line with a parent process.")
306
307 (defvar View-process-parent-line-foreground "darkviolet"
308 "*Foreground color of a line with a parent process.")
309
310 (defvar View-process-parent-line-font (face-font 'bold)
311 "*Font color of a line with a parent process.")
312
313 (defvar View-process-parent-line-underline-p t
314 "*T, if the \"line with a parent\" should be underlined.")
315
316 (defvar View-process-parent-line-mark ?P
317 "*A character, which is used as a mark for parent processes.")
318
319 (defvar View-process-single-line-background nil
320 "*Background color of a line with a single line mark.")
321
322 (defvar View-process-single-line-foreground "darkblue"
323 "*Foreground color of a line with a single line mark.")
324
325 (defvar View-process-single-line-font (face-font 'bold)
326 "*Font color of a line with a single line mark.")
327
328 (defvar View-process-single-line-underline-p t
329 "*T, if the \"line with a single line mark\" should be underlined.")
330
331 (defvar View-process-single-line-mark ?*
332 "*A character, which is used as a single line mark.")
333
334 (defvar View-process-font-lock-keywords
335 (list
336 (cons (concat "^"
337 (char-to-string View-process-child-line-mark)
338 " .*")
339 'View-process-child-line-face)
340 (cons (concat "^"
341 (char-to-string View-process-parent-line-mark)
342 " .*")
343 'View-process-parent-line-face)
344 (cons (concat "^\\"
345 (char-to-string View-process-single-line-mark)
346 " .*")
347 'View-process-single-line-face)
348 (cons (concat "^"
349 (char-to-string View-process-signaled-line-mark)
350 " .*")
351 'View-process-signaled-line-face)
352 (cons (concat "^"
353 (char-to-string View-process-signal-line-mark)
354 " .*")
355 'View-process-signal-line-face)
356 (cons (concat "^"
357 (char-to-string View-process-renice-line-mark)
358 " .*")
359 'View-process-renice-line-face)
360 )
361 "The font lock keywords for the `View-process-mode'."
362 )
363
364 (defvar View-process-pid-mark-alist nil
365 "Internal variable. An alist with marks and pids.")
366
367 (make-variable-buffer-local 'View-process-pid-mark-alist)
368
369 (defvar View-process-last-pid-mark-alist nil
370 "Internal variable. An alist withthe last marks and pids.")
371
372 (make-variable-buffer-local 'View-process-last-pid-mark-alist)
373
374 (defvar View-process-sorter-and-filter nil
375 "*A list, which specifies sorter and filter commands.
376 These commands will be run over the ps output, every time after
377 ps has create a new output.
378 The list consists of sublists, whereby every sublist specifies a
379 command. The first element of each list is a keyword, which
380 determines a command.
381 The following keywords are allowed:
382 sort - Sort the output by an output field
383 filter - Filter the output by an output field, delete non matching l.
384 exclude-filter - Filter the output by an output field, delete matching lines
385 grep - Filter the output by the whole line, delete non matching l.
386 exclude-grep - Filter the output by the whole line, delete matching lines
387 reverse - Reverse the order of the output lines.
388
389 The cdr of each sublist depends on the keyword. The following shows
390 the syntax of the different sublist types:
391 (sort <fieldname>)
392 (filter <fieldname> <regexp>)
393 (exclude-filter <fieldname> <regexp>)
394 (grep <regexp>)
395 (exclude-grep <regexp>)
396 (reverse)
397
398 Where <fieldname> is a string with determines the name of an output field
399 and <regexp> is a string with an regular expression. The output field names
400 are derived from the header line of the ps output.")
401
402 (defvar View-process-actual-sorter-and-filter nil
403 "Internal variable. It holds the actual sorter and filter commands.
404 Don't change it!")
405
406 (make-variable-buffer-local 'View-process-actual-sorter-and-filter)
407
408 (defvar View-process-itimer-value 5
409 "*Value of the view process itimer.")
410
411 (defvar View-process-system-type nil
412 "Internal variable. Type of the system, on which the ps command is called.
413 The variable is buffer local.")
414
415 (make-variable-buffer-local 'View-process-system-type)
416
417 (defvar View-process-remote-host nil
418 "Internal variable. Name of the remote host or nil.
419 The variable is buffer local.")
420
421 (make-variable-buffer-local 'View-process-remote-host)
422
423 (defvar View-process-header-start nil
424 "Internal variable. Start of the ps output header line.
425 The variable is buffer local.")
426
427 (make-variable-buffer-local 'View-process-header-start)
428
429 (defvar View-process-header-end nil
430 "Internal variable. End of the ps output header line.
431 The variable is buffer local.")
432
433 (make-variable-buffer-local 'View-process-header-end)
434
435 (defvar View-process-output-start nil
436 "Internal variable. Start of the ps output (after the header).
437 The variable is buffer local.")
438
439 (make-variable-buffer-local 'View-process-output-start)
440
441 (defvar View-process-output-end nil
442 "Internal variable. End of the ps output (after the header).
443 The variable is buffer local.")
444
445 (make-variable-buffer-local 'View-process-output-end)
446
447 (defvar View-process-old-window-configuration nil
448 "Internal variable. Window configuration before the first ps command.")
449
450 (make-variable-buffer-local 'View-process-old-window-configuration)
451
452 (defvar View-process-max-fields nil
453 "Internal variable. Number of output fields.
454 The variable is buffer local.")
455
456 (make-variable-buffer-local 'View-process-max-fields)
457
458 (defvar View-process-field-names nil
459 "Internal variable. An alist with the fieldnames and fieldnumbers.
460 The variable is buffer local.")
461
462 (make-variable-buffer-local 'View-process-max-fields)
463
464 (defvar View-process-field-blanks-already-replaced nil
465 "Internal variable. It is t, if blanks in fields are already replaced.")
466
467 (make-variable-buffer-local 'View-process-field-blanks-already-replaced)
468
469 (defvar View-process-kill-signals nil
470 "An alist with the possible signals for the kill command.
471 Don't change it by hand!
472 The variable is initialised each time after running ps.
473 The variable is buffer local.")
474
475 (make-variable-buffer-local 'View-process-kill-signals)
476
477 (defvar View-process-kill-signals-general
478 '(("SIGHUP" "1") ("SIGKILL" "9") ("SIGTERM" "15")
479 ("1" "1") ("2" "2") ("3" "3") ("4" "4") ("5" "5") ("6" "6") ("7" "7")
480 ("8" "8") ("9" "9") ("10" "10") ("11" "11") ("12" "12") ("13" "13")
481 ("14" "14") ("15" "15") ("16" "16") ("17" "17") ("18" "18")
482 ("19" "19") ("20" "20") ("21" "21") ("22" "22") ("23" "23")
483 ("24" "24") ("25" "25") ("26" "26") ("27" "27") ("28" "28")
484 ("29" "29") ("30" "30") ("31" "31"))
485 "An alist with the possible signals for the kill command.
486 This list is used, if no system specific list is defined.
487 It may be that you've other signals on your system. Try to test
488 it with \"kill -l\" in a shell.")
489
490 (defvar View-process-default-kill-signal "SIGTERM"
491 "*Default signal for the function `View-process-send-signal-to-process'.
492 The string must be also in the alist `View-process-kill-signals'!")
493
494 (defvar View-process-pid-field-name "PID"
495 "*The name of the field with the PID's.
496 The name must be the same as in the first outputline of the
497 command `View-process-status-command' (ps).
498 The variable is buffer local.")
499
500 (make-variable-buffer-local 'View-process-pid-field-name)
501
502 (defvar View-process-ppid-field-name "PPID"
503 "*The name of the field with the PPID's.
504 The name must be the same as in the first outputline of the
505 command `View-process-status-command' (ps).
506 The variable is buffer local.")
507
508 (make-variable-buffer-local 'View-process-ppid-field-name)
509
510 (defvar View-process-host-names-and-system-types nil
511 "A list with the names and the system types of hosts.
512 Each entry of the list looks like the following:
513 (<hostname> (<system-type> <version-number> <bsd-or-system-v>
514 <field-name-descriptions>
515 <kill-signals>))
516 Here are some examples:
517 (\"daedalus\" (\"sunos\" \"4\" \"bsd\"
518 View-process-field-name-descriptions-sunos4
519 View-process-kill-signals-sunos4))
520 (\"bach\" (\"linux\" nil \"bsd\"
521 nil
522 View-process-kill-signals-linux
523 ))
524 (\"cesar\" (nil nil \"bsd\"))
525 The list will be anhanced by the program, each time you run ps on
526 a new system. But you can also set this variable by hand in your
527 .emacs. If the host name is found in this list, then the system
528 type will not be checked again."
529 )
530
531 (defvar View-process-status-history nil
532 "A list with the command switch history of the status command (ps).")
533
534 (defvar View-process-remote-host-history nil
535 "A list with the remote host history.")
536
537 (defvar View-process-field-name-history nil
538 "A list with the field name history.")
539
540 (defvar View-process-filter-history nil
541 "A list with the filter history.")
542
543 (defvar View-process-signal-history nil
544 "A list with the signal history.")
545
546 (defvar View-process-field-name-descriptions nil
547 "Help list with the descriptions of ps fields.
548 Don't change it by hand!
549 The variable is initialised each time after running ps.
550 The variable is buffer local.")
551
552 (make-variable-buffer-local 'View-process-field-name-descriptions)
553
554 (defvar View-process-field-name-descriptions-general
555 '(
556 ("m" "Mark column of the View Processes Mode.") ; not a real field name
557 ("ADDR" "The memory address of the process. ")
558 ("%CPU" "CPU usage in percentage.")
559 ("%MEM" "Real Memory usage in percentage.")
560 ("COMMAND" "Command Name.")
561 ("F" ("Status= "
562 ("0" "0=not in main memory.")
563 ("1" "1=in main memory.")
564 ("2" "2=system process.")
565 ("4" "4=blocked in the main memory.")
566 ("10" "10=swapped out.")
567 ("20" "20=controlled by another one.")))
568 ("NI" "UNIX nice value, a positive value means less CPU time.")
569 ("PAGEIN" "Number of major page faults.")
570 ("PGID" "Process group id. ")
571 ("PID" "The process id.")
572 ("PPID" "The process id of the parent process.")
573 ("PRI" "Priority, a big value is a small priority.")
574 ("RSS" "Real (resident set) size, KBytes of program in memory.")
575 ("SHARE" "Shared memory")
576 ("SID" "ID of the session to which the process belongs. ")
577 ("SIZE" "Virtual image size, size of text+data+stack (in KByte ?).")
578 ("START" "Start time.")
579 ("STAT" ("Status. "
580 ("R" "R=runnable. ")
581 ("S" "S=sleeping. ")
582 ("D" "D=un-interruptible sleep (eg disk or NFS I/O). ")
583 ("T" "T=stopped or traced. ")
584 ("Z" "Z=zombie (terminated). ")
585 ("W" "W=waiting on an event. ")
586 ("I" "I=intermediate status. ")
587 ("N" "N=started with nice. ")
588 ))
589 ("SWAP" "Kilobytes (with -p pages) on swap device.")
590 ("TIME" "Elapsed process time.")
591 ("TPGID" "Process group id of the associated terminal. ")
592 ("TRS" "Text resident size.")
593 ("TT" ("Dialog station. " ("?" "?=No dialog station")))
594 ("TTY" ("Dialog station. " ("?" "?=No dialog station")))
595 ("UID" "User Id.")
596 ("USER" "Owner of the process.")
597 ("WCHAN" "Name of the kernel function where the process is sleeping.")
598 )
599 "Help list with the descriptions of ps fields.
600 This is a general list, which should be true for many systems.
601 This list will only be used, if there is no entry in a special
602 list for the system.")
603
604 (defvar View-process-insert-blank-alist
605 '(("SZ" behind-predecessor 0)
606 ("SIZE" behind-predecessor 0)
607 ("RSS" behind-predecessor 0)
608 ("START" behind 1))
609 "Determines places in the output, where a blank should be inserted.
610 It is an alist and each sublist has the following structure:
611 (field-name position-descriptor offset)
612 The field-name is a string with the name of the field.
613 The position-descriptor determines a position. It has one of the
614 following values:
615 `in-front' => insert in front of the field.
616 `in-front-successor' => insert in front of the successor of the field.
617 `behind' => insert behind of the field.
618 `behind-predecessor' => insert behind the predecessor of the field.
619 The offset is an integer , which specifies an offset.")
620
621 (defvar View-process-mode-syntax-table nil
622 "Syntax table for the `View-process-mode'.")
623
624 (if (not View-process-mode-syntax-table)
625 (let ((i 0))
626 (setq View-process-mode-syntax-table (make-syntax-table))
627 (setq i ?!)
628 (while (<= i ?#)
629 (modify-syntax-entry i "w" View-process-mode-syntax-table)
630 (setq i (1+ i)))
631 (modify-syntax-entry ?, "w" View-process-mode-syntax-table)
632 (modify-syntax-entry ?. "w" View-process-mode-syntax-table)
633 (setq i ?:)
634 (while (<= i ?\;)
635 (modify-syntax-entry i "w" View-process-mode-syntax-table)
636 (setq i (1+ i)))
637 (setq i ??)
638 (while (<= i ?@)
639 (modify-syntax-entry i "w" View-process-mode-syntax-table)
640 (setq i (1+ i)))
641 (modify-syntax-entry ?\\ "w" View-process-mode-syntax-table)
642 (modify-syntax-entry ?^ "w" View-process-mode-syntax-table)
643 (modify-syntax-entry ?` "w" View-process-mode-syntax-table)
644 (modify-syntax-entry ?' "w" View-process-mode-syntax-table)
645 (modify-syntax-entry ?~ "w" View-process-mode-syntax-table)
646 (modify-syntax-entry ?Ħ "w" View-process-mode-syntax-table)
647 ))
648
649 (defvar View-process-digit-bindings-send-signal nil
650 "The digits 1 to 9 will be bind to send signal commands, if t.")
651
652 (defvar View-process-mode-mark-map nil
653 "Local subkeymap for View-process-mode buffers.")
654
655 (if View-process-mode-mark-map
656 nil
657 (setq View-process-mode-mark-map (make-keymap))
658 (define-key View-process-mode-mark-map "m" 'View-process-mark-current-line)
659 (define-key View-process-mode-mark-map "u" 'View-process-unmark-current-line)
660 (define-key View-process-mode-mark-map "U" 'View-process-unmark-all)
661 (define-key View-process-mode-mark-map "c"
662 'View-process-mark-childs-in-current-line)
663 (define-key View-process-mode-mark-map "l" 'View-process-reset-last-marks)
664 )
665
666 (defvar View-process-mode-i-map nil
667 "Local subkeymap for View-process-mode buffers.")
668
669 (if View-process-mode-i-map
670 nil
671 (setq View-process-mode-i-map (make-keymap))
672 (define-key View-process-mode-i-map "s" 'View-process-start-itimer)
673 (define-key View-process-mode-i-map "d" 'View-process-delete-itimer)
674 )
675
676 (defvar View-process-mode-comma-map nil
677 "Local subkeymap for View-process-mode buffers.")
678
679 (if View-process-mode-comma-map
680 nil
681 (setq View-process-mode-comma-map (make-keymap))
682 (define-key View-process-mode-comma-map "k"
683 'View-process-send-signal-to-processes-with-mark)
684 (define-key View-process-mode-comma-map "a"
685 'View-process-renice-processes-with-mark))
686
687 (defvar View-process-mode-period-map nil
688 "Local subkeymap for View-process-mode buffers.")
689
690 (if View-process-mode-period-map
691 nil
692 (setq View-process-mode-period-map (make-keymap))
693 (define-key View-process-mode-period-map "f"
694 'View-process-filter-region-by-current-field)
695 (define-key View-process-mode-period-map "l"
696 'View-process-filter-region)
697 (define-key View-process-mode-period-map "s"
698 'View-process-sort-region-by-current-field)
699 (define-key View-process-mode-period-map "r"
700 'View-process-reverse-region)
701 (define-key View-process-mode-period-map "k"
702 'View-process-send-signal-to-processes-in-region)
703 (define-key View-process-mode-period-map "a"
704 'View-process-renice-processes-in-region)
705 (define-key View-process-mode-period-map "v"
706 'View-process-status))
707
708
709 (defvar View-process-mode-map nil
710 "Local keymap for View-process-mode buffers.")
711
712 (if View-process-mode-map
713 nil
714 (setq View-process-mode-map (make-keymap))
715 (define-key View-process-mode-map "q" 'View-process-quit)
716 (define-key View-process-mode-map "V" 'View-process-display-version)
717 (define-key View-process-mode-map " " 'scroll-up)
718 (define-key View-process-mode-map "b" 'scroll-down)
719 (define-key View-process-mode-map "t" 'View-process-toggle-truncate-lines)
720 (define-key View-process-mode-map "u" 'View-process-status-update)
721 (define-key View-process-mode-map "U"
722 'View-process-remove-all-filter-and-sorter)
723 (define-key View-process-mode-map "g" 'revert-buffer)
724 ; (define-key View-process-mode-map "v" 'View-process-status)
725 (define-key View-process-mode-map "v" 'view-processes)
726 (define-key View-process-mode-map "f"
727 'View-process-filter-by-current-field-g)
728 (define-key View-process-mode-map "F"
729 'View-process-filter-output-by-current-field)
730 (define-key View-process-mode-map "l"
731 'View-process-filter-g)
732 (define-key View-process-mode-map "L"
733 'View-process-filter-output)
734 (define-key View-process-mode-map "s"
735 'View-process-sort-by-current-field-g)
736 (define-key View-process-mode-map "S"
737 'View-process-sort-output-by-current-field)
738 (define-key View-process-mode-map "r"
739 'View-process-reverse-g)
740 (define-key View-process-mode-map "R"
741 'View-process-reverse-output)
742 (define-key View-process-mode-map "k"
743 'View-process-send-signal-to-processes-g)
744 (define-key View-process-mode-map "K"
745 'View-process-send-signal-to-process-in-line)
746 (define-key View-process-mode-map "a"
747 'View-process-renice-processes-g)
748 (define-key View-process-mode-map "A"
749 'View-process-renice-process-in-line)
750 ; (define-key View-process-mode-map "k"
751 ; 'View-process-send-signal-to-process)
752 (define-key View-process-mode-map "?"
753 'View-process-which-field-name)
754 (define-key View-process-mode-map "h"
755 'View-process-show-field-names)
756 (define-key View-process-mode-map "e"
757 'View-process-display-emacs-pid)
758 (define-key View-process-mode-map "w" 'View-process-show-pid-and-command)
759 (define-key View-process-mode-map "n" 'View-process-next-field)
760 (define-key View-process-mode-map "p" 'View-process-previous-field)
761 (define-key View-process-mode-map "<" 'View-process-output-start)
762 (define-key View-process-mode-map ">" 'View-process-output-end)
763 (define-key View-process-mode-map [return]
764 'View-process-goto-first-field-next-line)
765 (define-key View-process-mode-map "M" 'View-process-submit-bug-report)
766 (define-key View-process-mode-map "m" View-process-mode-mark-map)
767 (define-key View-process-mode-map "." View-process-mode-period-map)
768 (define-key View-process-mode-map "," View-process-mode-comma-map)
769 (define-key View-process-mode-map "i" View-process-mode-i-map)
770 )
771
772 (defvar View-process-pulldown-menu-name "Processes"
773 "Name of the pulldown menu in the `View-process-mode'.")
774
775 (defvar View-process-pulldown-menu nil
776 "Pulldown menu list for the `View-process-mode'.")
777
778 (defvar View-process-region-menu nil
779 "Menu list for the `View-process-mode', used if a region is active.")
780
781 (defvar View-process-marked-menu nil
782 "Menu list for the `View-process-mode', used if marked lines exists.
783 Not used, if a region is active.")
784
785 (defvar View-process-non-region-menu nil
786 "Menu list for the `View-process-mode', used if a region is not active.")
787
788 (defvar View-process-mode-name "Processes"
789 "Name of the `view process mode'.")
790
791 (defun View-process-make-field-postition-alist-1 ()
792 "Internal function of View-process-make-field-postition-alist."
793 (if (>= (point) View-process-header-end)
794 nil
795 (let (start end)
796 (skip-chars-forward " ")
797 (setq start (current-column))
798 (skip-chars-forward "^ ")
799 (setq end (current-column))
800 (cons (list start end)
801 (View-process-make-field-postition-alist-1))))
802 )
803
804 (defun View-process-make-field-postition-alist ()
805 "Returns an alist with the start and end positions of each field.
806 The list looks like ((start1 end1) (start2 end2) ...)."
807 (save-restriction
808 (widen)
809 (goto-char View-process-header-start)
810 (View-process-make-field-postition-alist-1)))
811
812 (defun View-process-overwrite-chars-in-region (begin end char)
813 "Overwrite region between BEGIN and END with CHAR."
814 (let ((region-begin (if (< begin end) begin end))
815 (region-end (if (> end begin) end begin)))
816 (save-excursion
817 (goto-char region-begin)
818 (while (> region-end (point))
819 (delete-char 1)
820 (View-process-insert-and-inherit char)))))
821
822 (defun View-process-replaces-blanks-in-the-fields-of-this-line
823 (field-position-alist)
824 "Replaces the blanks in the fields of this line with underscores.
825 FIELD-POSITION-ALIST is an alist with the name and the
826 aproximated start and end positions of each field."
827 (if (cdr field-position-alist) ; don't change the last field
828 (let ((field-start (+ (View-process-return-beginning-of-line)
829 (car (car field-position-alist))))
830 (field-end (+ (View-process-return-beginning-of-line)
831 (car (cdr (car field-position-alist)))))
832 (next-field-start (+ (View-process-return-beginning-of-line)
833 (car (car
834 (cdr field-position-alist))))))
835 (goto-char field-start)
836 (skip-chars-forward " ")
837 (if (> (point) field-end)
838 (progn (goto-char field-start)
839 (delete-char 1)
840 (View-process-insert-and-inherit "_"))
841 (let ((search-result (search-forward-regexp "[ ]+" field-end t))
842 (match-beginning nil))
843 (if search-result
844 (if (not (= search-result field-end))
845 (View-process-overwrite-chars-in-region (match-beginning 0)
846 (match-end 0)
847 ?_)
848 (setq match-beginning (match-beginning 0))
849 (if (and (search-forward-regexp "[^ ]+" next-field-start t)
850 (not (eq (point) next-field-start)))
851 (View-process-overwrite-chars-in-region
852 match-beginning
853 (match-beginning 0)
854 ?_))))
855 ))
856 (View-process-replaces-blanks-in-the-fields-of-this-line
857 (cdr field-position-alist)))))
858
859 (defun View-process-replaces-blanks-in-fields ()
860 "Replaces the blanks in fields with underscrores."
861 (save-excursion
862 (save-window-excursion
863 (let ((field-position-alist (View-process-make-field-postition-alist))
864 (read-only buffer-read-only))
865 (setq buffer-read-only nil)
866 (goto-char View-process-output-start)
867 (while (< (point) View-process-output-end)
868 (beginning-of-line)
869 (View-process-replaces-blanks-in-the-fields-of-this-line
870 field-position-alist)
871 (forward-line))
872 (setq buffer-read-only read-only)))))
873
874 (defun View-process-replaces-blanks-in-fields-if-necessary ()
875 "Replaces blanks in fields, if necessary.
876 For that it checks `View-process-field-blanks-already-replaced'."
877 (if View-process-field-blanks-already-replaced
878 nil
879 (View-process-replaces-blanks-in-fields)
880 (setq View-process-field-blanks-already-replaced t)))
881
882 (defun View-process-insert-column-in-region (char
883 column
884 begin
885 end
886 &optional overwrite
887 not-looking-at)
888 "Inserts the CHAR at the COLUMN in the region from BEGIN TO END.
889 The first line must have sufficient columns. No tabs are allowed.
890 If the optional argument OVERWRITE is non nil, then the CHAR
891 overwrites the char in the COLUMN.
892 The optional argument NOT-LOOKING-AT is nil or a regular expression.
893 In the second case the insertation will only be done, if NOT-LOOKING-AT
894 isn't a string starting at the column."
895 (save-excursion
896 (let ((no-of-lines (count-lines begin end))
897 (line 1))
898 (goto-char begin)
899 (beginning-of-line)
900 (while (<= line no-of-lines)
901 (forward-char column)
902 (if (not (= (current-column) column))
903 (View-process-insert-and-inherit
904 (make-string (- column (current-column)) ? )))
905 (if overwrite
906 (progn
907 (delete-char -1)
908 (View-process-insert-and-inherit char))
909 (if (or (not not-looking-at)
910 (not (looking-at not-looking-at)))
911 (progn
912 (View-process-insert-and-inherit char)
913 (forward-char -1)
914 )))
915 (forward-line 1)
916 (setq line (1+ line))))))
917
918 (defun View-process-insert-blank-in-column (column
919 &optional overwrite
920 not-looking-at)
921 "Inserts a blank in all lines of the ps output in column COLUMN.
922 If OVERWRITE is non nil, then it overwrites the old column char.
923 The optional argument NOT-LOOKING-AT is nil or a regular expression.
924 In the second case the insertation will only be done, if NOT-LOOKING-AT
925 isn't a string starting at the column."
926 (let ((read-only buffer-read-only))
927 (setq buffer-read-only nil)
928 (View-process-insert-column-in-region ?
929 column
930 View-process-header-start
931 View-process-output-end
932 overwrite
933 not-looking-at)
934 (setq View-process-output-end (point-max))
935 (setq buffer-read-only read-only)))
936
937 ;(defun View-process-insert-blanks-at-line-start ()
938 ; "Inserts some blanks at the beginning of each output line.
939 ;This space is used for the marks."
940 ; (save-excursion
941 ; (goto-char View-process-header-start)
942 ; (insert "m ")
943 ; (forward-line)
944 ; (while (< (point) View-process-output-end)
945 ; (insert "_ ")
946 ; (forward-line))))
947
948 (defun View-process-insert-blanks-at-line-start ()
949 "Inserts some blanks at the beginning of each output line.
950 This space is used for the marks."
951 (save-excursion
952 (goto-char View-process-output-end)
953 (forward-line -1)
954 (while (> (point) View-process-header-start)
955 (insert "_ ")
956 (forward-line -1))
957 (insert "m ")))
958
959 (defun View-process-return-position (field-name position-descriptor)
960 "Returns a position deppending on the FIELD-NAME and the POSITION-DESCRIPTOR.
961 The POSITION-DESCRIPTOR must be one of the 4 values: `in-front',
962 `in-front-successor', `behind' and `behind-predecessor'.
963 If the FIELD-NAME isn't in the header-line, then it return nil."
964 (save-excursion
965 (goto-char View-process-header-start)
966 (beginning-of-line)
967 (if (search-forward field-name (View-process-return-end-of-line) t)
968 (cond ((eq position-descriptor 'behind-predecessor)
969 (goto-char (match-beginning 0))
970 (skip-chars-backward " ")
971 (current-column))
972 ((eq position-descriptor 'behind)
973 (current-column))
974 ((eq position-descriptor 'in-front)
975 (goto-char (match-beginning 0))
976 (current-column))
977 ((eq position-descriptor 'in-front-successor)
978 (skip-chars-forward " ")
979 (current-column))))))
980
981 (defun View-process-split-merged-fields (insert-blank-alist)
982 "Tries to split merged fields.
983 At the moment this is done by inserting a blank between fields,
984 which are often merged together. The fields are determined by the
985 alist INSERT-BLANK-ALIST."
986 (cond (insert-blank-alist
987 (let ((position (View-process-return-position
988 (car (car insert-blank-alist))
989 (car (cdr (car insert-blank-alist))))))
990 (if position
991 (View-process-insert-blank-in-column
992 (+ position
993 (car (cdr (cdr (car insert-blank-alist)))))
994 nil
995 "[^ ][^ ]? ")))
996 (View-process-split-merged-fields (cdr insert-blank-alist)))
997 (t)))
998
999 (defun View-process-replace-colons-with-blanks ()
1000 "Replaces colons with blanks, if a colon is also in the header line.
1001 This fixes the output of the IRIX ps on SGI's."
1002 (save-excursion
1003 (goto-char View-process-header-start)
1004 (while (search-forward ":" (View-process-return-end-of-line) t)
1005 (View-process-insert-blank-in-column (current-column)
1006 t))))
1007
1008 (defun View-process-mode ()
1009 "Mode for displaying and killing processes.
1010 The mode has the following keybindings:
1011 \\{View-process-mode-map}.
1012
1013 The first column of each outputline will be used to display marked lines.
1014 The following mark signs are possible (one can change them by changing
1015 the variables in the second column of the following table):
1016
1017 Sign Variable Description
1018 _ View-process-no-mark Process isn't marked
1019 * View-process-single-line-mark The normal mark.
1020 C View-process-child-line-mark Marked as a child of P (see also P)
1021 K View-process-signal-line-mark Used during signaling
1022 N View-process-renice-line-mark Used during renicing
1023 P View-process-parent-line-mark Marked as the parent of P (see also C)
1024 s View-process-signaled-line-mark Process was signaled or reniced.
1025
1026 The signal and renice commands are working also on marked processes!"
1027 ; (kill-all-local-variables)
1028 (make-local-variable 'revert-buffer-function)
1029 (setq revert-buffer-function 'View-process-revert-buffer)
1030 (View-process-change-display-type View-process-display-with-2-windows)
1031 (use-local-map View-process-mode-map)
1032 (set-syntax-table View-process-mode-syntax-table)
1033 (setq major-mode 'View-process-mode
1034 mode-name View-process-mode-name)
1035 ; (View-process-replaces-blanks-in-fields)
1036 (setq View-process-deleted-lines nil)
1037 (View-process-call-sorter-and-filter View-process-actual-sorter-and-filter)
1038 (setq truncate-lines View-process-truncate-lines)
1039 (View-process-install-pulldown-menu)
1040 ; (View-process-install-mode-motion)
1041 (View-process-hide-header (and View-process-display-with-2-windows
1042 View-process-hide-header))
1043 (View-process-install-font-lock)
1044 (View-process-install-mode-motion)
1045 (run-hooks 'View-process-mode-hook)
1046 )
1047
1048 (defun View-process-build-field-name-list ()
1049 "Returns an alist with the field names and the field number.
1050 The list looks like ((\"USER\" 1) (\"PID\" 2) (\"COMMAND\" 3))."
1051 (goto-char View-process-header-start)
1052 (forward-word 1)
1053 (setq View-process-field-names '())
1054 (let ((i 1))
1055 (while (<= (point) View-process-header-end)
1056 (setq View-process-field-names (cons (list (current-word) i)
1057 View-process-field-names))
1058 (setq i (1+ i))
1059 (forward-word 1))))
1060
1061 (defun View-process-field-name-exists-p (field-name)
1062 "Returns non nil, if the field FIELD_NAME exists."
1063 (assoc field-name View-process-field-names))
1064
1065 (defun View-process-translate-field-name-to-position (field-name)
1066 "Returns the position of the field with the name FIELD-NAME."
1067 (car (cdr (assoc field-name View-process-field-names)))
1068 )
1069
1070 (defun View-process-translate-field-position-to-name (position)
1071 "Returns the field name of the field with the position POSITION."
1072 (if (> position View-process-max-fields)
1073 (car (View-process-assoc-2th View-process-max-fields
1074 View-process-field-names))
1075 (car (View-process-assoc-2th position View-process-field-names))
1076 ))
1077
1078 (defun View-process-get-system-type-from-host-list (host-name)
1079 "Returns nil, or the system type of the host with the name HOST-NAME."
1080 (car (cdr (assoc host-name View-process-host-names-and-system-types))))
1081
1082 (defun View-process-put-system-type-in-host-list (host-name system-type)
1083 "Puts the HOST-NAME and the SYSTEM-TYPE in a special host list.
1084 The list has the name `View-process-host-names-and-system-types'."
1085 (if (not (member (list host-name system-type)
1086 View-process-host-names-and-system-types))
1087 (setq View-process-host-names-and-system-types
1088 (cons (list host-name system-type)
1089 View-process-host-names-and-system-types))))
1090
1091 (defun View-process-bsd-or-system-v (&optional remote-host)
1092 "This function determines, if the system is a BSD or a System V.
1093 For that it uses the ps command.
1094 If REMOTE-HOST is non nil, then the system of the REMOTE-HOST will
1095 be tested."
1096 (if remote-host
1097 (if (eq 0 (call-process View-process-rsh-command
1098 nil
1099 nil
1100 nil
1101 remote-host
1102 (concat View-process-status-command
1103 " "
1104 "-dfj")))
1105 "system-v"
1106 "bsd")
1107 (if (eq 0 (call-process View-process-status-command
1108 nil
1109 nil
1110 nil
1111 "-dfj"))
1112 "system-v"
1113 "bsd")))
1114
1115 (defun View-process-program-exists-p (program &optional remote-host)
1116 "Returns t, if the PROGRAM exists.
1117 If REMOTE_HOST is non nil, then the program will be searched remote
1118 on that host."
1119 (if remote-host
1120 (or (= 0 (call-process View-process-rsh-command
1121 nil
1122 nil
1123 nil
1124 remote-host
1125 (concat View-process-test-command
1126 " "
1127 View-process-test-switches
1128 " "
1129 program)))
1130 (= 0 (call-process View-process-rsh-command
1131 nil
1132 nil
1133 nil
1134 remote-host
1135 (concat View-process-test-command
1136 " "
1137 View-process-test-switches
1138 " "
1139 "/bin/"
1140 program)))
1141 (= 0 (call-process View-process-rsh-command
1142 nil
1143 nil
1144 nil
1145 remote-host
1146 (concat View-process-test-command
1147 " "
1148 View-process-test-switches
1149 " "
1150 "/usr/bin/"
1151 program))))
1152 (or (= 0 (call-process View-process-test-command
1153 nil
1154 nil
1155 nil
1156 View-process-test-switches
1157 program))
1158 (= 0 (call-process View-process-test-command
1159 nil
1160 nil
1161 nil
1162 View-process-test-switches
1163 (concat "/bin/" program)))
1164 (= 0 (call-process View-process-test-command
1165 nil
1166 nil
1167 nil
1168 View-process-test-switches
1169 (concat "/usr/bin/" program))))))
1170
1171 (defun View-process-search-system-type-in-system-list-1 (system-type
1172 system-list)
1173 "Internal function of `View-process-search-system-type-in-system-list'."
1174 (cond ((not system-list) nil)
1175 ((equal system-type (car (car system-list)))
1176 (cons (car system-list)
1177 (View-process-search-system-type-in-system-list-1
1178 system-type
1179 (cdr system-list))))
1180 (t (View-process-search-system-type-in-system-list-1 system-type
1181 (cdr system-list))
1182 )))
1183
1184 (defun View-process-search-system-type-in-system-list (system-type system-list)
1185 "Searches the SYSTEM-TYPE in SYSTEM-LIST.
1186 It returns the entry or nil, if the SYSTEM-TYPE isn't in the list.
1187 If more then one entry with the same SYSTEM-TYPE are found, then the
1188 version number is also checked. If the version number isn't in the
1189 list, then nil is returned."
1190 (let ((system-type-entries (View-process-search-system-type-in-system-list-1
1191 (car system-type)
1192 system-list)))
1193 (if system-type-entries
1194 (if (= 1 (length system-type-entries))
1195 (car system-type-entries)
1196 (View-process-assoc-2th (car (cdr system-type)) system-type-entries))
1197 nil)))
1198
1199
1200 (defun View-process-generalize-system-type (system-type &optional remote-host)
1201 "Generalize the SYSTEM-TYPE.
1202 Determines, if the system is in the `View-process-specific-system-list'
1203 and if it is a BSD or a System V system. It returns a list which looks
1204 like the following: (<system-type> <version-no> <bsd-or-system-v>).
1205 The elements <system-type> and <version-no> are set to nil, if the
1206 <system-type> isn't in the `View-process-specific-system-list'. In that
1207 case the third element (<bsd-or-system-v>) is determined with the help
1208 of the ps output. if REMOTE-HOST is non nil, the the ps command to check
1209 the system type is run on the remote host REMOTE-HOST."
1210 (let ((new-system-type (View-process-search-system-type-in-system-list
1211 system-type
1212 View-process-specific-system-list)))
1213 (if new-system-type
1214 new-system-type
1215 (list nil nil (View-process-bsd-or-system-v)))))
1216
1217 (defun View-process-get-local-system-type ()
1218 "Returns the system type of the local host."
1219 (let ((system-type (View-process-get-system-type-from-host-list
1220 (system-name))))
1221 (if (not system-type) ; t, if the host isn't in the list
1222 (progn
1223 (if (View-process-program-exists-p View-process-uname-command)
1224 (save-excursion
1225 (let ((buffer (generate-new-buffer "*system-type*")))
1226 (call-process View-process-uname-command
1227 nil
1228 buffer
1229 nil
1230 View-process-uname-switches)
1231 (set-buffer buffer)
1232 (forward-line -1)
1233 (setq system-type (downcase (current-word)))
1234 (forward-word 2)
1235 (setq system-type
1236 (list system-type (downcase (current-word))))
1237 (kill-buffer buffer)
1238 ;; determine, if the system is in the
1239 ;; View-process-specific-system-list and if it is
1240 ;; a BSD or a System V system;
1241 ;; The system type will be set to nil,
1242 ;; if it isn't in the list
1243 (setq system-type (View-process-generalize-system-type
1244 system-type))
1245 ))
1246 (setq system-type (list nil nil (View-process-bsd-or-system-v))))
1247 (View-process-put-system-type-in-host-list (system-name)
1248 system-type)
1249 system-type)
1250 system-type)))
1251
1252 (defun View-process-get-remote-system-type ()
1253 "Returns the system type of the remote host `View-process-remote-host'."
1254 (let ((system-type (View-process-get-system-type-from-host-list
1255 View-process-remote-host)))
1256 (if system-type ; nil, if the host isn't in the list
1257 system-type
1258 (if (View-process-program-exists-p View-process-uname-command
1259 View-process-remote-host)
1260 (let ((buffer (generate-new-buffer "*system-type*")))
1261 (save-excursion
1262 (call-process View-process-rsh-command
1263 nil
1264 buffer
1265 nil
1266 View-process-remote-host
1267 (concat View-process-uname-command
1268 " "
1269 View-process-uname-switches))
1270 (set-buffer buffer)
1271 (forward-line -1)
1272 (setq system-type (downcase (current-word)))
1273 (forward-word 2)
1274 (setq system-type
1275 (list system-type (downcase (current-word))))
1276 (kill-buffer buffer)
1277 ;; determine, if the system is in the
1278 ;; View-process-specific-system-list and if it is
1279 ;; a BSD or a System V system;
1280 ;; The system type will be set to nil,
1281 ;; if it isn't in the list
1282 (setq system-type (View-process-generalize-system-type
1283 system-type
1284 View-process-remote-host))
1285 ))
1286 (setq system-type (list nil nil (View-process-bsd-or-system-v
1287 View-process-remote-host))))
1288 (View-process-put-system-type-in-host-list View-process-remote-host
1289 system-type)
1290 system-type)))
1291
1292 (defun View-process-get-system-type ()
1293 "Returns the type of the system on which ps was executed."
1294 (if View-process-remote-host
1295 (View-process-get-remote-system-type)
1296 (View-process-get-local-system-type)
1297 ))
1298
1299 (defun View-process-get-kill-signal-list (system-type)
1300 "Returns a kill signal list for the SYSTEM-TYPE."
1301 (if (= 3 (length system-type))
1302 (if (string= "bsd" (nth 2 system-type))
1303 (if View-process-kill-signals-bsd
1304 View-process-kill-signals-bsd
1305 View-process-kill-signals-general)
1306 (if View-process-kill-signals-system-v
1307 View-process-kill-signals-system-v
1308 View-process-kill-signals-general))
1309 (if (eval (nth 4 system-type))
1310 (eval (nth 4 system-type))
1311 (if (string= "bsd" (nth 2 system-type))
1312 (if View-process-kill-signals-bsd
1313 View-process-kill-signals-bsd
1314 View-process-kill-signals-general)
1315 (if View-process-kill-signals-system-v
1316 View-process-kill-signals-system-v
1317 View-process-kill-signals-general)))))
1318
1319 (defun View-process-get-field-name-description-list (system-type)
1320 "Returns a field name description list for the SYSTEM-TYPE.
1321 It returns nil, if no system specific list exists."
1322 (if (= 3 (length system-type))
1323 (if (string= "bsd" (nth 2 system-type))
1324 (if View-process-field-name-descriptions-bsd
1325 View-process-field-name-descriptions-bsd)
1326 (if View-process-field-name-descriptions-system-v
1327 View-process-field-name-descriptions-system-v))
1328 (if (eval (nth 3 system-type))
1329 (eval (nth 3 system-type))
1330 (if (string= "bsd" (nth 2 system-type))
1331 (if View-process-field-name-descriptions-bsd
1332 View-process-field-name-descriptions-bsd)
1333 (if View-process-field-name-descriptions-system-v
1334 View-process-field-name-descriptions-system-v)))))
1335
1336 (defun View-process-init-internal-variables (use-last-sorter-and-filer)
1337 "Init internal variables.
1338 (without `View-process-header-start').
1339 If USE-LAST-SORTER-AND-FILER is t, then
1340 'View-process-actual-sorter-and-filter' will not be changed"
1341 ;; don't replace blanks now
1342 (setq View-process-field-blanks-already-replaced t)
1343
1344 (goto-char View-process-header-start)
1345 (end-of-line)
1346 (setq View-process-header-end (point))
1347 ;; (newline)
1348 (forward-line)
1349 (setq View-process-output-start (point))
1350 (setq View-process-output-end (point-max))
1351 (goto-char View-process-header-end)
1352 (forward-word -1)
1353 (setq View-process-max-fields (View-process-current-field-number))
1354 (View-process-build-field-name-list)
1355 (setq View-process-system-type (View-process-get-system-type))
1356 (setq View-process-kill-signals (View-process-get-kill-signal-list
1357 View-process-system-type))
1358 (setq View-process-field-name-descriptions
1359 (View-process-get-field-name-description-list View-process-system-type)
1360 )
1361 ;; Replace the blanks the next time if it is necessary
1362 (setq View-process-field-blanks-already-replaced nil)
1363 (if (not use-last-sorter-and-filer)
1364 (setq View-process-actual-sorter-and-filter
1365 View-process-sorter-and-filter))
1366
1367 (if View-process-pid-mark-alist
1368 (progn
1369 (setq View-process-last-pid-mark-alist View-process-pid-mark-alist)
1370 (setq View-process-pid-mark-alist nil)))
1371 )
1372
1373 (defun View-process-insert-short-key-descriptions ()
1374 "Insert short key descriptions at the current point.
1375 If `View-process-display-short-key-descriptions' is nil, then
1376 nothing will be inserted."
1377 (if View-process-display-short-key-descriptions
1378 (let ((local-map (current-local-map)))
1379 (use-local-map View-process-mode-map)
1380 (insert
1381 (substitute-command-keys
1382 (concat
1383 " \\[view-processes]: new output "
1384 "\\[View-process-status]: new output with new options "
1385 " \\[revert-buffer]: update output \n"
1386 " \\[View-process-filter-by-current-field-g]: field filter "
1387 "\\[View-process-filter-g]: line filter "
1388 "\\[View-process-sort-by-current-field-g]: sort "
1389 "\\[View-process-reverse-g]: reverse "
1390 "\\[View-process-send-signal-to-processes-g]: send signal "
1391 "\\[View-process-quit]: quit\n")))
1392 (use-local-map local-map))))
1393
1394 (defun View-process-insert-uptime (&optional remote-host)
1395 "Inserts uptime information at the current point.
1396 if `View-process-display-uptime' is nil, then nothing will be inserted.
1397 If REMOTE-HOST is non nil, then its the name of the remote host."
1398 (if View-process-display-uptime
1399 (progn
1400 ; (newline)
1401 (if remote-host
1402 (call-process View-process-rsh-command
1403 nil
1404 t
1405 nil
1406 remote-host
1407 View-process-uptime-command)
1408 (call-process View-process-uptime-command
1409 nil
1410 t
1411 nil)))))
1412
1413 (defun View-process-insert-title-lines (command-switches
1414 remote-host
1415 use-last-sorter-and-filter)
1416 "Insert the title lines in the output lines.
1417 REMOTE-HOST is nil or the name of the host on which the
1418 ps command was executed. USE-LAST-SORTER-AND-FILTER determines, if
1419 the last sorter and filter (from `View-process-actual-sorter-and-filter')
1420 are used."
1421 (insert (or remote-host (system-name) "")
1422 ;;(getenv "HOST") (getenv "HOSTNAME") "")
1423 ", "
1424 (current-time-string)
1425 ", "
1426 View-process-status-command
1427 " "
1428 command-switches
1429 "\n")
1430 (View-process-insert-uptime remote-host)
1431 (View-process-insert-short-key-descriptions)
1432 (if (or (and use-last-sorter-and-filter
1433 View-process-actual-sorter-and-filter)
1434 View-process-sorter-and-filter)
1435 (insert
1436 "This output is filtered! Look at `View-process-sorter-and-filter'.\n"))
1437 (newline 1)
1438 (setq View-process-ps-header-window-size
1439 (+ View-process-ps-header-window-offset
1440 (count-lines (point-min) (point))
1441 (if (and (View-process-xemacs-p)
1442 (not (View-process-lemacs-p))
1443 View-process-header-mode-line-off)
1444 -1
1445 0))))
1446
1447 (defun View-process-search-header-line-1 (header-dectection-list
1448 no-error-message)
1449 "Internal funtion of `View-process-search-header-line'."
1450 (cond (header-dectection-list
1451 (goto-char View-process-header-start)
1452 (if (search-forward (car header-dectection-list) nil t)
1453 (setq View-process-header-start
1454 (View-process-return-beginning-of-line))
1455 (View-process-search-header-line-1 (cdr header-dectection-list)
1456 no-error-message)))
1457 (t (setq mode-motion-hook nil) ; otherwise emacs hangs
1458 (if no-error-message
1459 nil
1460 (error (concat "ERROR: No header line detected! "
1461 "Look at View-process-header-line-detection-list!")
1462 )))))
1463
1464
1465 (defun View-process-search-header-line (&optional no-error-message)
1466 "Function searches the headerline and sets `View-process-header-start'.
1467 The header line must have at least one of the words of the list
1468 `View-process-header-line-detection-list'.
1469 If NO-ERROR-MESSAGE is t and no header-line is found, then only
1470 nil (without an error message) will be returned."
1471 (save-excursion
1472 (View-process-search-header-line-1 View-process-header-line-detection-list
1473 no-error-message)
1474 ))
1475
1476 (defun View-process-save-position ()
1477 "Saves the current line and column in a cons cell and returns it."
1478 (save-restriction
1479 (widen)
1480 (if (< View-process-header-start (point-max))
1481 (cons (- (count-lines (or View-process-header-start (point-min))
1482 (point))
1483 (if (= 0 (current-column))
1484 0
1485 1))
1486 (current-column))
1487 nil)))
1488
1489 (defun View-process-goto-position (position)
1490 "Sets the point to the POSITION.
1491 POSITION is a cons cell with a linenumber and a column."
1492 (if position
1493 (save-restriction
1494 (widen)
1495 (goto-char View-process-header-start)
1496 (forward-line (car position))
1497 (move-to-column (cdr position) t)
1498 ; (setq temporary-goal-column (cdr position)) ; doesn't work :-(
1499 )))
1500
1501 (defun View-process-status (command-switches
1502 &optional remote-host
1503 use-last-sorter-and-filter)
1504 "Prints a list with processes in the buffer `View-process-buffer-name'.
1505 COMMAND-SWITCHES is a string with the command switches (ie: -aux).
1506 IF the optional argument REMOTE-HOST is given, then the command will
1507 be executed on the REMOTE-HOST. If an prefix arg is given, then the
1508 function asks for the name of the remote host.
1509 If USE-LAST-SORTER-AND-FILTER is t, then the last sorter and filter
1510 commands are used. Otherwise the sorter and filter from the list
1511 'View-process-sorter-and-filter' are used."
1512 (interactive
1513 (let ((View-process-stop-motion-help t))
1514 (list
1515 (read-string "Command switches: "
1516 (or View-process-status-last-command-switches
1517 (if (bufferp (get-buffer View-process-buffer-name))
1518 (cdr
1519 (assoc
1520 'View-process-status-last-command-switches
1521 (buffer-local-variables
1522 (get-buffer View-process-buffer-name)))))
1523 (if (string= "bsd" (View-process-bsd-or-system-v))
1524 View-process-status-command-switches-bsd
1525 View-process-status-command-switches-system-v))
1526 'View-process-status-history)
1527 (if current-prefix-arg
1528 (setq View-process-remote-host
1529 (read-string "Remote host name: "
1530 View-process-remote-host
1531 'View-process-remote-host-history))
1532 (setq View-process-remote-host nil)))))
1533 (View-process-save-old-window-configuration)
1534 (let ((buffer (get-buffer-create View-process-buffer-name))
1535 (position nil))
1536 ; (point-after-ps nil))
1537 (if (window-minibuffer-p (selected-window))
1538 (set-buffer buffer)
1539 (switch-to-buffer buffer))
1540
1541 ;; set switches for the next view process command
1542 (setq View-process-status-last-command-switches command-switches)
1543 (if (string= "bsd" (View-process-bsd-or-system-v))
1544 (setq View-process-status-command-switches-bsd command-switches)
1545 (setq View-process-status-command-switches-system-v command-switches))
1546
1547 (setq buffer-read-only nil)
1548 (if (not (= (point-min) (point-max)))
1549 (progn
1550 (setq position (View-process-save-position))
1551 ; (setq point-after-ps (point-min))
1552 ; (setq point-after-ps (point))
1553 (erase-buffer)))
1554 (View-process-insert-title-lines command-switches
1555 remote-host
1556 use-last-sorter-and-filter)
1557 (setq View-process-header-start (point))
1558 (if remote-host
1559 (call-process View-process-rsh-command
1560 nil
1561 t
1562 t
1563 remote-host
1564 (concat View-process-status-command
1565 " "
1566 command-switches))
1567 (call-process View-process-status-command
1568 nil
1569 t
1570 t
1571 command-switches))
1572 (View-process-search-header-line)
1573 (setq View-process-output-end (point-max))
1574 (View-process-replace-colons-with-blanks)
1575 (View-process-insert-blanks-at-line-start)
1576 (View-process-split-merged-fields View-process-insert-blank-alist)
1577 (View-process-init-internal-variables use-last-sorter-and-filter)
1578 (View-process-highlight-header-line)
1579 (goto-char View-process-output-start)
1580 (View-process-goto-position position)
1581 ; (goto-char (cond ((> point-after-ps (point-max)) (point-max))
1582 ; ((= point-after-ps (point-min)) View-process-output-start)
1583 ; ((< point-after-ps View-process-output-start)
1584 ; View-process-output-start)
1585 ; (t point-after-ps)))
1586 (setq buffer-read-only t)
1587 (let ((View-process-stop-motion-help t))
1588 ; (setq View-process-stop-motion-help t)
1589 (View-process-mode)
1590 ; (setq View-process-stop-motion-help nil)
1591 ; (View-process-redraw) ; only the first time (fixes an Emacs 19 bug)
1592 )
1593 ))
1594
1595 (defun View-process-status-update ()
1596 "Runs the `View-process-status' with the last switches
1597 and sorter and filter commands."
1598 (interactive)
1599 (if View-process-status-last-command-switches
1600 (View-process-status View-process-status-last-command-switches
1601 View-process-remote-host
1602 t)
1603 (error "ERROR: No view process buffer exists for update!")))
1604
1605 (defun view-processes (&optional remote-host)
1606 "Prints a list with processes in the buffer `View-process-buffer-name'.
1607 It calls the function `View-process-status' with default switches.
1608 As the default switches on BSD like systems the value of the variable
1609 `View-process-status-command-switches-bsd' is used.
1610 On System V like systems the value of the variable
1611 `View-process-status-command-switches-system-v' is used.
1612 IF the optional argument REMOTE-HOST is given, then the command will
1613 be executed on the REMOTE-HOST. If an prefix arg is given, then the
1614 function asks for the name of the remote host."
1615 (interactive
1616 (let ((View-process-stop-motion-help t))
1617 (list (if current-prefix-arg
1618 (setq View-process-remote-host
1619 (read-string "Remote host name: "
1620 View-process-remote-host
1621 'View-process-remote-host-history))
1622 (setq View-process-remote-host nil)))))
1623 (if (string= "bsd" (nth 2 (View-process-get-system-type)))
1624 (View-process-status View-process-status-command-switches-bsd
1625 View-process-remote-host)
1626 (View-process-status View-process-status-command-switches-system-v
1627 remote-host)))
1628
1629 ;;; itimer functions (to repeat the ps output)
1630
1631 (defun View-process-status-itimer-function ()
1632 "Itimer function for updating the ps output."
1633 (save-excursion
1634 (save-window-excursion
1635 (View-process-status-update)))
1636 ;;(View-process-start-itimer)
1637 )
1638
1639
1640 ;;; help functions
1641
1642 (defun View-process-show-pid-and-command-or-field-name ()
1643 "Displays the pid and the command of the current line or the field name.
1644 If the point is at a blank, then the pid and the command of the current
1645 line are displayed. Otherwise the name of the field and its description
1646 are displayed."
1647 (interactive)
1648 (if (looking-at " ")
1649 (View-process-show-pid-and-command)
1650 (View-process-which-field-name)))
1651
1652 (defun View-process-show-pid-and-command ()
1653 "Displays the pid and the command of the current line.
1654 It assumes, that the command is displayed at the end of the line."
1655 (interactive)
1656 (if (>= (point) View-process-output-start)
1657 (message "PID= %s, %s"
1658 (View-process-get-pid-from-current-line)
1659 (View-process-get-field-value-from-current-line
1660 View-process-max-fields
1661 View-process-max-fields))))
1662
1663 (defun View-process-show-field-names ()
1664 "Displays the name(s) of the ps output field(s).
1665 If the point is at a blank, then the header line with all field names
1666 is displayed. Otherwise only the name of the field at the point is
1667 displayed."
1668 (interactive)
1669 (if (looking-at " ")
1670 (View-process-show-header-line)
1671 (View-process-which-field-name)))
1672
1673 (defun View-process-show-header-line ()
1674 "Displays the header line in the buffer at the current line."
1675 (interactive)
1676 (save-window-excursion
1677 (let ((header-line (save-restriction
1678 (widen)
1679 (concat
1680 (buffer-substring View-process-header-start
1681 View-process-header-end)
1682 "\n"))))
1683 (momentary-string-display header-line
1684 (View-process-return-beginning-of-line)))))
1685
1686 (defun View-process-which-field-name ()
1687 "Displays the name of the field under the point in the echo area."
1688 (interactive)
1689 (if (>= (point) View-process-header-start)
1690 (let ((field-name (View-process-translate-field-position-to-name
1691 (View-process-current-field-number))))
1692 (message
1693 (View-process-replace-in-string
1694 "%"
1695 "%%"
1696 (concat field-name
1697 ": "
1698 (View-process-get-field-name-description field-name)))))))
1699
1700 (defun View-process-get-field-name-description (field-name)
1701 "Returns a string with a desciption of the ps output field FIELD-NAME."
1702 (let ((description
1703 (or (car (cdr (assoc field-name
1704 View-process-field-name-descriptions)))
1705 (car (cdr (assoc field-name
1706 View-process-field-name-descriptions-general))))
1707 ))
1708 (if (stringp description)
1709 description
1710 (concat (car description)
1711 (View-process-get-value-description
1712 (View-process-get-field-value-from-current-line
1713 (View-process-translate-field-name-to-position field-name)
1714 View-process-max-fields)
1715 (cdr description))))))
1716
1717 (defun View-process-get-value-description (values value-descriptions)
1718 "Returns a string with the description of the VALUES.
1719 VALUE-DESCRIPTIONS is an alist with the possible values and its
1720 descriptions."
1721 (cond ((string= values "") "")
1722 ((or (eq (aref values 0) ?_) (eq (aref values 0) ? ))
1723 (View-process-get-value-description (substring values 1)
1724 value-descriptions))
1725 (t (concat
1726 (car
1727 (cdr
1728 (assoc
1729 (substring values 0 (string-match "[ _]" values))
1730 value-descriptions)))
1731 (if (string-match "[ _]" values)
1732 (View-process-get-value-description
1733 (substring values (string-match "[ _]" values))
1734 value-descriptions)
1735 "")))))
1736
1737
1738 ;;; sort functions
1739
1740 (defun View-process-current-field-number ()
1741 "Returns the field number of the point.
1742 The functions fails with an error message, if the character under
1743 the point is a blank."
1744 (View-process-replaces-blanks-in-fields-if-necessary)
1745 (save-excursion
1746 (if (looking-at " ")
1747 (error "Point is on a blank and not in a field!")
1748 (if (and (eq (point) (point-max))
1749 (eq (current-column) 0))
1750 (error "Point is not in a field!")
1751 (let ((field-point (point))
1752 (i 0))
1753 (beginning-of-line)
1754 (skip-chars-forward " ")
1755 (while (>= field-point (point))
1756 (setq i (1+ i))
1757 (skip-chars-forward "^ ")
1758 (skip-chars-forward " "))
1759 i)))))
1760
1761 (defun View-process-sort-fields-in-region (field
1762 beg
1763 end
1764 &optional sort-function)
1765 "Sort lines in region by the ARGth field of each line.
1766 Fields are separated by whitespace and numbered from 1 up.
1767 With a negative arg, sorts by the ARGth field counted from the right.
1768 BEG and END specify region to sort.
1769 If the optional SORT-FUNCTION is nil, then the region is at first
1770 sorted with the function `sort-fields' and then with the function
1771 `sort-float-fields'. Otherwise a sort function like `sort-fields'
1772 must be specified."
1773 (let ((position (View-process-save-position))
1774 ; (point (point)) ;; that's, because save-excursion
1775 ; (column (current-column)) ;; doesn't work :-(
1776 (field-no (if (< field View-process-max-fields)
1777 field
1778 View-process-max-fields)))
1779 (if sort-function
1780 (eval (list sort-function field-no beg end))
1781 (sort-fields field-no beg end)
1782 (sort-float-fields field-no beg end))
1783 (View-process-goto-position position)))
1784 ; (goto-char point)
1785 ; (goto-char (+ point (- column (current-column))))))
1786
1787 (defun View-process-remove-sorter (sorter alist)
1788 "Removes the SORTER entry from the ALIST."
1789 (cond ((not alist) nil)
1790 ((eq sorter (car (car alist))) (cdr alist))
1791 (t (cons (car alist)
1792 (View-process-remove-sorter sorter (cdr alist))))))
1793
1794 (defun View-process-sort-output-by-field (field-name
1795 &optional dont-remember)
1796 "Sort the ps output by the field FIELD-NAME.
1797 If DONT-REMEMBER is t, then the filter command isn't inserted
1798 in the `View-process-actual-sorter-and-filter' list."
1799 (interactive
1800 (let ((View-process-stop-motion-help t))
1801 (list
1802 (completing-read "Field Name for sorting: "
1803 View-process-field-names
1804 nil
1805 t
1806 (car View-process-field-name-history)
1807 View-process-field-name-history))))
1808 (setq buffer-read-only nil)
1809 (View-process-sort-fields-in-region
1810 (View-process-translate-field-name-to-position field-name)
1811 View-process-output-start
1812 View-process-output-end)
1813 (setq buffer-read-only t)
1814 (if (not dont-remember)
1815 (setq View-process-actual-sorter-and-filter
1816 (append (View-process-remove-sorter
1817 'reverse
1818 (View-process-remove-sorter
1819 'sort
1820 View-process-actual-sorter-and-filter))
1821 (list (list 'sort field-name))))))
1822
1823 (defun View-process-sort-by-current-field-g ()
1824 "Sort the ps output by the field under the point.
1825 It is a generic interface to `View-process-sort-region-by-current-field'
1826 and `View-process-sort-output-by-current-field'.The first will be called
1827 if a region is active and the other one if not.
1828 With a prefix arg, it uses the NTH field instead of the current one."
1829 (interactive)
1830 (if (View-process-region-active-p)
1831 (call-interactively 'View-process-sort-region-by-current-field)
1832 (call-interactively 'View-process-sort-output-by-current-field)))
1833
1834 (defun View-process-sort-output-by-current-field (&optional nth dont-remember)
1835 "Sort the whole ps output by the field under the point.
1836 With a prefix arg, it uses the NTH field instead of the current one.
1837 If DONT-REMEMBER is t, then the filter command isn't inserted
1838 in the `View-process-actual-sorter-and-filter' list."
1839 (interactive "P")
1840 (let ((field-number (if nth
1841 (if (and (>= nth 1) (<= nth View-process-max-fields))
1842 nth
1843 (error "ERROR: Wrong field number!"))
1844 (View-process-current-field-number))))
1845 (setq buffer-read-only nil)
1846 (View-process-sort-fields-in-region field-number
1847 View-process-output-start
1848 View-process-output-end)
1849 (setq buffer-read-only t)
1850 (if (not dont-remember)
1851 (setq View-process-actual-sorter-and-filter
1852 (append (View-process-remove-sorter
1853 'reverse
1854 (View-process-remove-sorter
1855 'sort
1856 View-process-actual-sorter-and-filter))
1857 (list
1858 (list 'sort
1859 (View-process-translate-field-position-to-name
1860 field-number))))))))
1861
1862 (defun View-process-sort-region-by-current-field (&optional nth)
1863 "Sort the region by the field under the point.
1864 With a prefix arg, it uses the NTH field instead of the current one."
1865 (interactive "P")
1866 (let ((field-number (if nth
1867 (if (and (>= nth 1) (<= nth View-process-max-fields))
1868 nth
1869 (error "ERROR: Wrong field number!"))
1870 (View-process-current-field-number))))
1871 (setq buffer-read-only nil)
1872 (View-process-sort-fields-in-region
1873 field-number
1874 (save-excursion
1875 (goto-char (region-beginning))
1876 (View-process-return-beginning-of-line))
1877 (save-excursion
1878 (goto-char (region-end))
1879 (View-process-return-end-of-line)))
1880 (setq buffer-read-only t)))
1881
1882 (defun View-process-reverse-output (&optional dont-remember)
1883 "Reverses the whole output lines.
1884 If DONT-REMEMBER is t, then the filter command isn't inserted
1885 in the `View-process-actual-sorter-and-filter' list."
1886 (interactive)
1887 (setq buffer-read-only nil)
1888 (let ((position (View-process-save-position)))
1889 ; (line (count-lines (point-min) (point)))
1890 ; (column (current-column)))
1891 (reverse-region View-process-output-start View-process-output-end)
1892 (View-process-goto-position position))
1893 ; (goto-line line)
1894 ; (beginning-of-line)
1895 ; (forward-char column))
1896 (setq buffer-read-only t)
1897 (if (not dont-remember)
1898 (setq View-process-actual-sorter-and-filter
1899 (if (assq 'reverse View-process-actual-sorter-and-filter)
1900 (View-process-remove-sorter
1901 'reverse
1902 View-process-actual-sorter-and-filter)
1903 (append View-process-actual-sorter-and-filter
1904 (list (list 'reverse)))))))
1905
1906 (defun View-process-reverse-region ()
1907 "Reverses the output lines in the region."
1908 (interactive)
1909 (setq buffer-read-only nil)
1910 (let ((region-beginning (if (< (region-beginning) (region-end))
1911 (region-beginning)
1912 (region-end)))
1913 (region-end (if (> (region-end) (region-beginning))
1914 (region-end)
1915 (region-beginning)))
1916 (position (View-process-save-position)))
1917 ; (line (count-lines (point-min) (point)))
1918 ; (column (current-column)))
1919 (reverse-region (if (< region-beginning View-process-output-start)
1920 View-process-output-start
1921 (goto-char region-beginning)
1922 (View-process-return-beginning-of-line))
1923 (if (> region-end View-process-output-end)
1924 View-process-output-end
1925 (goto-char region-end)
1926 (View-process-return-end-of-line)))
1927 (View-process-goto-position position))
1928 ; (goto-line line)
1929 ; (beginning-of-line)
1930 ; (forward-char column))
1931 (setq buffer-read-only t))
1932
1933 (defun View-process-reverse-g ()
1934 "Reverses the output lines.
1935 It is a generic interface to `View-process-reverse-region'
1936 and `View-process-reverse-output'. The first will be called
1937 if a region is active and the other one if not."
1938 (interactive)
1939 (if (View-process-region-active-p)
1940 (call-interactively 'View-process-reverse-region)
1941 (call-interactively 'View-process-reverse-output)))
1942
1943 ;;; filter functions
1944
1945 (defun View-process-delete-region (start end)
1946 "Stores deleted lines in `View-process-deleted-lines'."
1947 (setq View-process-deleted-lines
1948 (cons (buffer-substring start end)
1949 View-process-deleted-lines))
1950 (delete-region start end))
1951
1952 (defun View-process-remove-all-filter-and-sorter ()
1953 "Undeletes all filtered lines from `View-process-deleted-lines'.
1954 It removes also all filter and sorter from the list
1955 `View-process-actual-sorter-and-filter'."
1956 (interactive)
1957 (let ((buffer-read-only))
1958 (goto-char View-process-output-end)
1959 (mapcar '(lambda (line)
1960 (insert line))
1961 View-process-deleted-lines)
1962 (setq View-process-output-end (point))
1963 (setq View-process-actual-sorter-and-filter nil)
1964 (goto-char View-process-output-start)))
1965
1966 (defun View-process-filter-fields-in-region (regexp
1967 field-no
1968 beg
1969 end
1970 &optional exclude)
1971 "Filters a region with a REGEXP in the field FIELD-NO.
1972 The region start is at BEG and the end at END. If FIELD-NO
1973 is nil, then the whole line is used. All lines which passes
1974 not the filter are deleted in the buffer, if EXCLUDE is nil.
1975 Otherwise only these lines are not deleted."
1976 (save-restriction
1977 (widen)
1978 (let ((region-start (if (< beg end) beg end))
1979 (region-end (if (> beg end) beg end)))
1980 (if (< region-start View-process-output-start)
1981 (setq region-start View-process-output-start))
1982 (goto-char region-end)
1983 (if field-no
1984 (while (>= (point) region-start)
1985 (if (string-match regexp
1986 (View-process-get-field-value-from-current-line
1987 field-no
1988 View-process-max-fields))
1989 (if exclude
1990 (View-process-delete-region
1991 (1- (View-process-return-beginning-of-line))
1992 (View-process-return-end-of-line))
1993 (forward-line -1))
1994 (if exclude
1995 (forward-line -1)
1996 (View-process-delete-region
1997 (1- (View-process-return-beginning-of-line))
1998 (View-process-return-end-of-line)))
1999 ))
2000 (beginning-of-line)
2001 (while (>= (point) region-start)
2002 (if (search-forward-regexp regexp
2003 (View-process-return-end-of-line) t)
2004 (if exclude
2005 (progn
2006 (View-process-delete-region
2007 (1- (View-process-return-beginning-of-line))
2008 (View-process-return-end-of-line))
2009 (beginning-of-line))
2010 (forward-line -1))
2011 (if exclude
2012 (forward-line -1)
2013 (View-process-delete-region
2014 (1- (View-process-return-beginning-of-line))
2015 (View-process-return-end-of-line))
2016 (beginning-of-line))
2017 )))
2018 (goto-char region-start))
2019 (setq View-process-output-end (point-max))
2020 (if (> View-process-output-start View-process-output-end)
2021 (progn
2022 (newline)
2023 (setq View-process-output-end View-process-output-start)))))
2024
2025 (defun View-process-filter-output-by-field (field-name
2026 regexp
2027 &optional exclude
2028 dont-remember)
2029 "Filter the whole output by the field FIELD-NAME with REGEXP.
2030 The matching lines are deleted, if EXCLUDE is t. The non matching
2031 lines are deleted, if EXCLUDE is nil. If you call this function
2032 interactive, then you can give a prefix arg to set EXCLUDE to non nil.
2033 If DONT-REMEMBER is t, then the filter command isn't inserted
2034 in the `View-process-actual-sorter-and-filter' list."
2035 (interactive
2036 (let ((View-process-stop-motion-help t))
2037 (list
2038 (completing-read "Field Name for filtering: "
2039 View-process-field-names
2040 nil
2041 t
2042 (car View-process-field-name-history)
2043 View-process-field-name-history)
2044 (read-string "Regexp for filtering the output in the field: "
2045 (car View-process-filter-history)
2046 View-process-filter-history)
2047 current-prefix-arg
2048 )))
2049 (setq buffer-read-only nil)
2050 (View-process-filter-fields-in-region
2051 regexp
2052 (View-process-translate-field-name-to-position field-name)
2053 View-process-output-start
2054 View-process-output-end
2055 exclude)
2056 (setq buffer-read-only t)
2057 (if (not dont-remember)
2058 (setq View-process-actual-sorter-and-filter
2059 (append View-process-actual-sorter-and-filter
2060 (list (list (if exclude 'exclude-filter 'filter)
2061 field-name
2062 regexp))))))
2063
2064 (defun View-process-filter-output-by-current-field (regexp
2065 &optional exclude
2066 dont-remember)
2067 "Filter the whole output by the field under the point with REGEXP.
2068 The matching lines are deleted, if EXCLUDE is t. The non matching
2069 lines are deleted, if EXCLUDE is nil. If you call this function
2070 interactive, then you can give a prefix arg to set EXCLUDE to non nil.
2071 If DONT-REMEMBER is t, then the filter command isn't inserted
2072 in the `View-process-actual-sorter-and-filter' list."
2073 ; (interactive "sRegexp for filtering the output in the current field: \nP")
2074 (interactive
2075 (let* ((View-process-stop-motion-help t)
2076 (regexp (read-string
2077 "sRegexp for filtering the output in the current field: "))
2078 (exclude current-prefix-arg))
2079 (list regexp exclude)))
2080 (let ((current-field-number (View-process-current-field-number)))
2081 (setq buffer-read-only nil)
2082 (View-process-filter-fields-in-region regexp
2083 current-field-number
2084 View-process-output-start
2085 View-process-output-end
2086 exclude)
2087 (setq buffer-read-only t)
2088 (if (not dont-remember)
2089 (setq View-process-actual-sorter-and-filter
2090 (append View-process-actual-sorter-and-filter
2091 (list
2092 (list (if exclude 'exclude-filter 'filter)
2093 (View-process-translate-field-position-to-name
2094 current-field-number)
2095 regexp)))))))
2096
2097 (defun View-process-filter-region-by-current-field (regexp &optional exclude)
2098 "Filter the region by the field under the point with REGEXP.
2099 The matching lines are deleted, if EXCLUDE is t. The non matching
2100 lines are deleted, if EXCLUDE is nil. If you call this function
2101 interactive, then you can give a prefix arg to set EXCLUDE to non nil."
2102 ; (interactive "sRegexp for filtering the region in the current field: \nP")
2103 (interactive
2104 (let* ((View-process-stop-motion-help t)
2105 (regexp (read-string
2106 "sRegexp for filtering the region in the current field: "))
2107 (exclude current-prefix-arg))
2108 (list regexp exclude)))
2109 (setq buffer-read-only nil)
2110 (View-process-filter-fields-in-region
2111 regexp
2112 (View-process-current-field-number)
2113 (save-excursion
2114 (goto-char (region-beginning))
2115 (View-process-return-beginning-of-line))
2116 (save-excursion
2117 (goto-char (region-end))
2118 (View-process-return-end-of-line))
2119 exclude)
2120 (setq buffer-read-only t))
2121
2122 (defun View-process-filter-by-current-field-g (&optional exclude)
2123 "Filter the whole output by the field under the point with an Regexp.
2124 It is a generic interface to `View-process-filter-region-by-current-field'
2125 and `View-process-filter-output-by-current-field'. The first will be called
2126 if a region is active and the other one if not.
2127 The matching lines are deleted, if EXCLUDE is t. The non matching
2128 lines are deleted, if EXCLUDE is nil. If you call this function
2129 interactive, then you can give a prefix arg to set EXCLUDE to non nil."
2130 (interactive "P")
2131 (setq prefix-arg current-prefix-arg)
2132 (if (View-process-region-active-p)
2133 (call-interactively 'View-process-filter-region-by-current-field)
2134 (call-interactively 'View-process-filter-output-by-current-field)))
2135
2136 (defun View-process-filter-output (regexp &optional exclude dont-remember)
2137 "Filter the whole output with REGEXP.
2138 The matching lines are deleted, if EXCLUDE is t. The non matching
2139 lines are deleted, if EXCLUDE is nil. If you call this function
2140 interactive, then you can give a prefix arg to set EXCLUDE to non nil.
2141 If DONT-REMEMBER is t, then the filter command isn't inserted
2142 in the `View-process-actual-sorter-and-filter' list."
2143 ; (interactive "sRegexp for filtering the output: \nP")
2144 (interactive
2145 (let* ((View-process-stop-motion-help t)
2146 (regexp (read-string
2147 "sRegexp for filtering the output: "))
2148 (exclude current-prefix-arg))
2149 (list regexp exclude)))
2150 (setq buffer-read-only nil)
2151 (View-process-filter-fields-in-region regexp
2152 nil
2153 View-process-output-start
2154 View-process-output-end
2155 exclude)
2156 (setq buffer-read-only t)
2157 (if (not dont-remember)
2158 (setq View-process-actual-sorter-and-filter
2159 (append View-process-actual-sorter-and-filter
2160 (list (list (if exclude 'exclude-grep 'grep)
2161 regexp))))))
2162
2163 (defun View-process-filter-region (regexp &optional exclude)
2164 "Filter the region with REGEXP.
2165 The matching lines are deleted, if EXCLUDE is t. The non matching
2166 lines are deleted, if EXCLUDE is nil. If you call this function
2167 interactive, then you can give a prefix arg to set EXCLUDE to non nil."
2168 ; (interactive "sRegexp for filtering the region: \nP")
2169 (interactive
2170 (let* ((View-process-stop-motion-help t)
2171 (regexp (read-string
2172 "sRegexp for filtering the region: "))
2173 (exclude current-prefix-arg))
2174 (list regexp exclude)))
2175 (setq buffer-read-only nil)
2176 (View-process-filter-fields-in-region
2177 regexp
2178 nil
2179 (save-excursion
2180 (goto-char (region-beginning))
2181 (View-process-return-beginning-of-line))
2182 (save-excursion
2183 (goto-char (region-end))
2184 (View-process-return-end-of-line))
2185 exclude)
2186 (setq buffer-read-only t))
2187
2188 (defun View-process-filter-g (&optional exclude)
2189 "Filters the output by the field under the point with an Regexp.
2190 It is a generic interface to `View-process-filter-region'
2191 and `View-process-filter-output'. The first will be called
2192 if a region is active and the other one if not.
2193 The matching lines are deleted, if EXCLUDE is t. The non matching
2194 lines are deleted, if EXCLUDE is nil. If you call this function
2195 interactive, then you can give a prefix arg to set EXCLUDE to non nil."
2196 (interactive "P")
2197 (setq prefix-arg current-prefix-arg)
2198 (if (View-process-region-active-p)
2199 (call-interactively 'View-process-filter-region)
2200 (call-interactively 'View-process-filter-output)))
2201
2202
2203 ;;; call sorter, filter or grep after running ps
2204
2205 (defun View-process-call-sorter-and-filter (sorter-and-filter-list)
2206 "Call sorter, filter or grep after running ps.
2207 The sorter, filter or grep commands and its parameters are called
2208 from SORTER-AND-FILTER-LIST."
2209 (cond ((not sorter-and-filter-list) t)
2210 ((eq 'grep (car (car sorter-and-filter-list)))
2211 (View-process-filter-output (car (cdr (car sorter-and-filter-list)))
2212 nil
2213 t)
2214 (View-process-call-sorter-and-filter (cdr sorter-and-filter-list)))
2215 ((eq 'exclude-grep (car (car sorter-and-filter-list)))
2216 (View-process-filter-output (car (cdr (car sorter-and-filter-list)))
2217 t
2218 t)
2219 (View-process-call-sorter-and-filter (cdr sorter-and-filter-list)))
2220 ((eq 'sort (car (car sorter-and-filter-list)))
2221 (if (assoc (car (cdr (car sorter-and-filter-list)))
2222 View-process-field-names)
2223 (View-process-sort-output-by-field
2224 (car (cdr (car sorter-and-filter-list)))
2225 t))
2226 (View-process-call-sorter-and-filter (cdr sorter-and-filter-list)))
2227 ((eq 'filter (car (car sorter-and-filter-list)))
2228 (if (assoc (car (cdr (car sorter-and-filter-list)))
2229 View-process-field-names)
2230 (View-process-filter-output-by-field
2231 (car (cdr (car sorter-and-filter-list)))
2232 (car (cdr (cdr (car sorter-and-filter-list))))
2233 nil
2234 t))
2235 (View-process-call-sorter-and-filter (cdr sorter-and-filter-list)))
2236 ((eq 'exclude-filter (car (car sorter-and-filter-list)))
2237 (if (assoc (car (cdr (car sorter-and-filter-list)))
2238 View-process-field-names)
2239 (View-process-filter-output-by-field
2240 (car (cdr (car sorter-and-filter-list)))
2241 (car (cdr (cdr (car sorter-and-filter-list))))
2242 t
2243 t))
2244 (View-process-call-sorter-and-filter (cdr sorter-and-filter-list)))
2245 ((eq 'reverse (car (car sorter-and-filter-list)))
2246 (View-process-reverse-output t)
2247 (View-process-call-sorter-and-filter (cdr sorter-and-filter-list)))
2248 (t (error "Filter/Sorter command not implemented!"))))
2249
2250
2251 ;;; Child processes
2252
2253 (defun View-process-get-child-process-list-1 (pid pid-ppid-alist)
2254 "Internal function of `View-process-get-child-process-list'."
2255 (cond ((car pid-ppid-alist)
2256 (if (not (string= pid (cdr (car pid-ppid-alist))))
2257 (View-process-get-child-process-list-1 pid (cdr pid-ppid-alist))
2258 (cons (car (car pid-ppid-alist))
2259 (View-process-get-child-process-list-1 pid
2260 (cdr pid-ppid-alist))
2261 )))))
2262
2263 (defun View-process-get-child-process-list (pid pid-ppid-alist)
2264 "Returns a list with all direct childs of the processes with the PID.
2265 The list PID-PPID-ALIST is an alist with the pid's as car's
2266 and ppid's as cdr's.
2267 Example list: (\"0\" \"10\" \"20\")
2268 With \"0\" eq PID as the parent of the direct childs \"10\" and \"20\"."
2269 (cons pid (View-process-get-child-process-list-1 pid pid-ppid-alist)))
2270
2271 (defun View-process-get-child-process-tree (pid)
2272 "Returns a list with all childs and subchilds of the processes with the PID.
2273 Example list: (\"0\" (\"10\") (\"20\" (\"30\" \"40\")))
2274 With \"0\" eq PID as the parent of the direct childs \"10\" and \"20\"
2275 and with \"20\" as the parent of the direct childs \"30\" and \"40\"."
2276 (cons pid
2277 (mapcar 'View-process-get-child-process-tree
2278 (cdr (View-process-get-child-process-list
2279 pid
2280 (save-excursion
2281 (View-process-get-pid-ppid-list-from-region
2282 View-process-output-start
2283 View-process-output-end)))))))
2284
2285 ;(defun View-process-highlight-process-tree (process-tree)
2286 ; "Highlights all processes in the list process-tree."
2287 ; (cond ((not process-tree))
2288 ; ((listp (car process-tree))
2289 ; (View-process-highlight-process-tree (car process-tree))
2290 ; (View-process-highlight-process-tree (cdr process-tree)))
2291 ; ((stringp (car process-tree))
2292 ; (View-process-highlight-line-with-pid (car process-tree)
2293 ; 'View-process-child-line-face
2294 ; View-process-child-line-mark)
2295 ; (View-process-highlight-process-tree (cdr process-tree)))
2296 ; (t (error "Bug in 'View-process-highlight-process-tree' !"))))
2297
2298 ;(defun View-process-highlight-recursive-all-childs (pid)
2299 ; "Highlights all childs of the process with the PID."
2300 ; (interactive "sParent PID: ")
2301 ; (if (not
2302 ; (View-process-field-name-exists-p View-process-ppid-field-name))
2303 ; (error "ERROR: No field `%s' in the output. Try `M-x ps -j' to get it."
2304 ; View-process-ppid-field-name)
2305 ; (View-process-highlight-line-with-pid pid
2306 ; 'View-process-parent-line-face
2307 ; View-process-parent-line-mark)
2308 ; (View-process-highlight-process-tree
2309 ; (cdr (View-process-get-child-process-tree pid)))))
2310
2311 ;(defun View-process-highlight-recursive-all-childs-in-line ()
2312 ; "Highlights all the child processes of the process in the current line."
2313 ; (interactive)
2314 ; (View-process-highlight-recursive-all-childs
2315 ; (View-process-get-pid-from-current-line)))
2316
2317 ;;; kill processes
2318
2319 (defun View-process-send-signal-to-processes-with-mark (signal)
2320 "Sends a SIGNAL to all processes, which are marked."
2321 (interactive
2322 (let* ((View-process-stop-motion-help t)
2323 (signal (completing-read "Signal: "
2324 View-process-kill-signals
2325 nil
2326 t
2327 View-process-default-kill-signal
2328 View-process-signal-history)))
2329 (list signal)))
2330 (if View-process-pid-mark-alist
2331 (View-process-call-function-on-pid-and-mark-list
2332 'View-process-send-signal-to-process-in-line
2333 View-process-pid-mark-alist
2334 t
2335 signal)
2336 (error "ERROR: There is no marked process!.")))
2337
2338 (defun View-process-send-signal-to-processes-in-region (signal)
2339 "Sends a SIGNAL to all processes in the current region."
2340 (interactive
2341 (let* ((View-process-stop-motion-help t)
2342 (signal (completing-read "Signal: "
2343 View-process-kill-signals
2344 nil
2345 t
2346 View-process-default-kill-signal
2347 View-process-signal-history)))
2348 (list signal)))
2349 (let ((region-start (if (> (region-beginning) View-process-output-start)
2350 (region-beginning)
2351 View-process-output-start))
2352 (region-end (if (< (region-end) View-process-output-end)
2353 (region-end)
2354 View-process-output-end)))
2355 (save-excursion
2356 (goto-char region-start)
2357 (beginning-of-line)
2358 (let ((pid-list (View-process-get-pid-list-from-region (point)
2359 region-end)))
2360 (View-process-send-signal-to-processes-in-pid-list signal
2361 pid-list
2362 nil
2363 t)
2364 ))))
2365
2366 (defun View-process-send-signal-to-processes-in-pid-list (signal
2367 pid-list
2368 &optional
2369 dont-ask
2370 dont-update)
2371 "Sends a SIGNAL to all processes with a pid in PID-LIST.
2372 If DONT-ASK is non nil, then no confirmation question will be asked.
2373 If DONT-UPDATE is non nil, then the command `View-process-status-update'
2374 will not be run after sending a signal."
2375 (if (not pid-list)
2376 t
2377 (View-process-send-signal-to-process signal
2378 (car pid-list)
2379 dont-ask
2380 dont-update)
2381 (View-process-send-signal-to-processes-in-pid-list signal
2382 (cdr pid-list)
2383 dont-ask
2384 dont-update)))
2385
2386 (defun View-process-send-signal-to-process-in-line (signal)
2387 "Sends a SIGNAL to the process in the current line."
2388 (interactive
2389 (let* ((View-process-stop-motion-help t)
2390 (signal (completing-read "Signal: "
2391 View-process-kill-signals
2392 nil
2393 t
2394 View-process-default-kill-signal
2395 View-process-signal-history)))
2396 (list signal)))
2397 (if (and (>= (point) View-process-output-start)
2398 (< (point) View-process-output-end))
2399 (View-process-send-signal-to-process
2400 signal
2401 (View-process-get-pid-from-current-line)
2402 nil
2403 t)))
2404
2405 (defun View-process-send-key-as-signal-to-processes ()
2406 "Converts the key which invokes this command to a signal.
2407 After that it sends this signal to the process in the current line,
2408 or, if an active region exists, to all processes in the region.
2409 For this function only numbers could be used as keys."
2410 (interactive)
2411 (let ((signal (View-process-return-current-command-key-as-string)))
2412 (if (not (= 0 (string-to-int signal)))
2413 (if (View-process-region-active-p)
2414 (View-process-send-signal-to-processes-in-region signal)
2415 (View-process-send-signal-to-process-in-line signal))
2416 (error "ERROR: This command must be bind to and call by an integer!")
2417 )))
2418
2419 (defun View-process-send-signal-to-processes-g ()
2420 "Sends a signal to processes.
2421 It is a generic interface to `View-process-send-signal-to-processes-in-region'
2422 and `View-process-send-signal-to-process-in-line'. The first will be called
2423 if a region is active and the other one if not. If the region isn't
2424 active, but marks are set, then the function is called on every
2425 marked process."
2426 (interactive)
2427 (cond ((View-process-region-active-p)
2428 (call-interactively 'View-process-send-signal-to-processes-in-region))
2429 (View-process-pid-mark-alist
2430 (call-interactively 'View-process-send-signal-to-processes-with-mark))
2431 (t
2432 (call-interactively 'View-process-send-signal-to-process-in-line))))
2433
2434 (defun View-process-send-signal-to-process (signal
2435 pid
2436 &optional
2437 dont-ask
2438 dont-update)
2439 "Sends the SIGNAL to the process with the PID.
2440 If DONT-ASK is non nil, then no confirmation question will be asked.
2441 If DONT-UPDATE is non nil, then the command `View-process-status-update'
2442 will not be run after sending the signal."
2443 (interactive
2444 (let* ((View-process-stop-motion-help t)
2445 (signal (completing-read "Signal: "
2446 View-process-kill-signals
2447 nil
2448 t
2449 View-process-default-kill-signal
2450 View-process-signal-history))
2451 (pid (int-to-string (read-number "Process Id (PID): "))))
2452 (list signal pid)))
2453 (if (and (eq (string-to-int pid) (emacs-pid))
2454 (or (not View-process-remote-host)
2455 (string= View-process-remote-host (getenv "HOSTNAME"))))
2456 (error "Hey, are you a murderer? You've just tried to kill me!")
2457 (let (
2458 ; (signal-line-extent
2459 ; (View-process-highlight-line-with-pid
2460 ; pid
2461 ; 'View-process-signal-line-face
2462 ; View-process-signal-line-mark))
2463 (signal-number (car (cdr (assoc signal View-process-kill-signals)))))
2464 (View-process-mark-line-with-pid pid View-process-signal-line-mark)
2465 (if (or dont-ask
2466 (if (string= signal-number signal)
2467 (y-or-n-p (format
2468 "Do you realy want to send signal %s to PID %s "
2469 signal
2470 pid))
2471 (y-or-n-p
2472 (format "Do you realy want to send signal %s (%s) to PID %s "
2473 signal
2474 signal-number
2475 pid))))
2476 (progn
2477 (if View-process-remote-host
2478 (call-process View-process-rsh-command
2479 nil
2480 nil
2481 nil
2482 View-process-remote-host
2483 (concat View-process-signal-command
2484 " -"
2485 signal-number
2486 " "
2487 pid))
2488 (call-process View-process-signal-command
2489 nil
2490 nil
2491 nil
2492 (concat "-" signal-number)
2493 pid))
2494 (if (not dont-update)
2495 (View-process-status-update)
2496 (View-process-mark-line-with-pid pid
2497 View-process-signaled-line-mark)
2498 ))
2499 ; (View-process-delete-extent signal-line-extent)
2500 (if (View-process-goto-line-with-pid pid)
2501 (View-process-unmark-current-line))
2502 ))))
2503
2504
2505 ;;; renice processes
2506
2507 (defun View-process-read-nice-value ()
2508 "Reads and returns a valid nice value."
2509 (let ((nice-value nil)
2510 (min-value (if (string= (user-real-login-name) "root") -20 1))
2511 (prompt "Add nice value [%d ... 20]: "))
2512 (while (not nice-value)
2513 (setq nice-value (read-string (format prompt min-value)
2514 View-process-default-nice-value))
2515 (if (and (string= (int-to-string (string-to-int nice-value))
2516 nice-value)
2517 (>= (string-to-int nice-value) min-value)
2518 (<= (string-to-int nice-value) 20)
2519 (not (= (string-to-int nice-value) 0)))
2520 (if (> (string-to-int nice-value) 0)
2521 (setq nice-value
2522 (concat "+" (int-to-string (string-to-int nice-value)))))
2523 (setq nice-value nil)
2524 (setq prompt
2525 "Wrong Format! Try again. Add nice value [%d ... 20]: ")))
2526 nice-value))
2527
2528 (defun View-process-renice-process (nice-value
2529 pid
2530 &optional
2531 dont-ask
2532 dont-update)
2533 "Alter priority of the process with the PID.
2534 NICE-VALUE is the value, which will be added to the old nice value.
2535 If DONT-ASK is non nil, then no confirmation question will be asked.
2536 If DONT-UPDATE is non nil, then the command `View-process-status-update'
2537 will not be run after renicing."
2538 (interactive
2539 (let* ((View-process-stop-motion-help t)
2540 (nice-value (View-process-read-nice-value))
2541 (pid (int-to-string (read-number "Process Id (PID): "))))
2542 (list nice-value pid)))
2543 ; (let ((signal-line-extent
2544 ; (View-process-highlight-line-with-pid
2545 ; pid
2546 ; 'View-process-signal-line-face
2547 ; View-process-renice-line-mark)))
2548 (View-process-mark-line-with-pid pid View-process-renice-line-mark)
2549 (if (or dont-ask
2550 (y-or-n-p (format
2551 "Do you realy want to renice PID %s with %s "
2552 pid
2553 nice-value)))
2554 (progn
2555 (if View-process-remote-host
2556 (call-process View-process-rsh-command
2557 nil
2558 nil
2559 nil
2560 View-process-remote-host
2561 (concat View-process-renice-command
2562 " "
2563 nice-value
2564 " "
2565 pid))
2566 (call-process View-process-renice-command
2567 nil
2568 nil
2569 nil
2570 nice-value
2571 pid))
2572 (if (not dont-update)
2573 (View-process-status-update)
2574 (View-process-mark-line-with-pid pid View-process-signaled-line-mark)
2575 ))
2576 ; (View-process-delete-extent signal-line-extent)
2577 (if (View-process-goto-line-with-pid pid)
2578 (View-process-unmark-current-line))))
2579
2580 (defun View-process-renice-processes-with-mark (nice-value)
2581 "Alter priority of all processes, which are marked.
2582 NICE-VALUE is the value, which will be added to the old nice value."
2583 (interactive
2584 (let* ((View-process-stop-motion-help t)
2585 (nice-value (View-process-read-nice-value)))
2586 (list nice-value)))
2587 (if View-process-pid-mark-alist
2588 (View-process-call-function-on-pid-and-mark-list
2589 'View-process-renice-process-in-line
2590 View-process-pid-mark-alist
2591 t
2592 nice-value)
2593 (error "ERROR: There is no marked process!.")))
2594
2595 (defun View-process-renice-processes-in-region (nice-value)
2596 "Alter priority of all processes in the current region.
2597 NICE-VALUE is the value, which will be added to the old nice value."
2598 (interactive
2599 (let* ((View-process-stop-motion-help t)
2600 (nice-value (View-process-read-nice-value)))
2601 (list nice-value)))
2602 (let ((region-start (if (> (region-beginning) View-process-output-start)
2603 (region-beginning)
2604 View-process-output-start))
2605 (region-end (if (< (region-end) View-process-output-end)
2606 (region-end)
2607 View-process-output-end)))
2608 (save-excursion
2609 (goto-char region-start)
2610 (beginning-of-line)
2611 (let ((pid-list (View-process-get-pid-list-from-region (point)
2612 region-end)))
2613 (View-process-renice-processes-in-pid-list nice-value pid-list nil t)
2614 ))))
2615
2616 (defun View-process-renice-processes-in-pid-list (nice-value
2617 pid-list
2618 &optional
2619 dont-ask
2620 dont-update)
2621 "Alter priority all processes with a pid in PID-LIST.
2622 NICE-VALUE is the value, which will be added to the old nice value.
2623 If DONT-ASK is non nil, then no confirmation question will be asked.
2624 If DONT-UPDATE is non nil, then the command `View-process-status-update'
2625 will not be run after renicing"
2626 (if (not pid-list)
2627 t
2628 (View-process-renice-process nice-value
2629 (car pid-list)
2630 dont-ask
2631 dont-update)
2632 (View-process-renice-processes-in-pid-list nice-value
2633 (cdr pid-list)
2634 dont-ask
2635 dont-update)))
2636
2637 (defun View-process-renice-process-in-line (nice-value)
2638 "Alter priority of to the process in the current line.
2639 NICE-VALUE is the value, which will be added to the old nice value."
2640 (interactive
2641 (let* ((View-process-stop-motion-help t)
2642 (nice-value (View-process-read-nice-value)))
2643 (list nice-value)))
2644 (if (and (>= (point) View-process-output-start)
2645 (< (point) View-process-output-end))
2646 (View-process-renice-process
2647 nice-value
2648 (View-process-get-pid-from-current-line)
2649 nil
2650 t)))
2651
2652 (defun View-process-renice-processes-g ()
2653 "Alter priority of processes.
2654 It is a generic interface to `View-process-renice-processes-in-region'
2655 and `View-process-renice-process-in-line'. The first will be called
2656 if a region is active and the other one if not. If the region isn't
2657 active, but marks are set, then the function is called on every
2658 marked process."
2659 (interactive)
2660 (cond ((View-process-region-active-p)
2661 (call-interactively 'View-process-renice-processes-in-region))
2662 (View-process-pid-mark-alist
2663 (call-interactively 'View-process-renice-processes-with-mark))
2664 (t
2665 (call-interactively 'View-process-renice-process-in-line))))
2666
2667
2668 ;;; Returning field values
2669
2670 (defun View-process-get-pid-from-current-line ()
2671 "Returns a string with the pid of the process in the current line."
2672 (View-process-get-field-value-from-current-line
2673 (View-process-translate-field-name-to-position View-process-pid-field-name)
2674 View-process-max-fields)
2675 )
2676
2677 (defun View-process-get-ppid-from-current-line ()
2678 "Returns a string with the ppid of the process in the current line."
2679 (View-process-get-field-value-from-current-line
2680 (View-process-translate-field-name-to-position View-process-ppid-field-name)
2681 View-process-max-fields)
2682 )
2683
2684 (defun View-process-get-pid-list-from-region (begin end)
2685 "Returns a list with all PID's in the region from BEGIN to END."
2686 (goto-char begin)
2687 (if (>= (point) end)
2688 nil
2689 (cons (View-process-get-pid-from-current-line)
2690 (progn (forward-line)
2691 (View-process-get-pid-list-from-region (point) end)))))
2692
2693 (defun View-process-get-pid-ppid-list-from-region (begin end)
2694 "Returns a list with all PID's ant its PPID's in the region
2695 from BEGIN to END. END must be greater than BEGIN."
2696 (goto-char begin)
2697 (if (>= (point) end)
2698 nil
2699 (cons (cons (View-process-get-pid-from-current-line)
2700 (View-process-get-ppid-from-current-line))
2701 (progn (forward-line)
2702 (View-process-get-pid-ppid-list-from-region (point) end)))))
2703
2704 (defun View-process-get-field-value-from-current-line (field-no max-fields)
2705 "Returns the value of the field FIELD-NO from the current line as string.
2706 If the FIELD-NO is >= max-fields, then the rest of the line after the
2707 start of the field FIELD-NO will be returned."
2708 (save-excursion
2709 (View-process-jump-to-field field-no max-fields)
2710 (if (>= field-no max-fields)
2711 (buffer-substring (point) (View-process-return-end-of-line))
2712 (current-word)))
2713 )
2714
2715 (defun View-process-jump-to-field (field-no max-fields)
2716 "Sets the point at the start of field FIELD-NO in the current line.
2717 MAX_FIELDS is used instead of FIELD-NO, if FIELD-NO > MAX_FIELDS."
2718 (View-process-replaces-blanks-in-fields-if-necessary)
2719 (beginning-of-line)
2720 (skip-chars-forward " ")
2721 (if (< field-no 1)
2722 (error "Parameter FIELD-NO must be >= 1"))
2723 (if (> field-no max-fields)
2724 (setq field-no max-fields))
2725 (if (= field-no 1)
2726 (point)
2727 (skip-chars-forward "^ ")
2728 (skip-chars-forward " ")
2729 (View-process-jump-to-field-1 (1- field-no))))
2730
2731 (defun View-process-jump-to-field-1 (field-no)
2732 "Internal function of View-process-jump-to-field"
2733 (if (= field-no 1)
2734 (point)
2735 (skip-chars-forward "^ ")
2736 (skip-chars-forward " ")
2737 (View-process-jump-to-field-1 (1- field-no))))
2738
2739
2740 (defun View-process-display-emacs-pid ()
2741 "Sets the point to the line with the emacs process."
2742 (interactive)
2743 (message (format "This emacs has the PID `%d'!" (emacs-pid))))
2744
2745
2746 ;;; mouse functions
2747
2748 (defun View-process-mouse-kill (event)
2749 "Function for kill a process with the mouse."
2750 (interactive "e")
2751 (mouse-set-point event)
2752 (View-process-send-signal-to-process-in-line "SIGTERM"))
2753
2754
2755 ;;; Highlighting functions
2756
2757 (defun View-process-highlight-current-line (face)
2758 "Highlights the current line with the FACE."
2759 (let ((read-only buffer-read-only))
2760 (setq buffer-read-only nil)
2761 (let ((extent (make-extent (View-process-return-beginning-of-line)
2762 (View-process-return-end-of-line))))
2763 (set-extent-face extent face)
2764 (setq buffer-read-only read-only)
2765 extent)
2766 ))
2767
2768 (defun View-process-goto-line-with-pid (pid)
2769 "Sets the point in the line with the PID.
2770 It returns nil, if there is no line with the PID in the output."
2771 (if (string= pid (View-process-get-pid-from-current-line))
2772 t
2773 (goto-char View-process-output-start)
2774 (while (and (< (point) View-process-output-end)
2775 (not (string= pid (View-process-get-pid-from-current-line))))
2776 (forward-line))
2777 (< (point) View-process-output-end)))
2778
2779 ;(defun View-process-highlight-line-with-pid (pid face mark)
2780 ; "Highlights the line with the PID with the FACE and sets the MARK.
2781 ;It returns the extent of the line."
2782 ; (save-excursion
2783 ; (View-process-goto-line-with-pid pid)
2784 ; (View-process-set-mark-in-current-line mark)
2785 ; (View-process-save-pid-and-mark pid mark)
2786 ; (View-process-highlight-current-line face)
2787 ; ))
2788
2789 ;(defun View-process-delete-extent (extent)
2790 ; "Deletes the extent EXTENT."
2791 ; (let ((read-only buffer-read-only))
2792 ; (save-excursion
2793 ; (goto-char (extent-start-position extent))
2794 ; (View-process-set-mark-in-current-line View-process-no-mark)
2795 ; (setq buffer-read-only nil)
2796 ; (delete-extent extent)
2797 ; (setq buffer-read-only read-only))))
2798
2799 ;;; mark functions
2800
2801 (defun View-process-save-pid-and-mark (pid mark)
2802 "Saves the PID and the MARK in a special alist.
2803 The name of the alist is `View-process-pid-mark-alist'."
2804 (if (assoc pid View-process-pid-mark-alist)
2805 (setcdr (assoc pid View-process-pid-mark-alist) (list mark ))
2806 (setq View-process-pid-mark-alist
2807 (cons (list pid mark) View-process-pid-mark-alist))))
2808
2809 (defun View-process-remove-pid-and-mark-1 (pid pid-mark-alist)
2810 "Internal function of `View-process-remove-pid-and-mark'."
2811 (cond ((not pid-mark-alist)
2812 nil)
2813 ((string= pid (car (car pid-mark-alist)))
2814 (View-process-remove-pid-and-mark-1 pid (cdr pid-mark-alist)))
2815 (t
2816 (cons (car pid-mark-alist)
2817 (View-process-remove-pid-and-mark-1 pid (cdr pid-mark-alist)))
2818 )))
2819
2820 (defun View-process-remove-pid-and-mark (pid)
2821 "Removes the PID from the alist `View-process-pid-mark-alist'."
2822 (setq View-process-pid-mark-alist
2823 (View-process-remove-pid-and-mark-1 pid View-process-pid-mark-alist))
2824 )
2825
2826 (defun View-process-set-mark-in-current-line (mark)
2827 "Sets the MARK at the start of the current line."
2828 (let ((buffer-read-only nil))
2829 (save-excursion
2830 (beginning-of-line)
2831 (delete-char 1)
2832 (insert mark))))
2833
2834 (defun View-process-mark-line-with-pid (pid &optional mark)
2835 "Sets the MARK in the line with the PID.
2836 It uses the 'View-process-single-line-mark', if mark is nil."
2837 ; (interactive "sPID: ")
2838 (interactive (let ((View-process-stop-motion-help t))
2839 (list (read-string "PID: "))))
2840 (save-excursion
2841 (View-process-goto-line-with-pid pid)
2842 (View-process-set-mark-in-current-line (or mark
2843 View-process-single-line-mark))
2844 (View-process-save-pid-and-mark pid
2845 (or mark
2846 View-process-single-line-mark))
2847 ))
2848
2849 (defun View-process-mark-current-line (&optional mark)
2850 "Sets a mark in the current line.
2851 It uses the 'View-process-single-line-mark' if MARK is nil."
2852 (interactive)
2853 (if (or (< (point) View-process-output-start)
2854 (> (point) View-process-output-end))
2855 (error "ERROR: Not in a process line!")
2856 (View-process-set-mark-in-current-line (or mark
2857 View-process-single-line-mark))
2858 (View-process-save-pid-and-mark (View-process-get-pid-from-current-line)
2859 (or mark
2860 View-process-single-line-mark))))
2861
2862
2863 (defun View-process-unmark-current-line ()
2864 "Unsets a mark in the current line."
2865 (interactive)
2866 (if (and (>= (point) View-process-output-start)
2867 (<= (point) View-process-output-end))
2868 (progn
2869 (View-process-remove-pid-and-mark
2870 (View-process-get-pid-from-current-line))
2871 (View-process-set-mark-in-current-line View-process-no-mark)
2872 )
2873 (error "ERROR: Not in a process line!")))
2874
2875 (defun View-process-mark-process-tree (process-tree)
2876 "Marks all processes in the list process-tree."
2877 (cond ((not process-tree))
2878 ((listp (car process-tree))
2879 (View-process-mark-process-tree (car process-tree))
2880 (View-process-mark-process-tree (cdr process-tree)))
2881 ((stringp (car process-tree))
2882 (View-process-mark-line-with-pid (car process-tree)
2883 View-process-child-line-mark)
2884 (View-process-mark-process-tree (cdr process-tree)))
2885 (t (error "Bug in 'View-process-mark-process-tree' !"))))
2886
2887 (defun View-process-mark-childs (pid)
2888 "Marks all childs of the process with the PID."
2889 ; (interactive "sParent PID: ")
2890 (interactive (let ((View-process-stop-motion-help t))
2891 (list (read-string "Parent PID: "))))
2892 (if (not
2893 (View-process-field-name-exists-p View-process-ppid-field-name))
2894 (error "ERROR: No field `%s' in the output. Try `M-x ps -j' to get it."
2895 View-process-ppid-field-name)
2896 (View-process-mark-line-with-pid pid View-process-parent-line-mark)
2897 (View-process-mark-process-tree
2898 (cdr (View-process-get-child-process-tree pid)))))
2899
2900 (defun View-process-mark-childs-in-current-line ()
2901 "Marks all the child processes of the process in the current line."
2902 (interactive)
2903 (View-process-mark-childs
2904 (View-process-get-pid-from-current-line)))
2905
2906 (defun View-process-call-function-on-pid-and-mark-list (function
2907 pid-mark-alist
2908 &optional
2909 not-interactive
2910 &rest
2911 non-interactive-args)
2912 "Calls the FUNCTION on every process in the PID-MARK-ALIST.
2913 FUNCTION must be an interactive function, which works on the
2914 process in the current line, if INTERACTIVE is nil.
2915 If INTERACTIVE is t, then the function will be called non interactive
2916 with the NON-INTERACTIVE-ARGS."
2917 (cond ((not pid-mark-alist))
2918 ((View-process-goto-line-with-pid (car (car pid-mark-alist)))
2919 (if not-interactive
2920 (eval (cons function non-interactive-args))
2921 (call-interactively function))
2922 (eval (append (list 'View-process-call-function-on-pid-and-mark-list
2923 'function
2924 '(cdr pid-mark-alist)
2925 'not-interactive)
2926 non-interactive-args)))
2927 (t
2928 (eval (append (list 'View-process-call-function-on-pid-and-mark-list
2929 'function
2930 '(cdr pid-mark-alist)
2931 'not-interactive)
2932 non-interactive-args)))
2933 ))
2934
2935 (defun View-process-set-marks-from-pid-mark-alist (pid-mark-alist)
2936 "Sets the marks of the PID-MARK-ALIST to the pids of the PID-MARK-ALIST."
2937 (cond ((not pid-mark-alist))
2938 ((View-process-goto-line-with-pid (car (car pid-mark-alist)))
2939 (View-process-mark-current-line (car (cdr (car pid-mark-alist))))
2940 (View-process-set-marks-from-pid-mark-alist (cdr pid-mark-alist)))
2941 (t
2942 (View-process-set-marks-from-pid-mark-alist (cdr pid-mark-alist)))))
2943
2944 (defun View-process-reset-last-marks ()
2945 "Resets the last marks."
2946 (interactive)
2947 (View-process-set-marks-from-pid-mark-alist View-process-last-pid-mark-alist)
2948 )
2949
2950 (defun View-process-unmark-all ()
2951 "Unmarks all processes."
2952 (interactive)
2953 (View-process-call-function-on-pid-and-mark-list
2954 'View-process-unmark-current-line
2955 View-process-pid-mark-alist
2956 t))
2957
2958
2959 ;;; commands to moving around in a ps buffer
2960
2961 (defun View-process-output-start ()
2962 "Set point to the first field after the output start."
2963 (interactive)
2964 (goto-char View-process-output-start)
2965 (skip-chars-forward " "))
2966
2967 (defun View-process-output-end ()
2968 "Set point to the first field before the output end."
2969 (interactive)
2970 (goto-char View-process-output-end)
2971 (skip-chars-backward " ")
2972 (skip-chars-backward "^ "))
2973
2974 (defun View-process-next-field ()
2975 "Moves forward one field."
2976 (interactive)
2977 (if (< (point) View-process-output-start)
2978 (View-process-output-start)
2979 (skip-chars-forward " ")
2980 (if (< (point) View-process-output-end)
2981 (if (= View-process-max-fields (View-process-current-field-number))
2982 (progn
2983 (forward-line)
2984 (skip-chars-forward " ")
2985 (if (>= (point) View-process-output-end)
2986 (progn
2987 (goto-char View-process-output-start)
2988 (skip-chars-forward " "))))
2989 (skip-chars-forward "^ ")
2990 (skip-chars-forward " ")
2991 )
2992 (goto-char View-process-output-start)
2993 (skip-chars-forward " "))))
2994
2995 (defun View-process-previous-field ()
2996 "Moves backward one field."
2997 (interactive)
2998 (skip-chars-backward " ")
2999 (backward-char)
3000 (if (> (point) View-process-output-start)
3001 (if (= View-process-max-fields (View-process-current-field-number))
3002 (View-process-jump-to-field View-process-max-fields
3003 View-process-max-fields)
3004 (skip-chars-backward "^ \n")
3005 (if (< (point) View-process-output-start)
3006 (progn
3007 (goto-char View-process-output-end)
3008 (forward-line -1)
3009 (View-process-jump-to-field View-process-max-fields
3010 View-process-max-fields))))
3011 (goto-char View-process-output-end)
3012 (forward-line -1)
3013 (View-process-jump-to-field View-process-max-fields
3014 View-process-max-fields)))
3015
3016 (defun View-process-goto-first-field-next-line ()
3017 "Set point to the first field in the next line."
3018 (interactive)
3019 (if (< (point) View-process-output-start)
3020 (View-process-output-start)
3021 (forward-line)
3022 (if (>= (point) View-process-output-end)
3023 (View-process-output-start)
3024 (View-process-jump-to-field 1 View-process-max-fields))))
3025
3026
3027 ;;; buffer renaming
3028
3029 (defun View-process-rename-current-output-buffer (new-buffer-name)
3030 "Renames the ps output buffer to NEW-BUFFER-NAME."
3031 (interactive
3032 (let ((View-process-stop-motion-help t))
3033 (list
3034 (read-string "New PS output buffer name: "
3035 (generate-new-buffer-name
3036 (concat "*ps-"
3037 (or View-process-remote-host
3038 (getenv "HOSTNAME"))
3039 "*"))))))
3040 (if (not (string= mode-name View-process-mode-name))
3041 (error "ERROR: Not in a View-process-mode buffer!")
3042 (if (get-buffer new-buffer-name)
3043 (error "ERROR: Buffer %s exists!" new-buffer-name)
3044 (rename-buffer new-buffer-name)
3045 (setq View-process-buffer-name new-buffer-name)
3046 (if (or View-process-display-with-2-windows
3047 (get-buffer View-process-header-buffer-name))
3048 (let ((new-header-buffer-name
3049 (generate-new-buffer-name
3050 (concat (substring new-buffer-name 0 -1)
3051 " header*")))
3052 (buffer (current-buffer)))
3053 (set-buffer View-process-header-buffer-name)
3054 (rename-buffer new-header-buffer-name)
3055 (set-buffer buffer)
3056 (setq View-process-header-buffer-name new-header-buffer-name))
3057 ))))
3058
3059 ;;; For newer versions of field.el
3060 (if (not (fboundp 'sort-float-fields))
3061 (defalias 'sort-float-fields 'sort-numeric-fields))
3062
3063
3064 ;;; Display Functions
3065
3066 (defun View-process-header-mode ()
3067 "The mode of the buffer with the view process header."
3068 (set-syntax-table View-process-mode-syntax-table)
3069 (setq major-mode 'View-process-header-mode
3070 mode-name View-process-header-mode-name)
3071 (setq truncate-lines View-process-truncate-lines)
3072 ; (setq buffer-modeline (not View-process-header-mode-line-off))
3073 (view-process-switch-buffer-modeline (not View-process-header-mode-line-off))
3074 (run-hooks 'View-process-header-mode-hook)
3075 )
3076
3077 (defun View-process-top-window-p (&optional window)
3078 "Returns t, if the WINDOW is the top one.
3079 If WINDOW is nil, then the current window is tested."
3080 (eq 0 (car (cdr (window-pixel-edges window)))))
3081
3082 (defun View-process-change-display-type (display-with-2-windows)
3083 "If DISPLAY-WITH-2-WINDOWS is non nil, then a 2 windows display is used."
3084 (if display-with-2-windows
3085 (let ((window-size View-process-ps-header-window-size))
3086 (cond ((eq (count-windows 'NO-MINI) 1)
3087 ;; split window
3088 (split-window nil window-size)
3089 (select-window (next-window nil 'no-minibuf))
3090 )
3091 ((= (count-windows 'NO-MINI) 2)
3092 (if (View-process-top-window-p)
3093 (progn
3094 ;; delete other windows
3095 (delete-other-windows)
3096 ;; split window
3097 (split-window nil window-size))
3098 (select-window (next-window nil 'no-minibuf))
3099 ; (shrink-window (- (window-height) window-size))
3100 )
3101 (select-window (next-window nil 'no-minibuf))
3102 )
3103 ((> (count-windows 'NO-MINI) 2)
3104 ;; delete other windows
3105 (delete-other-windows)
3106 ;; split window
3107 (split-window nil window-size)
3108 (select-window (next-window nil 'no-minibuf))
3109 ))
3110 ;; copy header lines
3111 (let ((header-lines (buffer-substring (point-min)
3112 View-process-header-end))
3113 (buffer (get-buffer-create View-process-header-buffer-name)))
3114 (select-window (next-window nil 'no-minibuf))
3115 ;; load *ps-header* buffer in window
3116 (set-window-buffer (get-buffer-window (current-buffer)) buffer)
3117 (setq buffer-read-only nil)
3118 (erase-buffer)
3119 ;; insert header lines
3120 (insert header-lines)
3121 (setq buffer-read-only t)
3122 (goto-char (point-min))
3123 (View-process-header-mode)
3124 (if (not (= (window-height) window-size))
3125 (shrink-window (- (window-height) window-size)))
3126 (select-window (next-window nil 'no-minibuf))
3127 ))
3128 (let ((header-buffer (get-buffer View-process-header-buffer-name)))
3129 (if header-buffer
3130 (progn
3131 (if (get-buffer-window header-buffer)
3132 (delete-window (get-buffer-window header-buffer)))
3133 (kill-buffer header-buffer))))))
3134
3135 (defun View-process-toggle-display-with-2-windows (&optional arg)
3136 "Change whether the view process output is displayed with two windows.
3137 With ARG, set `View-process-display-with-2-windows' to t, if ARG is
3138 positive. ARG is a prefix arg."
3139 (interactive "P")
3140 (if arg
3141 (if (>= (prefix-numeric-value arg) 0)
3142 (setq View-process-display-with-2-windows t)
3143 (setq View-process-display-with-2-windows nil))
3144 (if View-process-display-with-2-windows
3145 (setq View-process-display-with-2-windows nil)
3146 (setq View-process-display-with-2-windows t)))
3147 (View-process-change-display-type View-process-display-with-2-windows)
3148 (if View-process-display-with-2-windows
3149 (View-process-toggle-hide-header '(1))
3150 (View-process-toggle-hide-header '(-1))))
3151
3152 (defun View-process-save-old-window-configuration ()
3153 "Saves the window configuration before the first call of view process."
3154 (if (not View-process-old-window-configuration)
3155 (setq View-process-old-window-configuration
3156 (current-window-configuration))
3157 ))
3158
3159 (defun View-process-hide-header (hide-header)
3160 "Hides the header lines in the view processes buffer, if HIDE-HEADER is t."
3161 (if hide-header
3162 (if (<= View-process-output-start (point-max))
3163 (narrow-to-region View-process-output-start (point-max))
3164 (narrow-to-region (point-max) (point-max)))
3165 (widen)))
3166
3167 (defun View-process-toggle-hide-header (&optional arg)
3168 "Change whether the header are hided.
3169 With ARG, set `View-process-hide-header' to t, if ARG is positive.
3170 ARG is a prefix arg."
3171 (interactive "P")
3172 (if arg
3173 (if (>= (prefix-numeric-value arg) 0)
3174 (setq View-process-hide-header t)
3175 (setq View-process-hide-header nil))
3176 (if View-process-hide-header
3177 (setq View-process-hide-header nil)
3178 (setq View-process-hide-header t)))
3179 (View-process-hide-header View-process-hide-header))
3180
3181 ;;; Misc. commands
3182
3183 (defun View-process-quit ()
3184 "Kills the *ps* buffer."
3185 (interactive)
3186 (if (y-or-n-p
3187 "Do you want really want to quit the view process mode? ")
3188 (progn
3189 (if (get-buffer View-process-buffer-name)
3190 (kill-buffer View-process-buffer-name))
3191 (if (or View-process-display-with-2-windows
3192 (get-buffer View-process-header-buffer-name))
3193 (kill-buffer View-process-header-buffer-name))
3194 (set-window-configuration View-process-old-window-configuration)
3195 (setq View-process-old-window-configuration nil)
3196 )))
3197
3198 (defun View-process-submit-bug-report ()
3199 "Submit via mail a bug report on View-process-mode."
3200 (interactive)
3201 (require 'reporter)
3202 (let ((bsd-or-system-v (View-process-bsd-or-system-v)))
3203 (reporter-submit-bug-report
3204 View-process-package-maintainer
3205 (concat View-process-package-name " " View-process-package-version)
3206 (list 'emacs-version
3207 'major-mode
3208 'View-process-buffer-name
3209 'View-process-header-buffer-name
3210 'View-process-sorter-and-filter
3211 'View-process-actual-sorter-and-filter
3212 'View-process-display-with-2-windows
3213 'View-process-hide-header
3214 'View-process-truncate-lines
3215 'View-process-motion-help
3216 'View-process-old-window-configuration
3217 'View-process-field-names
3218 'View-process-max-fields
3219 'View-process-output-start
3220 'View-process-output-end
3221 'View-process-header-start
3222 'View-process-header-end
3223 'View-process-host-names-and-system-types
3224 'View-process-remote-host
3225 'View-process-system-type
3226 'bsd-or-system-v
3227 'View-process-rsh-command
3228 'View-process-signal-command
3229 'View-process-status-command-switches-bsd
3230 'View-process-status-command-switches-system-v
3231 'View-process-status-last-command-switches
3232 'View-process-status-command
3233 'View-process-test-command
3234 'View-process-test-switches
3235 'View-process-uname-command
3236 'View-process-uname-switches
3237 )
3238 nil
3239 nil
3240 (concat
3241 "If it is possible, you should send this bug report from the buffer\n"
3242 "with the view process mode. Please answer the following questions.\n"
3243 "Which is the name of your system? \n"
3244 "Is your system a BSD Unix? \n"
3245 "Is your system a System V Unix? \n"
3246 "Describe your bug: "
3247 ))))
3248
3249 (defun View-process-display-version ()
3250 "Displays the current version of the mode."
3251 (interactive)
3252 (message "View Process Mode, %s, Author: Heiko Münkel."
3253 View-process-package-version))
3254
3255 (defun View-process-toggle-truncate-lines (&optional arg)
3256 "Change whether the lines in this buffer are truncated.
3257 With ARG, set `truncate-lines' to t, if ARG is positive.
3258 ARG is a prefix arg.
3259 It saves also the state of `truncate-lines' for the next
3260 view process command in `View-process-truncate-lines'.
3261 It truncates also the lines in the view process header buffer,
3262 if it is run in a view process mode buffer."
3263 (interactive "P")
3264 (if arg
3265 (if (>= (prefix-numeric-value arg) 0)
3266 (setq truncate-lines t)
3267 (setq truncate-lines nil))
3268 (if truncate-lines
3269 (setq truncate-lines nil)
3270 (setq truncate-lines t)))
3271 (setq View-process-truncate-lines truncate-lines)
3272 (setq-default View-process-truncate-lines truncate-lines)
3273 (if (and (eq major-mode 'View-process-mode)
3274 (or View-process-display-with-2-windows
3275 (get-buffer View-process-header-buffer-name)))
3276 (let ((buffer (current-buffer))
3277 (truncate truncate-lines))
3278 (set-buffer View-process-header-buffer-name)
3279 (setq truncate-lines truncate)
3280 (set-buffer buffer))))
3281
3282 (defun View-process-return-beginning-of-line ()
3283 "Returns the beginning of the current line.
3284 The point isn't changed."
3285 (save-excursion
3286 (beginning-of-line)
3287 (point)))
3288
3289 (defun View-process-return-end-of-line ()
3290 "Returns the end of the current line.
3291 The point isn't changed."
3292 (save-excursion
3293 (end-of-line)
3294 (point)))
3295
3296 (defun View-process-assoc-2th (key list)
3297 "Return non-nil if KEY is `equal' to the 2th of an element of LIST.
3298 The value is actually the element of LIST whose 2th is KEY."
3299 (cond ((not list) nil)
3300 ((equal (car (cdr (car list))) key) (car list))
3301 (t (View-process-assoc-2th key (cdr list)))))
3302
3303
3304 (defun View-process-replace-in-string (from-string
3305 to-string
3306 in-string
3307 &optional start)
3308 "Replace FROM-STRING with TO-STRING in IN-STRING.
3309 The optional argument START set the start position > 0.
3310 FROM-STRING is a regular expression."
3311 (setq start (or start 0))
3312 (let ((start-of-from-string (string-match from-string in-string start)))
3313 (if start-of-from-string
3314 (concat (substring in-string start start-of-from-string)
3315 to-string
3316 (View-process-replace-in-string from-string
3317 to-string
3318 in-string
3319 (match-end 0)))
3320 (substring in-string start))))
3321
3322
3323 (defun View-process-toggle-digit-bindings (&optional arg)
3324 "Change whether the digit keys sends signals to the processes.
3325 With ARG, set `View-process-digit-bindings-send-signal' to t,
3326 if ARG is positive. ARG is a prefix arg."
3327 (interactive "P")
3328 (if arg
3329 (if (>= (prefix-numeric-value arg) 0)
3330 (setq View-process-digit-bindings-send-signal t)
3331 (setq View-process-digit-bindings-send-signal nil))
3332 (if View-process-digit-bindings-send-signal
3333 (setq View-process-digit-bindings-send-signal nil)
3334 (setq View-process-digit-bindings-send-signal t)))
3335 (if View-process-digit-bindings-send-signal
3336 (progn
3337 (define-key View-process-mode-map "0"
3338 'undefined)
3339 (define-key View-process-mode-map "1"
3340 'View-process-send-key-as-signal-to-processes)
3341 (define-key View-process-mode-map "2"
3342 'View-process-send-key-as-signal-to-processes)
3343 (define-key View-process-mode-map "3"
3344 'View-process-send-key-as-signal-to-processes)
3345 (define-key View-process-mode-map "4"
3346 'View-process-send-key-as-signal-to-processes)
3347 (define-key View-process-mode-map "5"
3348 'View-process-send-key-as-signal-to-processes)
3349 (define-key View-process-mode-map "6"
3350 'View-process-send-key-as-signal-to-processes)
3351 (define-key View-process-mode-map "7"
3352 'View-process-send-key-as-signal-to-processes)
3353 (define-key View-process-mode-map "8"
3354 'View-process-send-key-as-signal-to-processes)
3355 (define-key View-process-mode-map "9"
3356 'View-process-send-key-as-signal-to-processes)
3357 )
3358 (define-key View-process-mode-map "0"
3359 'digit-argument)
3360 (define-key View-process-mode-map "1"
3361 'digit-argument)
3362 (define-key View-process-mode-map "2"
3363 'digit-argument)
3364 (define-key View-process-mode-map "3"
3365 'digit-argument)
3366 (define-key View-process-mode-map "4"
3367 'digit-argument)
3368 (define-key View-process-mode-map "5"
3369 'digit-argument)
3370 (define-key View-process-mode-map "6"
3371 'digit-argument)
3372 (define-key View-process-mode-map "7"
3373 'digit-argument)
3374 (define-key View-process-mode-map "8"
3375 'digit-argument)
3376 (define-key View-process-mode-map "9"
3377 'digit-argument)
3378 ))
3379
3380 (if View-process-digit-bindings-send-signal
3381 (View-process-toggle-digit-bindings 1)
3382 (View-process-toggle-digit-bindings -1))
3383
3384 (defun View-process-revert-buffer (&optional ignore-auto noconfirm)
3385 "Updates the view-process buffer with `View-process-status-update'."
3386 (View-process-status-update))
3387
3388
3389 ;;; Emacs version specific stuff
3390
3391 (if (View-process-xemacs-p)
3392 (require 'view-process-xemacs)
3393 (require 'view-process-emacs-19))
3394
3395
3396 ;;; face setting
3397
3398 (if (facep 'View-process-child-line-face)
3399 nil
3400 (make-face 'View-process-child-line-face)
3401 (if (View-process-search-color View-process-child-line-foreground)
3402 (set-face-foreground 'View-process-child-line-face
3403 (View-process-search-color
3404 View-process-child-line-foreground)))
3405 (if (View-process-search-color View-process-child-line-background)
3406 (set-face-background 'View-process-child-line-face
3407 (View-process-search-color
3408 View-process-child-line-background)))
3409 (set-face-font 'View-process-child-line-face
3410 View-process-child-line-font)
3411 (set-face-underline-p 'View-process-child-line-face
3412 View-process-child-line-underline-p))
3413
3414 (if (facep 'View-process-parent-line-face)
3415 nil
3416 (make-face 'View-process-parent-line-face)
3417 (if (View-process-search-color View-process-parent-line-foreground)
3418 (set-face-foreground 'View-process-parent-line-face
3419 (View-process-search-color
3420 View-process-parent-line-foreground)))
3421 (if (View-process-search-color View-process-parent-line-background)
3422 (set-face-background 'View-process-parent-line-face
3423 (View-process-search-color
3424 View-process-parent-line-background)))
3425 (set-face-font 'View-process-parent-line-face
3426 View-process-parent-line-font)
3427 (set-face-underline-p 'View-process-parent-line-face
3428 View-process-parent-line-underline-p))
3429
3430 (if (facep 'View-process-single-line-face)
3431 nil
3432 (make-face 'View-process-single-line-face)
3433 (if (View-process-search-color View-process-single-line-foreground)
3434 (set-face-foreground 'View-process-single-line-face
3435 (View-process-search-color
3436 View-process-single-line-foreground)))
3437 (if (View-process-search-color View-process-single-line-background)
3438 (set-face-background 'View-process-single-line-face
3439 (View-process-search-color
3440 View-process-single-line-background)))
3441 (set-face-font 'View-process-single-line-face
3442 View-process-single-line-font)
3443 (set-face-underline-p 'View-process-single-line-face
3444 View-process-single-line-underline-p))
3445
3446 (if (facep 'View-process-signaled-line-face)
3447 nil
3448 (make-face 'View-process-signaled-line-face)
3449 (if (View-process-search-color View-process-signaled-line-foreground)
3450 (set-face-foreground 'View-process-signaled-line-face
3451 (View-process-search-color
3452 View-process-signaled-line-foreground)))
3453 (if (View-process-search-color View-process-signaled-line-background)
3454 (set-face-background 'View-process-signaled-line-face
3455 (View-process-search-color
3456 View-process-signaled-line-background)))
3457 (set-face-font 'View-process-signaled-line-face
3458 View-process-signaled-line-font)
3459 (set-face-underline-p 'View-process-signaled-line-face
3460 View-process-signaled-line-underline-p))
3461
3462 (if (facep 'View-process-signal-line-face)
3463 nil
3464 (make-face 'View-process-signal-line-face)
3465 (if (View-process-search-color View-process-signal-line-foreground)
3466 (set-face-foreground 'View-process-signal-line-face
3467 (View-process-search-color
3468 View-process-signal-line-foreground)))
3469 (if (View-process-search-color View-process-signal-line-background)
3470 (set-face-background 'View-process-signal-line-face
3471 (View-process-search-color
3472 View-process-signal-line-background)))
3473 (set-face-font 'View-process-signal-line-face
3474 View-process-signal-line-font)
3475 (set-face-underline-p 'View-process-signal-line-face
3476 View-process-signal-line-underline-p))
3477
3478 (if (facep 'View-process-renice-line-face)
3479 nil
3480 (make-face 'View-process-renice-line-face)
3481 (if (View-process-search-color View-process-renice-line-foreground)
3482 (set-face-foreground 'View-process-renice-line-face
3483 (View-process-search-color
3484 View-process-renice-line-foreground)))
3485 (if (View-process-search-color View-process-renice-line-background)
3486 (set-face-background 'View-process-renice-line-face
3487 (View-process-search-color
3488 View-process-renice-line-background)))
3489 (set-face-font 'View-process-renice-line-face
3490 View-process-renice-line-font)
3491 (set-face-underline-p 'View-process-renice-line-face
3492 View-process-renice-line-underline-p))
3493
3494 (if (facep 'View-process-header-line-face)
3495 nil
3496 (make-face 'View-process-header-line-face)
3497 (if (View-process-search-color View-process-header-line-foreground)
3498 (set-face-foreground 'View-process-header-line-face
3499 (View-process-search-color
3500 View-process-header-line-foreground)))
3501 (if (View-process-search-color View-process-header-line-background)
3502 (set-face-background 'View-process-header-line-face
3503 (View-process-search-color
3504 View-process-header-line-background)))
3505 (set-face-font 'View-process-header-line-face
3506 View-process-header-line-font)
3507 (set-face-underline-p 'View-process-header-line-face
3508 View-process-header-line-underline-p))
3509
3510 (defun View-process-highlight-header-line ()
3511 "Highlights the headerline with the face `View-process-header-line-face'."
3512 (let ((extent
3513 (make-extent View-process-header-start View-process-header-end)
3514 ))
3515 (set-extent-face extent 'View-process-header-line-face)
3516 (set-extent-property extent 'duplicable t))
3517 )
3518
3519 ;;; A short cut for the View-process-status command
3520
3521 (defalias 'ps 'View-process-status)
3522
3523 ;;; view-process-mode.el ends here