org-brain icon indicating copy to clipboard operation
org-brain copied to clipboard

[Suggest] Add org-brain-merge feature

Open tumashu opened this issue 4 years ago • 1 comments

Merging two entry to one seem to be a usful feature, at the moment, I use the below function in my config:

(defun eh-org-brain-merge (entry1 entry2)
  "Merge ENTRY2 to ENTRY1, and set ENTRY2's title as a nickname of ENTRY1."
  (let ((title2 (org-brain-title entry2))
        (entry1-id (nth 2 entry1))
        (entry2-id (nth 2 entry2))
        (entry2-parent (org-brain-parents entry2))
        (entry2-children (org-brain-children entry2))
        (entry2-friends (org-brain-friends entry2))
        (entry1-tags (org-brain-get-tags entry1))
        (entry2-tags (org-brain-get-tags entry2)))
    ;; Merge tags
    (when entry2-tags
      (org-with-point-at (org-brain-entry-marker entry1)
        (org-set-tags (delete-dups (remove nil `(,@entry1-tags ,@entry2-tags))))))
    ;; Merge parent, children and friends1
    (org-brain-add-parent entry1 entry2-parent)
    (org-brain-add-child entry1 entry2-children)
    (org-brain-add-friendship entry1 entry2-friends)
    ;; Merge org brain resources
    (dolist (link (org-brain-resources entry2))
      (org-brain-add-resource
       (car link)
       (format "%s: %s" title2 (cdr link))
       nil entry1))
    ;; Merge org brain text
    (let ((text (org-brain-text entry2)))
      (when (> (length (replace-regexp-in-string "[[:space:]\n]+" "" text)) 0)
        (org-with-point-at (org-brain-entry-marker entry1)
          (save-excursion
            (org-back-to-heading t)
            (org-end-of-subtree t t)
            (when (org-at-heading-p) (backward-char 1))
            (insert text)))))
    ;; Merge attachment
    (let ((attach (org-with-point-at (org-brain-entry-marker entry2)
                    (org-attach-dir))))
      (when attach
        (org-brain-add-resource
         (format "file:%s" (file-name-as-directory attach))
         (format "%s: /" title2)
         nil entry1)))
    ;; Merge edge
    (dolist (e `(,@entry2-parent ,@entry2-children ,@entry2-friends))
      (let* ((id (nth 2 e))
             (entry2-edge
              (org-with-point-at (org-brain-entry-marker entry2)
                (org-entry-get
                 (org-brain-entry-marker entry2)
                 (format "BRAIN_EDGE_%s" id)))))
        (when entry2-edge
          (let ((m (org-brain-entry-marker entry1)))
            (org-with-point-at m
              (org-entry-put m (format "BRAIN_EDGE_%s" id) entry2-edge)))
          (let ((m (org-brain-entry-marker e)))
            (org-with-point-at m
              (org-entry-put
               m (format "BRAIN_EDGE_%s" entry1-id)
               (org-entry-get m (format "BRAIN_EDGE_%s" entry2-id))))))))
    (org-brain-delete-entry entry2 t)
    (org-brain-add-nickname entry1 title2)
    (org-brain--revert-if-visualizing)))

tumashu avatar Jul 31 '20 00:07 tumashu

I haven't tried the function that you suggest, but I like the idea!

Kungsgeten avatar Aug 01 '20 16:08 Kungsgeten