Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agenda entries are missing properties necessary for view filtering #370

Open
anpandey opened this issue Sep 17, 2023 · 5 comments
Open

Agenda entries are missing properties necessary for view filtering #370

anpandey opened this issue Sep 17, 2023 · 5 comments

Comments

@anpandey
Copy link
Contributor

For agenda entries generated by an org-ql-block query, the entries themselves are missing a few properties necessary for filtering the agenda view using Org's built-in functionality. For example, org-agenda-filter-by-effort expects a txt property for each entry and org-agenda-filter-by-category can't find the necessary category at the current point. For fixing filtering by effort, you can advise org-ql-view--format-element to inject the required txt property (which in turn has the necessary effort-minutes property):

(defun my/org-ql-view--format-element (orig-fun &rest args)
  (if (not args)
      ""
    (let* ((element args)
           (properties (cadar element))
           (result (apply orig-fun element))
           (effort (org-entry-get (plist-get properties :org-marker) "Effort"))
           (effort-minutes (if effort (org-duration-to-minutes effort) nil))
           ;; Attempts to emulate the txt properties of each entry. Only sets
           ;; effort-minutes.
           (txt (if effort-minutes
                 (propertize "dummy" 'effort-minutes effort-minutes)
                 "dummy")))
      (org-add-props result (list 'txt txt)))))
(advice-add 'org-ql-view--format-element :around #'my/org-ql-view--format-element)

Ideally, we would be able to reuse whatever Org does to set these properties and set what is necessary for the filtering commands that don't work (as far as I can tell it's only by effort and category).

Also potentially related to #294 which mentions the missing txt property.

@alphapapa
Copy link
Owner

alphapapa commented Sep 17, 2023

Yes, as the comment here says:

org-ql/org-ql-view.el

Lines 821 to 823 in 1314078

(defun org-ql-view--format-element (element)
;; This essentially needs to do what `org-agenda-format-item' does,
;; which is a lot. We are a long way from that, but it's a start.

Patches to remedy that shortcoming are welcome, as long as they don't impact performance too badly.

OTOH, for this specific example, it would almost seem more sensible to adjust the search query to account for the effort or category. After all, filtering results after the search is equivalent to adjusting the query to return more specific results in the first place. Implementing filtering on top of searching seems like spending effort to implement two different ways of doing the same thing.

@anpandey
Copy link
Contributor Author

I agree, I think the fact that org-ql already allows filtering by category and effort probably doesn't make this issue too important to address. My use case is also a little bit obscure: from a single org-ql query, I'd like to quickly filter entries based on their efforts, which org-agenda-filter-by-effort has a UI to let you do so. Re-using that UI instead of building something to interactively edit the query seemed like the easiest thing to do. At the very least, having entries behave more consistently with org-generated entries would be nice.

Also, for category, it seems like Org just uses the property org-category.

@alphapapa
Copy link
Owner

Well, I can see how additional quick filtering could be useful, so I'm not opposed to supporting it, given the conditions I mentioned. Thanks.

@alphapapa alphapapa self-assigned this Sep 18, 2023
@mirkov
Copy link

mirkov commented Nov 4, 2023

I also encountered this issue. My use case is to generate an agenda and filter by category.

My agenda covers many projects, each in its own category. I thus like to filter the agenda by category. Native agenda allows for this, while agenda generated by org-ql-block does not.

In the past I was using org's native tags-todo to build my agenda, but org-ql syntax is much more transparent. It also allows for more complex stuck projects that fit my needs much better :-)

I described the filtering issue in a Reddit Post.

Following alphapapa's suggestion, I modified the code in org-ql-view--format-element, also adding category in the output list like so (I guessed at the format):

(--> string
           ;; FIXME: Use proper prefix
           (concat "  " it)
           (org-add-props it properties
             'org-agenda-type 'search
             'category category  ; <----- MV mod ***
             'todo-state todo-keyword
             'tags tag-list
             'org-habit-p habit-property))

That did not enable editing by category: categories were not present in the block agenda.

@anpandey
Copy link
Contributor Author

anpandey commented Nov 5, 2023

@mirkov Org uses org-category instead of just category, so you probably need to use that property instead (you can do C-u C-x = on a regular agenda entry to see all the properties that Org sets).

This is what I've been using to add support for filtering by category. It also adds effort and timestamp date type:

(defun my/org-ql-view--format-element (orig-fun &rest args)
  "This function will intercept the original function and
add the effort and category to the result.

ARGS is `element' in `org-ql-view--format-element'"
  (if (not args)
      ""
    (let* ((element args)
           (properties (cadar element))
           (result (apply orig-fun element))
           (effort (org-entry-get (plist-get properties :org-marker) "Effort"))
           ;; XXX: Category might already be included in the plist.
           (category (org-entry-get (plist-get properties :org-marker) "CATEGORY"))
           (effort-minutes (if effort (org-duration-to-minutes effort) nil))
           ;; Attempts to emulate the txt properties of each entry. Only sets
           ;; effort-minutes.
           (txt (if effort-minutes
                    (propertize "dummy" 'effort-minutes effort-minutes)
                  "dummy"))
           (ts-date-pair (org-with-point-at (plist-get properties :org-marker)
                           (org-agenda-entry-get-agenda-timestamp (point))))
           (ts-date (car ts-date-pair))
           ;; This string looks something like " scheduled". It is meant to be
           ;; concatted with a type to make something like "todo scheduled", but
           ;; we only care about the "scheduled" part.
           (ts-date-type (cdr ts-date-pair)))
      (org-add-props result
          (list 'txt txt
                'org-category category
                'ts-date ts-date
                'type ts-date-type)))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants