From 597b413de435e1d60d9a9902e3a2cd25210bb714 Mon Sep 17 00:00:00 2001 From: "Collin J. Doering" Date: Sun, 2 May 2021 13:16:21 -0400 Subject: [PATCH 1/4] org-ql-search.el: Extend org-dblock-write:org-ql to indicate query scope --- org-ql-search.el | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/org-ql-search.el b/org-ql-search.el index c60bd8e..0e15d3c 100644 --- a/org-ql-search.el +++ b/org-ql-search.el @@ -242,6 +242,15 @@ automatically from the query." "Insert content for org-ql dynamic block at point according to PARAMS. Valid parameters include: + :scope The scope to consider for the Org QL query. This can + be one of the following: + + `buffer' the current buffer + `org-agenda-files' all agenda files + `org-directory' all org files + `(list-of-files ...)' a list of org files + `all' all agenda files, and org-mode buffers + :query An Org QL query expression in either sexp or string form. @@ -271,13 +280,18 @@ Valid parameters include: For example, an org-ql dynamic block header could look like: #+BEGIN: org-ql :query (todo \"UNDERWAY\") :columns (priority todo heading) :sort (priority date) :ts-format \"%Y-%m-%d %H:%M\"" - (-let* (((&plist :query :columns :sort :ts-format :take) params) + (-let* (((&plist :scope :query :columns :sort :ts-format :take) params) (query (cl-etypecase query - (string (org-ql--query-string-to-sexp query)) + (string (org-ql--plain-query query)) (list ;; SAFETY: Query is in sexp form: ask for confirmation, because it could contain arbitrary code. (org-ql--ask-unsafe-query query) query))) (columns (or columns '(heading todo (priority "P")))) + (scope (cond ((listp scope) scope) + ((string-equal scope "org-agenda-files") (org-agenda-files)) + ((or (not scope) (string-equal scope "buffer")) (current-buffer)) + ((string-equal scope "org-directory") (org-ql-search-directories-files)) + (t (user-error "Unknown scope '%s'" scope)))) ;; MAYBE: Custom column functions. (format-fns ;; NOTE: Backquoting this alist prevents the lambdas from seeing @@ -285,9 +299,11 @@ For example, an org-ql dynamic block header could look like: (list (cons 'todo (lambda (element) (org-element-property :todo-keyword element))) (cons 'heading (lambda (element) - (org-make-link-string (org-element-property :raw-value element) - (org-link-display-format - (org-element-property :raw-value element))))) + (let ((m (plist-get (cadr element) :org-hd-marker))) + (with-current-buffer (marker-buffer m) + (save-excursion + (goto-char m) + (org-store-link nil nil)))))) (cons 'priority (lambda (element) (--when-let (org-element-property :priority element) (char-to-string it)))) @@ -299,9 +315,9 @@ For example, an org-ql dynamic block header could look like: (ts-format ts-format (ts-parse-org-element it))))) (cons 'property (lambda (element property) (org-element-property (intern (concat ":" (upcase property))) element))))) - (elements (org-ql-query :from (current-buffer) + (elements (org-ql-query :from scope :where query - :select '(org-element-headline-parser (line-end-position)) + :select 'element-with-markers :order-by sort))) (when take (setf elements (cl-etypecase take From 0045168ce1fb8e5bdca57b582c3ca8f9074335be Mon Sep 17 00:00:00 2001 From: Ihor Radchenko Date: Sun, 8 Aug 2021 16:46:05 +0800 Subject: [PATCH 2/4] Allow :file parameter in org-ql dynamic blocks --- org-ql-search.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/org-ql-search.el b/org-ql-search.el index 4fb5489..02af483 100644 --- a/org-ql-search.el +++ b/org-ql-search.el @@ -271,13 +271,14 @@ Valid parameters include: For example, an org-ql dynamic block header could look like: #+BEGIN: org-ql :query (todo \"UNDERWAY\") :columns (priority todo heading) :sort (priority date) :ts-format \"%Y-%m-%d %H:%M\"" - (-let* (((&plist :query :columns :sort :ts-format :take) params) + (-let* (((&plist :query :columns :sort :ts-format :take :file) params) (query (cl-etypecase query (string (org-ql--query-string-to-sexp query)) (list ;; SAFETY: Query is in sexp form: ask for confirmation, because it could contain arbitrary code. (org-ql--ask-unsafe-query query) query))) (columns (or columns '(heading todo (priority "P")))) + (file (or file (current-buffer))) ;; MAYBE: Custom column functions. (format-fns ;; NOTE: Backquoting this alist prevents the lambdas from seeing @@ -302,7 +303,7 @@ For example, an org-ql dynamic block header could look like: (ts-format ts-format (ts-parse-org-element it))))) (cons 'property (lambda (element property) (org-element-property (intern (concat ":" (upcase property))) element))))) - (elements (org-ql-query :from (current-buffer) + (elements (org-ql-query :from file :where query :select '(org-element-headline-parser (line-end-position)) :order-by sort))) From 888876594bf97dbbdffe0ba6d1d786ff136e71bb Mon Sep 17 00:00:00 2001 From: Ihor Radchenko Date: Mon, 4 Oct 2021 15:00:46 +0800 Subject: [PATCH 3/4] Clarify accepted value for list of files in :scope --- org-ql-search.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org-ql-search.el b/org-ql-search.el index c8298c1..dbd3b7b 100644 --- a/org-ql-search.el +++ b/org-ql-search.el @@ -248,7 +248,7 @@ Valid parameters include: `buffer' the current buffer `org-agenda-files' all agenda files `org-directory' all org files - `(list-of-files ...)' a list of org files + `(\"path\" ...)' list of buffer names or file paths `all' all agenda files, and org-mode buffers :query An Org QL query expression in either sexp or string @@ -287,7 +287,7 @@ For example, an org-ql dynamic block header could look like: (org-ql--ask-unsafe-query query) query))) (columns (or columns '(heading todo (priority "P")))) - (scope (cond ((listp scope) scope) + (scope (cond ((and (listp scope) (seq-every-p #'stringp scope)) scope) ((string-equal scope "org-agenda-files") (org-agenda-files)) ((or (not scope) (string-equal scope "buffer")) (current-buffer)) ((string-equal scope "org-directory") (org-ql-search-directories-files)) From 9d0712a17a450465ef7c8e62be1923b32db2286c Mon Sep 17 00:00:00 2001 From: Ihor Radchenko Date: Mon, 4 Oct 2021 15:20:09 +0800 Subject: [PATCH 4/4] Use valid links to other files --- org-ql-search.el | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/org-ql-search.el b/org-ql-search.el index dbd3b7b..2e75ded 100644 --- a/org-ql-search.el +++ b/org-ql-search.el @@ -299,9 +299,19 @@ For example, an org-ql dynamic block header could look like: (list (cons 'todo (lambda (element) (org-element-property :todo-keyword element))) (cons 'heading (lambda (element) - (org-make-link-string (org-element-property :raw-value element) - (org-link-display-format - (org-element-property :raw-value element))))) + (cond + ((and org-id-link-to-org-use-id + (org-element-property :ID element)) + (org-make-link-string (format "id:%s" (org-element-property :ID element)) + (org-element-property :raw-value element))) + ((org-element-property :file element) + (org-make-link-string (format "file:%s::*%s" + (org-element-property :file element) + (org-element-property :raw-value element)) + (org-element-property :raw-value element))) + (t (org-make-link-string (org-element-property :raw-value element) + (org-link-display-format + (org-element-property :raw-value element))))))) (cons 'priority (lambda (element) (--when-let (org-element-property :priority element) (char-to-string it)))) @@ -318,7 +328,7 @@ For example, an org-ql dynamic block header could look like: (org-element-property (intern (concat ":" (upcase property))) element))))) (elements (org-ql-query :from scope :where query - :select '(org-element-headline-parser (line-end-position)) + :select '(org-element-put-property (org-element-headline-parser (line-end-position)) :file (buffer-file-name)) :order-by sort))) (when take (setf elements (cl-etypecase take