Function: proced-update

proced-update is an interactive and byte-compiled function defined in proced.el.gz.

Signature

(proced-update &optional REVERT QUIET)

Documentation

Update the Proced process information. Preserves point and marks.

With prefix REVERT non-nil, revert listing. Suppress status information if QUIET is nil. After updating a displayed Proced buffer run the normal hook proced-post-display-hook.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/proced.el.gz
(defun proced-update (&optional revert quiet)
  "Update the Proced process information.  Preserves point and marks.
With prefix REVERT non-nil, revert listing.
Suppress status information if QUIET is nil.
After updating a displayed Proced buffer run the normal hook
`proced-post-display-hook'."
  ;; This is the main function that generates and updates the process listing.
  (interactive "P" proced-mode)
  (setq revert (or revert (not proced-process-alist)))
  (or quiet (message (if revert "Updating process information..."
                       "Updating process display...")))
  (if revert ;; evaluate all processes
      (setq proced-process-alist (proced-process-attributes)))
  ;; filtering
  (setq proced-process-alist (proced-filter proced-process-alist proced-filter))
  ;; refinements
  (pcase-dolist (`(,refiner ,pid ,key ,grammar) proced-refinements)
    ;; It's possible the process has exited since the refinement was made
    (when (assq pid proced-process-alist)
      (cond ((functionp (car refiner))
             (setq proced-process-alist (funcall (car refiner) pid)))
            ((consp refiner)
             (let ((predicate (nth 4 grammar))
                   (ref (cdr (assq key (cdr (assq pid proced-process-alist)))))
                   val new-alist)
               (dolist (process proced-process-alist)
                 (setq val (funcall predicate (cdr (assq key (cdr process))) ref))
                 (when (cond ((not val) (nth 2 refiner))
                             ((eq val 'equal) (nth 1 refiner))
                             (val (car refiner)))
                   (push process new-alist)))
               (setq proced-process-alist new-alist))))))

  ;; sorting
  (setq proced-process-alist
        (proced-sort proced-process-alist proced-sort proced-descend))

  ;; display as process tree?
  (setq proced-process-alist
        (proced-tree proced-process-alist))

  ;; It is useless to keep undo information if we revert, filter, or
  ;; refine the listing so that `proced-process-alist' has changed.
  ;; We could keep the undo information if we only re-sort the buffer.
  ;; Would that be useful?  Re-re-sorting is easy, too.
  (if (consp buffer-undo-list)
      (setq buffer-undo-list nil))
  (let ((buffer-undo-list t)
        (window-pos-infos
         (mapcar (lambda (w) `(,w . ,(proced--position-info (window-point w))))
                 (get-buffer-window-list (current-buffer) nil t)))
        (old-pos (proced--position-info (point)))
        buffer-read-only mp-list)
    ;; remember marked processes (whatever the mark was)
    (goto-char (point-min))
    (while (re-search-forward "^\\(\\S-\\)" nil t)
      (push (cons (save-match-data (proced-pid-at-point))
                  (match-string-no-properties 1)) mp-list))

    ;; generate listing
    (erase-buffer)
    (proced-format proced-process-alist proced-format)
    (goto-char (point-min))
    (while (not (eobp))
      (insert "  ")
      (forward-line))
    (setq proced-header-line (concat "  " proced-header-line))
    (if revert (set-buffer-modified-p nil))

    ;; set `goal-column'
    (let ((grammar (assq proced-goal-attribute proced-grammar-alist)))
      (setq goal-column ;; set to nil if no match
            (if (and grammar
                     (not (zerop (buffer-size)))
                     (string-match (regexp-quote (nth 1 grammar))
                                   proced-header-line))
                (if (nth 3 grammar)
                    (match-beginning 0)
                  (match-end 0)))))

    ;; Restore process marks and buffer position (if possible).
    ;; Sometimes this puts point in the middle of the proced buffer
    ;; where it is not interesting.  Is there a better / more flexible solution?
    (goto-char (point-min))

    (let (pid mark new-pos win-points)
      (if (or mp-list (car old-pos))
          (while (not (eobp))
            (setq pid (proced-pid-at-point))
            (when (setq mark (assq pid mp-list))
              (insert (cdr mark))
              (delete-char 1)
              (beginning-of-line))
            (when (eq (car old-pos) pid)
              (setq new-pos (proced--determine-pos (nth 1 old-pos)
                                                   (nth 2 old-pos))))
            (mapc (lambda (w-pos)
                    (when (eq (cadr w-pos) pid)
                      (push `(,(car w-pos) . ,(proced--determine-pos
                                               (nth 1 (cdr w-pos))
                                               (nth 2 (cdr w-pos))))
                            win-points)))
                  window-pos-infos)
            (forward-line)))
      (let ((fallback (save-excursion (goto-char (point-min))
                                      (proced-move-to-goal-column)
                                      (point))))
        (goto-char (or new-pos fallback))
        ;; Update window points
        (mapc (lambda (w-pos)
                (set-window-point (car w-pos)
                                  (alist-get (car w-pos) win-points fallback)))
              window-pos-infos)))
    ;; update mode line
    ;; Does the long `mode-name' clutter the mode line?  It would be nice
    ;; to have some other location for displaying the values of the various
    ;; flags that affect the behavior of proced (flags one might want
    ;; to change on the fly).  Where??
    (setq mode-name
          (concat "Proced"
                  (if proced-filter
                      (format ": %S" proced-filter)
                    "")
                  (if proced-sort
                      (let* ((key (if (consp proced-sort) (car proced-sort)
                                    proced-sort))
                             (grammar (assq key proced-grammar-alist)))
                        (concat " by " (if proced-descend "-" "+")
                                (nth 1 grammar)))
                    "")))
    (force-mode-line-update)
    ;; run `proced-post-display-hook' only for a displayed buffer.
    (if (get-buffer-window) (run-hooks 'proced-post-display-hook))
    ;; done
    (or quiet (input-pending-p)
        (message (if revert "Updating process information...done."
                   "Updating process display...done.")))))