Kungsgeten / org-brain

Org-mode wiki + concept-mapping
MIT License
1.73k stars 103 forks source link

Include / Exclude headings : Restrict the brain using properties and tags #253

Open theottm opened 4 years ago

theottm commented 4 years ago

Would it be possible to restrict the headlines in the brain not only by tag but also by properties ? I see that in https://github.com/Kungsgeten/org-brain/blob/8cb2efc86026f0dcd19a63aef97044131682eba5/org-brain.el#L557-L561 that the variable org-brain--ql-query is defined so that it avoid specific tags. Would it be enough to add restrictions here ?

theottm commented 4 years ago

Well I tried it out and it worked. I just added (property "REF") after (property "ID") and now org-brain-add-parents candidates are limited to headings with the REF property, wonderful! I'm not that well informed about how to use org-ql. What would it take to also restrict to specific values of that property ? Do you think this hack could be easy to implement as a variable ?

theottm commented 4 years ago

And could it even be possible to restrict to a regexp ?

Kungsgeten commented 4 years ago

Hi! I think these questions are more suited to the org-ql package. Have a look at the documentation there.

theottm commented 4 years ago

Ok I will have a look there ! I'll post things here when I get proper results.

theottm commented 4 years ago

So for now, to restrict my brain to entries having a specific PROPERTY, I put this in my .emacs

(setq org-brain--ql-query '(and (property "ID") (property "NAME_OF_MY_PROPERTY") (not (or (tags org-brain-exclude-tree-tag) (tags-inherited org-brain-exclude-children-tag)))) )

I can write a defcustom if someone else has a need for this feature to be implemented.

theottm commented 4 years ago

Hello there !

since the last version of org-brain my hack doesn't work anymore because org-ql is not used anymore. What I want to do : by default I don't want entries to be part of the brain. So I want a mechanism to include headings and leave the rest out.

For now there is only a mechanism to exclude headings from the brain using tags. Would it be easy to add a mechanism to include headings with a specific tag or would it be to complicated ?

theottm commented 4 years ago

So I came up with a new solution, taking advantage of the fact that org-brain only considers headings having an ID. I wrote a function to remove the IDs from all headings that don't have a defined include tag. To avoid data to be lost, I avoid deleting IDs for headings that have an org-brain related PROPERTY. You can also filter using more properties.

(setq org-brain-include-heading-tag "brain")

(defun org-brain-update-file ()
  "Go through headings in current buffer and conditionaly adds or remove IDs."
  (interactive)
  (message
   "Went through %s headings."
   (length (org-map-entries (lambda ()
                              ;; add an id if heading is part of the brain or should be
                              (if (or (member "brain" (split-string (org-entry-get nil "TAGS") ":"))
                                      (org-entry-get nil "BRAIN_CHILDREN")
                                      (org-entry-get nil "BRAIN_PARENTS")
                                      (org-entry-get nil "BRAIN_FRIENDS"))
                                  (ignore-errors (org-id-get-create))
                                ;; print the headings for which IDs will be deleted
                                (message (format "%s" (org-entry-get nil "ITEM")))
                                ;; uncomment to delete irrelevant IDs (use with care)
                                ;; (org-entry-delete nil "ID")
                                )))
           ))
  (org-brain-update-id-locations)
  )

@Kungsgeten is this relevant enough to be pulled ?

Kungsgeten commented 4 years ago

I think it should work if you redefine org-brain-entry-at-point-excludedp. It currently look like this:

(defun org-brain-entry-at-point-excludedp ()
  "Return t if the entry at point is tagged as being excluded from org-brain."
  (let ((tags (org-get-tags)))
    (or (member org-brain-exclude-tree-tag tags)
        (and (member org-brain-exclude-children-tag tags)
             (not (member org-brain-exclude-children-tag
                          (org-get-tags nil t)))))))

You could update it like this:

(setq org-brain-include-heading-tag "brain")

(defun org-brain-entry-at-point-excludedp ()
  "Return t if the entry at point is tagged as being excluded from org-brain."
  (let ((tags (org-get-tags)))
    (or (not (member org-brain-include-heading-tag tags))
        (member org-brain-exclude-tree-tag tags)
        (and (member org-brain-exclude-children-tag tags)
             (not (member org-brain-exclude-children-tag
                          (org-get-tags nil t)))))))

This is a bit cumbersome to find out, so the README should probably mention it or there could be some kind of customization to do this.