Function: mh-thread-prune-containers

mh-thread-prune-containers is a byte-compiled function defined in mh-thread.el.gz.

Signature

(mh-thread-prune-containers ROOTS)

Documentation

Prune empty containers in the containers ROOTS.

Source Code

;; Defined in /usr/src/emacs/lisp/mh-e/mh-thread.el.gz
(defun mh-thread-prune-containers (roots)
  "Prune empty containers in the containers ROOTS."
  (let ((dfs-ordered-nodes ())
        (work-list roots))
    (while work-list
      (let ((node (pop work-list)))
        (dolist (child (mh-container-children node))
          (push child work-list))
        (push node dfs-ordered-nodes)))
    (while dfs-ordered-nodes
      (let ((node (pop dfs-ordered-nodes)))
        (cond ((gethash (mh-message-id (mh-container-message node))
                        mh-thread-id-index-map)
               ;; Keep it
               (setf (mh-container-children node)
                     (mh-thread-sort-containers (mh-container-children node))))
              ((and (mh-container-children node)
                    (or (null (cdr (mh-container-children node)))
                        (mh-container-parent node)))
               ;; Promote kids
               (let ((children ()))
                 (dolist (kid (mh-container-children node))
                   (mh-thread-remove-parent-link kid)
                   (mh-thread-add-link (mh-container-parent node) kid)
                   (push kid children))
                 (push `(PROMOTE ,node ,(mh-container-parent node) ,@children)
                       mh-thread-history)
                 (mh-thread-remove-parent-link node)))
              ((mh-container-children node)
               ;; Promote the first orphan to parent and add the other kids as
               ;; his children
               (setf (mh-container-children node)
                     (mh-thread-sort-containers (mh-container-children node)))
               (let ((new-parent (car (mh-container-children node)))
                     (other-kids (cdr (mh-container-children node))))
                 (mh-thread-remove-parent-link new-parent)
                 (dolist (kid other-kids)
                   (mh-thread-remove-parent-link kid)
                   (setf (mh-container-real-child-p kid) nil)
                   (mh-thread-add-link new-parent kid t))
                 (push `(PROMOTE ,node ,(mh-container-parent node)
                                 ,new-parent ,@other-kids)
                       mh-thread-history)
                 (mh-thread-remove-parent-link node)))
              (t
               ;; Drop it
               (push `(DROP ,node ,(mh-container-parent node))
                     mh-thread-history)
               (mh-thread-remove-parent-link node)))))
    (let ((results ()))
      (maphash (lambda (_k v)
                 (when (and (null (mh-container-parent v))
                            (gethash (mh-message-id (mh-container-message v))
                                     mh-thread-id-index-map))
                   (push v results)))
               mh-thread-id-table)
      (mh-thread-sort-containers results))))