Function: mh-process-commands

mh-process-commands is a byte-compiled function defined in mh-folder.el.gz.

Signature

(mh-process-commands FOLDER)

Documentation

Process outstanding commands for FOLDER.

This function runs mh-before-commands-processed-hook before the commands are processed and mh-after-commands-processed-hook after the commands are processed.

Source Code

;; Defined in /usr/src/emacs/lisp/mh-e/mh-folder.el.gz
(defun mh-process-commands (folder)
  "Process outstanding commands for FOLDER.

This function runs `mh-before-commands-processed-hook' before the
commands are processed and `mh-after-commands-processed-hook'
after the commands are processed."
  (message "Processing deletes and refiles for %s..." folder)
  (set-buffer folder)
  (with-mh-folder-updating (nil)
    ;; Run the before hook -- the refile and delete lists are still valid
    (run-hooks 'mh-before-commands-processed-hook)

    ;; Update the unseen sequence if it exists
    (mh-update-unseen)

    (let ((redraw-needed-flag mh-index-data)
          (folders-changed (list mh-current-folder))
          (seq-map (and
                    (or (and mh-refile-list mh-refile-preserves-sequences-flag)
                        (and mh-allowlist
                             mh-allowlist-preserves-sequences-flag))
                    (mh-create-sequence-map mh-seq-list)))
          (dest-map (and mh-refile-list mh-refile-preserves-sequences-flag
                         (make-hash-table)))
          (allow-map (and mh-allowlist mh-allowlist-preserves-sequences-flag
                          (make-hash-table))))
      ;; Remove invalid scan lines if we are in an index folder and then remove
      ;; the real messages
      (when mh-index-data
        (mh-index-delete-folder-headers)
        (setq folders-changed
              (append folders-changed (mh-index-execute-commands))))

      ;; Then refile messages
      (mapc (lambda (folder-msg-list)
              (let* ((dest-folder (symbol-name (car folder-msg-list)))
                     (last (car (mh-translate-range dest-folder "last")))
                     (msgs (cdr folder-msg-list)))
                (push dest-folder folders-changed)
                (setq redraw-needed-flag t)
                (apply #'mh-exec-cmd
                       "refile" "-src" folder dest-folder
                       (mh-coalesce-msg-list msgs))
                (mh-delete-scan-msgs msgs)
                ;; Preserve sequences in destination folder...
                (when mh-refile-preserves-sequences-flag
                  (clrhash dest-map)
                  (cl-loop
                   for i from (1+ (or last 0))
                   for msg in (sort (copy-sequence msgs) #'<)
                   do (cl-loop for seq-name in (gethash msg seq-map)
                               do (push i (gethash seq-name dest-map))))
                  (maphash
                   #'(lambda (seq msgs)
                       ;; Can't be run in the background, since the
                       ;; current folder is changed by mark this could
                       ;; lead to a race condition with the next refile.
                       (apply #'mh-exec-cmd "mark"
                              "-sequence" (symbol-name seq) dest-folder
                              "-add" (mapcar #'(lambda (x) (format "%s" x))
                                             (mh-coalesce-msg-list msgs))))
                   dest-map))))
            mh-refile-list)
      (setq mh-refile-list ())

      ;; Now delete messages
      (cond (mh-delete-list
             (setq redraw-needed-flag t)
             (apply #'mh-exec-cmd "rmm" folder
                    (mh-coalesce-msg-list mh-delete-list))
             (mh-delete-scan-msgs mh-delete-list)
             (setq mh-delete-list nil)))

      ;; Blocklist messages.
      (when mh-blocklist
        (let ((msg-list (mh-coalesce-msg-list mh-blocklist))
              (dest (mh-junk-blocklist-disposition)))
          (mh-junk-process-blocklist mh-blocklist)
          ;; TODO I wonder why mh-exec-cmd is used instead of the following:
          ;; (mh-refile-a-msg nil (intern dest))
          ;; (mh-delete-a-msg nil)))
          (if (null dest)
              (apply #'mh-exec-cmd "rmm" folder msg-list)
            (apply #'mh-exec-cmd "refile" "-src" folder dest msg-list)
            (push dest folders-changed))
          (setq redraw-needed-flag t)
          (mh-delete-scan-msgs mh-blocklist)
          (setq mh-blocklist nil)))

      ;; Allowlist messages.
      (when mh-allowlist
        (let ((msg-list (mh-coalesce-msg-list mh-allowlist))
              (last (car (mh-translate-range mh-inbox "last"))))
          (mh-junk-process-allowlist mh-allowlist)
          (apply #'mh-exec-cmd "refile" "-src" folder mh-inbox msg-list)
          (push mh-inbox folders-changed)
          (setq redraw-needed-flag t)
          (mh-delete-scan-msgs mh-allowlist)
          (when mh-allowlist-preserves-sequences-flag
            (clrhash allow-map)
            (cl-loop for i from (1+ (or last 0))
                     for msg in (sort (copy-sequence mh-allowlist) #'<)
                     do (cl-loop for seq-name in (gethash msg seq-map)
                                 do (push i (gethash seq-name allow-map))))
            (maphash
             (lambda (seq msgs)
               ;; Can't be run in background, since the current
               ;; folder is changed by mark this could lead to a
               ;; race condition with the next refile/allowlist.
               (apply #'mh-exec-cmd "mark"
                      "-sequence" (symbol-name seq) mh-inbox
                      "-add" (mapcar #'(lambda(x) (format "%s" x))
                                     (mh-coalesce-msg-list msgs))))
             allow-map))
          (setq mh-allowlist nil)))

      ;; Don't need to remove sequences since delete and refile do so.
      ;; Mark cur message
      (if (> (buffer-size) 0)
          (mh-define-sequence 'cur (list (or (mh-get-msg-num nil) "last"))))

      ;; Redraw folder buffer if needed
      (when (and redraw-needed-flag)
        (when (mh-speed-flists-active-p)
          (apply #'mh-speed-flists t folders-changed))
        (cond ((memq 'unthread mh-view-ops) (mh-thread-inc folder (point-max)))
              (mh-index-data (mh-index-insert-folder-headers))))

      (and (buffer-file-name (get-buffer mh-show-buffer))
           (not (file-exists-p (buffer-file-name (get-buffer mh-show-buffer))))
           ;; If "inc" were to put a new msg in this file,
           ;; we would not notice, so mark it invalid now.
           (mh-invalidate-show-buffer))

      (setq mh-seq-list (mh-read-folder-sequences mh-current-folder nil))
      (mh-remove-all-notation)
      (mh-notate-user-sequences)

      ;; Run the after hook -- now folders-changed is valid,
      ;; but not the lists of specific messages.
      (let ((mh-folders-changed folders-changed))
        (run-hooks 'mh-after-commands-processed-hook)))

    (message "Processing deletes and refiles for %s...done" folder)))