alphapapa / org-ql

A searching tool for Org-mode, including custom query languages, commands, saved searches and agenda-like views, etc.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Subtree agenda restriction is ignored by org-ql-block

yantar92 opened this issue · comments

When I try to apply restriction to an agenda with org-ql-block, the buffer restriction works as expected, but not the subtree restriction. Instead of only listing matching items from the subtree, org-ql acts as if it was a buffer restriction.

This would probably be fixable, but IIRC the agenda restriction code is not so straightforward.

In general, the org-ql-block feature is not intended to be completely compatible with or to respect all agenda features. To make it so would defeat some of the purpose of org-ql, which is to reimplement some of the agenda's features (maybe most of them, eventually) in a more usable way. The org-ql-block feature exists because it is useful and was simple to implement to the current extent. I probably won't put much effort into adding compatibility with features like this, because I'd rather work on a better agenda-like view (e.g. the wip/view-section branch).

I see. May I know how the wip/view-section is different from the existing agenda?

I took another look at the Org Agenda restriction code and found that supporting it isn't as complicated as I expected. This seems to work. Please let me know how it works for you. Thanks.

I just tried the laterst git version of org-ql. Does not seem to work, even though your code looks reasonable. I tried to debug a bit and found that org-agenda-overriding-restriction was set to nil for some reason (within scope of org-ql-search-block).

As you can see in the code, org-agenda-overriding-restriction is not bound by this package. Please try to reproduce in emacs -q or emacs-sandbox.sh to ensure it's not a problem in your config.

I used the following init.el loaded after emacs -q:

(setq straight-repository-branch "develop")
(setq straight-vc-git-default-protocol 'ssh)
(eval-and-compile
  (defvar bootstrap-version)
  (let ((bootstrap-file
	 (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
	(bootstrap-version 5))
    (unless (file-exists-p bootstrap-file)
      (with-current-buffer
	  (url-retrieve-synchronously
	   "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
	   'silent 'inhibit-cookies)
	(goto-char (point-max))
	(eval-print-last-sexp)))
    (load bootstrap-file nil 'nomessage)))

(setq load-prefer-newer t)

(eval-and-compile
  (setq load-path (append '("~/.emacs.d/site-lisp/") load-path))
  (setq load-path (append (directory-files "~/.emacs.d/site-lisp/" t "^[^.]" t) load-path)))

(eval-and-compile (straight-use-package 'use-package))

(use-package org-ql
  :demand t
  :straight (org-ql :type git :host github :repo "alphapapa/org-ql")
  :init (use-package org-ql-search :demand t))

(defun yant/org-ql-focused-agenda-block (&rest args)
  "Return expression, suitable for `org-agenda-custom-commands', which matches focused agenda view."
  (org-ql-block
   '(and (todo)
	 (not (priority "C")))))

(add-to-list 'org-agenda-custom-commands
	     `("D" "Focused agenda (ql version)"
	       ((yant/org-ql-focused-agenda-block))
	       ((org-ql-block-header "Focused agenda(ql version)"))))

The "D" agenda should provide equivalent of default List of TODO entries. However, the org-ql version still gives todos from all the file, ignoring subtree restriction. If needed, I can also provide the .org file.

One blind guess is that org-ql-block does not have (require 'org-agenda), while org-agenda-overriding-restriction is defined in lexical scope of org-agenda.el only.

It works for me.

  • emacs-sandbox.sh -i org-ql.
  • Eval:
(setf org-agenda-custom-commands
      '(("x" ""
	 ((org-ql-block '(and (todo) (tags "Emacs")))))))
  • Open Org file, navigate to subtree.
  • M-x org-agenda-set-restriction-lock RET.
  • M-x org-agenda RET x.

Result: Only entries from the subtree are displayed.

One blind guess is that org-ql-block does not have (require 'org-agenda), while org-agenda-overriding-restriction is defined in lexical scope of org-agenda.el only.

No, org-agenda-overriding-restriction is a special variable defined in org-agenda.el, and org-agenda is already loaded by (require 'org-super-agenda). If that were not the case, a compile warning would be raised about an undefined variable.

M-x org-agenda-set-restriction-lock RET. also made it work for me. I was using M-x org-agenda < < D or < < t with point at the beginning of the subtree.

What command does < < call and what does it do?

Pressing < while Agenda Commands buffer is shown will cycle buffer restriction -> subtree restriction -> no restriction for the following agenda view.

I'm asking what Emacs command function is called by the code.

Here's what I see:

  • org-agenda-set-restriction-lock sets variable org-agenda-overriding-restriction.
  • org-agenda (search to comment ;; Establish the restriction, if any) does not set variable org-agenda-overriding-restriction. Other than that, it seems to do the same things that org-agenda-set-restriction-lock does.
  • Variable org-agenda-overriding-restriction is not documented, so its purpose in Org Agenda is unclear. However, it seems like the only way to determine whether the restriction is intended to be a subtree or a whole file.

Therefore I conclude that the fact that org-agenda does not set org-agenda-overriding-restriction may be an oversight and/or a bug that should be fixed. At least, having it set org-agenda-overriding-restriction would probably do no harm, and would enable other code to determine what the desired restriction mode is, which would make the < < sequence work here.

As well, the fact that some restriction-setting code seems to be duplicated in org-agenda and org-agenda-set-restriction-lock should probably be rectified. If the potential oversight I mentioned is indeed one, having the code duplicated contributed to it happening.

Would you be willing to file a report or raise the discussion on the Org list? I very rarely use Agenda restrictions myself.

I think that there is actually a way to determine if the restriction is set to file or subtree without a need to access to org-agenda-overriding-restriction. Looking at the code of org-agenda-set-restriction-lock and the place in org-agenda where org-agenda-get-restriction-and-command is called, I can conclude that all you need is three variables: org-agenda-restrict, org-agenda-restrict-begin, and org-agenda-restrict-end. The first variable is non-nil when either 'file or 'subtree/'region restriction is in use. However, the last two are only non-nil when subtree/region restriction is active.

Fixed in 0f5cf5e and 0.4.9. Thanks.