Add: Link support

This commit is contained in:
Adam Porter 2020-11-10 01:52:04 -06:00
parent c0a10ba96a
commit 992f3c2675
4 changed files with 271 additions and 54 deletions

View file

@ -69,6 +69,7 @@ Installing with [[https://framagit.org/steckerhalter/quelpa][Quelpa]] is easy:
- [[#datetime-predicates][Date/time predicates]] - [[#datetime-predicates][Date/time predicates]]
- [[#functions--macros][Functions / Macros]] - [[#functions--macros][Functions / Macros]]
- [[#dynamic-block][Dynamic block]] - [[#dynamic-block][Dynamic block]]
- [[#links][Links]]
- [[#tips][Tips]] - [[#tips][Tips]]
:END: :END:
@ -427,6 +428,19 @@ For example, this dynamic block shows the first seven headings that are to-do it
,#+END: ,#+END:
#+END_SRC #+END_SRC
** Links
Org QL View searches may be accessed by opening ~org-ql-search:~ links in an Org file.
In an Org QL View buffer, the command ~org-store-link~ (i.e. ~C-c l~) stores a link to the current search, and it may be inserted into an Org buffer with the command ~org-insert-link~ (~C-c C-l~). The stored link records all of the view settings, like title, sorting, and grouping.
Simple links may also be written manually in either sexp or non-sexp form, like:
#+BEGIN_SRC org
[[org-ql-search:todo:NEXT priority:A]]
[[org-ql-search:(and (todo "NEXT") (priority "A"))]]
#+END_SRC
** Tips ** Tips
+ Org QL View buffers can be bookmarked with Emacs bookmark commands, e.g. =C-x r m=. This also integrates with [[https://github.com/alphapapa/org-sidebar][org-sidebar]] and [[https://github.com/alphapapa/burly.el][Burly]]. + Org QL View buffers can be bookmarked with Emacs bookmark commands, e.g. =C-x r m=. This also integrates with [[https://github.com/alphapapa/org-sidebar][org-sidebar]] and [[https://github.com/alphapapa/burly.el][Burly]].
@ -445,6 +459,7 @@ For example, this dynamic block shows the first seven headings that are to-do it
+ Predicate =link=, which matches descriptions and targets in Org links. + Predicate =link=, which matches descriptions and targets in Org links.
+ Emacs bookmark support: Org QL View buffers can be bookmarked with, e.g. =C-x r m= and shown with, e.g. =C-x r b=. (This also enables view restoration with [[https://github.com/alphapapa/burly.el][Burly]].) + Emacs bookmark support: Org QL View buffers can be bookmarked with, e.g. =C-x r m= and shown with, e.g. =C-x r b=. (This also enables view restoration with [[https://github.com/alphapapa/burly.el][Burly]].)
+ Dynamic block support. + Dynamic block support.
+ Org link support (storing and opening links to Org QL View searches in the current document).
+ Mascot. + Mascot.
*Changed* *Changed*

128
notes.org
View file

@ -16,12 +16,15 @@
* [#A] Overview * [#A] Overview
** Underway
[[org-ql-search:%2528todo%2520%2522UNDERWAY%2522%2529?sort=%2528priority%2529&title=%2522Underway%2522][org-ql-search: Underway]]
#+BEGIN: org-ql :query (todo "UNDERWAY") :columns (priority todo heading) :sort (priority date) :ts-format "%Y-%m-%d %H:%M" #+BEGIN: org-ql :query (todo "UNDERWAY") :columns (priority todo heading) :sort (priority date) :ts-format "%Y-%m-%d %H:%M"
| Priority | Todo | Heading | | Priority | Todo | Heading |
|----------+----------+--------------------------------------------------------------------| |----------+----------+--------------------------------------------------------------------|
| A | UNDERWAY | [[Dynamic blocks][Dynamic blocks]] |
| A | UNDERWAY | [[Tools%20for%20saving%20queries%20and%20accessing%20them%20%5B3/4%5D][Tools for saving queries and accessing them {3/4}]] | | A | UNDERWAY | [[Tools%20for%20saving%20queries%20and%20accessing%20them%20%5B3/4%5D][Tools for saving queries and accessing them {3/4}]] |
| A | UNDERWAY | [[Org link types][Org link types]] | | A | UNDERWAY | [[Org%20link%20types%20%5B2/3%5D][Org link types {2/3}]] |
| A | UNDERWAY | [[Outline path predicate][Outline path predicate]] | | A | UNDERWAY | [[Outline path predicate][Outline path predicate]] |
| B | UNDERWAY | [[Recursive queries][Recursive queries]] | | B | UNDERWAY | [[Recursive queries][Recursive queries]] |
| B | UNDERWAY | [[Timeline view][Timeline view]] | | B | UNDERWAY | [[Timeline view][Timeline view]] |
@ -30,6 +33,19 @@
| | UNDERWAY | [[Benchmarking tags searches without and with new group-tags support][Benchmarking tags searches without and with new group-tags support]] | | | UNDERWAY | [[Benchmarking tags searches without and with new group-tags support][Benchmarking tags searches without and with new group-tags support]] |
#+END: #+END:
** To-do
[[org-ql-search:%2528and%2520%2528todo%2520%2522TODO%2522%2529%2520%2528priority%2520%2522A%2522%2529%2529?sort=%2528priority%2529&title=%2522To-do%2520%255B%2523A%255D%2522][org-ql-search: To-do {#A}]]
#+BEGIN: org-ql :query "todo:TODO priority:A" :columns (priority todo heading) :sort (priority date) :take 7
| Priority | Todo | Heading |
|----------+------+--------------------------------------------------------------|
| A | TODO | [[Add ~:auto~ keyword to ~(planning)~ predicate][Add ~:auto~ keyword to ~(planning)~ predicate]] |
| A | TODO | [[Document sorters][Document sorters]] |
| A | TODO | [[Org block to insert results of queries with links to entries][Org block to insert results of queries with links to entries]] |
| A | TODO | [[Change ~(deadline)~'s ~auto~ argument to ~:auto~ and/or ~:auto t~][Change ~(deadline)~'s ~auto~ argument to ~:auto~ and/or ~:auto t~]] |
#+END:
* [#A] Tasks * [#A] Tasks
:PROPERTIES: :PROPERTIES:
:TOC: :include descendants :depth 1 :TOC: :include descendants :depth 1
@ -49,7 +65,6 @@
- [[#org-agenda-skip-function][org-agenda-skip-function]] - [[#org-agenda-skip-function][org-agenda-skip-function]]
- [[#test-caching][Test caching]] - [[#test-caching][Test caching]]
- [[#update-commentary][Update commentary]] - [[#update-commentary][Update commentary]]
- [[#dynamic-blocks][Dynamic blocks]]
- [[#tools-for-saving-queries-and-accessing-them-34][Tools for saving queries and accessing them {3/4}]] - [[#tools-for-saving-queries-and-accessing-them-34][Tools for saving queries and accessing them {3/4}]]
- [[#outline-path-predicate][Outline path predicate]] - [[#outline-path-predicate][Outline path predicate]]
- [[#recursive-queries][Recursive queries]] - [[#recursive-queries][Recursive queries]]
@ -60,6 +75,7 @@
- [[#alternative-parsing-libraries][Alternative parsing libraries]] - [[#alternative-parsing-libraries][Alternative parsing libraries]]
- [[#fancier-searching-for-inherited-tags][Fancier searching for inherited tags]] - [[#fancier-searching-for-inherited-tags][Fancier searching for inherited tags]]
- [[#group-tag-support][Group tag support]] - [[#group-tag-support][Group tag support]]
- [[#dynamic-blocks][Dynamic blocks]]
- [[#helm-command][Helm command]] - [[#helm-command][Helm command]]
- [[#quickly-change-sortinggrouping-in-search-views][Quickly change sorting/grouping in search views]] - [[#quickly-change-sortinggrouping-in-search-views][Quickly change sorting/grouping in search views]]
- [[#byte-compile-lambdas][Byte-compile lambdas]] - [[#byte-compile-lambdas][Byte-compile lambdas]]
@ -194,13 +210,17 @@ See notes on 1dce9467f25428b5289d3665cd840820969ed65a. It would be good to test
+ Added example to =examples.org=. + Added example to =examples.org=.
*** UNDERWAY [#A] Org link types *** UNDERWAY [#A] Org link types [2/3]
:PROPERTIES: :PROPERTIES:
:ID: 4db73c1c-a4ed-425e-9e38-8d334ed03e1e :ID: 4db73c1c-a4ed-425e-9e38-8d334ed03e1e
:END: :END:
This would be useful for having a menu of saved queries as Org links, or even bookmarking saved queries. This would be useful for having a menu of saved queries as Org links, or even bookmarking saved queries.
**** TODO For saved queries
**** DONE For searches
[2020-11-08 Sun 22:59] Let's try a very simple implementation so I could write a link like this to search the current buffer: [2020-11-08 Sun 22:59] Let's try a very simple implementation so I could write a link like this to search the current buffer:
#+BEGIN_SRC org #+BEGIN_SRC org
@ -209,7 +229,7 @@ This would be useful for having a menu of saved queries as Org links, or even bo
[2020-11-08 Sun 23:22] Seems to work! [2020-11-08 Sun 23:22] Seems to work!
#+BEGIN_SRC elisp #+BEGIN_SRC elisp :results silent
;;;; Org link type ;;;; Org link type
;; This section adds a custom link type to Org. See info:org#Adding hyperlink types. ;; This section adds a custom link type to Org. See info:org#Adding hyperlink types.
@ -240,9 +260,103 @@ Tested on these queries:
+ [[org-ql-search:link:nullprogram]] + [[org-ql-search:link:nullprogram]]
#+END_SRC #+END_SRC
**** TODO For all parameters [2020-11-10 Tue 00:35] I'd like to support other parameters to the search, like grouping and sorting, so:
**** TODO For saved queries #+BEGIN_SRC elisp :results silent
;;;; Org link type
;; This section adds a custom link type to Org. See info:org#Adding hyperlink types.
(org-link-set-parameters "org-ql-search"
:follow #'org-ql-search--link-open
:store #'org-ql-search--link-store)
(defun org-ql-search--link-open (query)
"Open Org QL QUERY for current buffer."
(require 'url-parse)
(pcase-let* ((`(,query . ,params)
(url-path-and-query (url-parse-make-urlobj "org-ql-search" nil nil nil nil
query)))
(params (url-parse-query-string params))
;; Hacky or elegant?
(_ (mapc (lambda (pair)
(cl-callf (lambda (it)
(intern (concat ":" it)))
(car pair))
(cl-callf read (cdr pair)))
params))
(params (cl-loop for (key . value) in params
append (list key value))))
(apply #'org-ql-search (current-buffer) query params)))
(defun org-ql-search--link-store ()
"Store a link to current Org QL query."
(when org-ql-view-query
(org-store-link-props :type "org-ql-search"
:link (concat "org-ql-search:" (org-ql-view--format-query org-ql-view-query))
:description org-ql-view-title)
t))
#+END_SRC
That seems to work, like:
#+BEGIN_SRC org
[[org-ql-search:property:author="Chris%20Wellons"?super-groups=((:auto-outline-path%20t))]]
#+END_SRC
[2020-11-10 Tue 01:34] Okay, this seems to take care of all parameters:
#+BEGIN_SRC elisp
(defun org-ql-search--link-open (path)
"Open Org QL query for current buffer at PATH.
PATH should be the part of an \"org-ql-search:\" URL after the
protocol. See, e.g. `org-ql-search--link-store'."
(require 'url-parse)
(require 'url-util)
(pcase-let* ((`(,query . ,params) (url-path-and-query
(url-parse-make-urlobj "org-ql-search" nil nil nil nil
path)))
(query (url-unhex-string query))
(params (when params
(url-parse-query-string params)))
;; `url-parse-query-string' returns "improper" alists, which makes this awkward.
(sort (when (alist-get "sort" params nil nil #'string=)
(read (alist-get "sort" params nil nil #'string=))))
(groups (when (alist-get "super-groups" params nil nil #'string=)
(read (alist-get "super-groups" params nil nil #'string=))))
(title (when (alist-get "title" params nil nil #'string=)
(read (alist-get "title" params nil nil #'string=)))))
(org-ql-search (current-buffer) query
:sort sort
:super-groups groups
:title title)))
(defun org-ql-search--link-store ()
"Store a link to the current Org QL view.
Only views that search a single buffer may be linked to."
(require 'url-parse)
(require 'url-util)
(unless (or (bufferp org-ql-view-buffers-files) (= 1 (length org-ql-view-buffers-files)))
(user-error "Only views searching a single buffer may be linked"))
(when org-ql-view-query
(let* ((params (list (when org-ql-view-super-groups
(list "super-groups" (prin1-to-string org-ql-view-super-groups)))
(when org-ql-view-sort
(list "sort" (prin1-to-string org-ql-view-sort)))
(when org-ql-view-title
(list "title" (prin1-to-string org-ql-view-title)))))
(filename (concat (url-hexify-string (org-ql-view--format-query org-ql-view-query))
"?" (url-build-query-string (delete nil params))))
(url (url-recreate-url (url-parse-make-urlobj "org-ql-search" nil nil nil nil
filename))))
(org-store-link-props
:type "org-ql-search"
:link url
:description (concat "org-ql-search: " org-ql-view-title)))
t))
#+END_SRC
**** DONE For all parameters
*** DONE Bookmarks *** DONE Bookmarks

View file

@ -565,6 +565,68 @@ dates in the past, and negative for dates in the future."
;; more complicated and might introduce bugs elsewhere, so we'll just do this for now. ;; more complicated and might introduce bugs elsewhere, so we'll just do this for now.
(set-buffer (window-buffer (selected-window))))) (set-buffer (window-buffer (selected-window)))))
;;;; Links
;; This section implements support for Org links to Org QL searches. Since the
;; links are stored from and opened in `org-ql-view' buffers, this section resides
;; in this file. However, since the links are to `org-ql-search' searches rather
;; than `org-ql-view' saved views, the link type is "org-ql-search".
(org-link-set-parameters "org-ql-search"
:follow #'org-ql-view--link-open
:store #'org-ql-view--link-store)
;; We require the URL libraries in the functions to hopefully avoid
;; loading them until they're needed.
(defun org-ql-view--link-open (path)
"Open Org QL query for current buffer at PATH.
PATH should be the part of an \"org-ql-search:\" URL after the
protocol. See, e.g. `org-ql-view--link-store'."
(require 'url-parse)
(require 'url-util)
(pcase-let* ((`(,query . ,params) (url-path-and-query
(url-parse-make-urlobj "org-ql-search" nil nil nil nil
path)))
(query (url-unhex-string query))
(params (when params (url-parse-query-string params)))
;; `url-parse-query-string' returns "improper" alists, which makes this awkward.
(sort (--when-let (alist-get "sort" params nil nil #'string=)
(read it)))
(groups (--when-let (alist-get "super-groups" params nil nil #'string=)
(read it)))
(title (--when-let (alist-get "title" params nil nil #'string=)
(read it))))
(org-ql-search (current-buffer) query
:sort sort
:super-groups groups
:title title)))
(defun org-ql-view--link-store ()
"Store a link to the current Org QL view.
When opened, the link searches the buffer it's opened from."
(require 'url-parse)
(require 'url-util)
(unless (or (bufferp org-ql-view-buffers-files)
(= 1 (length org-ql-view-buffers-files)))
(user-error "Only views searching a single buffer may be linked"))
(when org-ql-view-query
(let* ((params (list (when org-ql-view-super-groups
(list "super-groups" (prin1-to-string org-ql-view-super-groups)))
(when org-ql-view-sort
(list "sort" (prin1-to-string org-ql-view-sort)))
(when org-ql-view-title
(list "title" (prin1-to-string org-ql-view-title)))))
(filename (concat (url-hexify-string (org-ql-view--format-query org-ql-view-query))
"?" (url-build-query-string (delete nil params))))
(url (url-recreate-url (url-parse-make-urlobj "org-ql-search" nil nil nil nil
filename))))
(org-store-link-props
:type "org-ql-search"
:link url
:description (concat "org-ql-search: " org-ql-view-title)))
t))
;;;; Transient ;;;; Transient
;; This section uses `transient' to allow the user to easily modify ;; This section uses `transient' to allow the user to easily modify

View file

@ -36,6 +36,7 @@ Usage
* Queries:: * Queries::
* Functions / Macros:: * Functions / Macros::
* Dynamic block:: * Dynamic block::
* Links::
* Tips:: * Tips::
Commands Commands
@ -155,7 +156,7 @@ File: README.info, Node: Usage, Next: Changelog, Prev: Installation, Up: Top
******* *******
• • • •
• • • • • • • • • • • • • •
Feedback on these APIs is welcome. Eventually, after being tested Feedback on these APIs is welcome. Eventually, after being tested
and polished, they will be considered stable. and polished, they will be considered stable.
@ -167,6 +168,7 @@ and polished, they will be considered stable.
* Queries:: * Queries::
* Functions / Macros:: * Functions / Macros::
* Dynamic block:: * Dynamic block::
* Links::
* Tips:: * Tips::
 
@ -713,7 +715,7 @@ File: README.info, Node: Listing / acting-on results, Prev: Agenda-like views,
For convenience, arguments should be unquoted. For convenience, arguments should be unquoted.
 
File: README.info, Node: Dynamic block, Next: Tips, Prev: Functions / Macros, Up: Usage File: README.info, Node: Dynamic block, Next: Links, Prev: Functions / Macros, Up: Usage
4.4 Dynamic block 4.4 Dynamic block
================= =================
@ -753,9 +755,30 @@ with certain columns and timestamp format:
#+END: #+END:
 
File: README.info, Node: Tips, Prev: Dynamic block, Up: Usage File: README.info, Node: Links, Next: Tips, Prev: Dynamic block, Up: Usage
4.5 Tips 4.5 Links
=========
Org QL View searches may be accessed by opening org-ql-search: links
in an Org file.
In an Org QL View buffer, the command org-store-link (i.e. C-c
l) stores a link to the current search, and it may be inserted into an
Org buffer with the command org-insert-link (C-c C-l). The stored
link records all of the view settings, like title, sorting, and
grouping.
Simple links may also be written manually in either sexp or non-sexp
form, like:
[[org-ql-search:todo:NEXT priority:A]]
[[org-ql-search:(and (todo "NEXT") (priority "A"))]]

File: README.info, Node: Tips, Prev: Links, Up: Usage
4.6 Tips
======== ========
• Org QL View buffers can be bookmarked with Emacs bookmark commands, • Org QL View buffers can be bookmarked with Emacs bookmark commands,
@ -810,6 +833,8 @@ File: README.info, Node: 05-pre, Next: 046, Up: Changelog
view restoration with Burly view restoration with Burly
(https://github.com/alphapapa/burly.el).) (https://github.com/alphapapa/burly.el).)
• Dynamic block support. • Dynamic block support.
• Org link support (storing and opening links to Org QL View searches
in the current document).
• Mascot. • Mascot.
*Changed* *Changed*
@ -1231,49 +1256,50 @@ GPLv3
 
Tag Table: Tag Table:
Node: Top225 Node: Top225
Node: Contents1539 Node: Contents1549
Node: Screenshots1662 Node: Screenshots1672
Node: Installation1780 Node: Installation1790
Node: Quelpa2418 Node: Quelpa2428
Node: Usage2861 Node: Usage2871
Node: Commands3245 Node: Commands3269
Node: org-ql-search3718 Node: org-ql-search3742
Node: helm-org-ql5432 Node: helm-org-ql5456
Node: org-ql-view5844 Node: org-ql-view5868
Node: org-ql-view-sidebar6344 Node: org-ql-view-sidebar6368
Node: org-ql-view-recent-items6700 Node: org-ql-view-recent-items6724
Node: org-ql-sparse-tree7184 Node: org-ql-sparse-tree7208
Node: Queries7984 Node: Queries8008
Node: Non-sexp query syntax8892 Node: Non-sexp query syntax8916
Node: General predicates10599 Node: General predicates10623
Node: Ancestor/descendant predicates15814 Node: Ancestor/descendant predicates15838
Node: Date/time predicates16942 Node: Date/time predicates16966
Node: Functions / Macros19597 Node: Functions / Macros19621
Node: Agenda-like views19852 Node: Agenda-like views19876
Node: Listing / acting-on results21257 Node: Listing / acting-on results21281
Node: Dynamic block25859 Node: Dynamic block25883
Node: Tips27885 Node: Links27910
Node: Changelog28211 Node: Tips28597
Node: 05-pre28850 Node: Changelog28915
Node: 04629726 Node: 05-pre29554
Node: 04530129 Node: 04630536
Node: 04430488 Node: 04530939
Node: 04330845 Node: 04431298
Node: 04231040 Node: 04331655
Node: 04131199 Node: 04231850
Node: 0431438 Node: 04132009
Node: 03235369 Node: 0432248
Node: 03135746 Node: 03236179
Node: 0335943 Node: 03136556
Node: 02338918 Node: 0336753
Node: 02239146 Node: 02339728
Node: 02139414 Node: 02239956
Node: 0239613 Node: 02140224
Node: 0143648 Node: 0240423
Node: Notes43749 Node: 0144458
Node: Comparison with Org Agenda searches43911 Node: Notes44559
Node: org-sidebar44783 Node: Comparison with Org Agenda searches44721
Node: License45062 Node: org-sidebar45593
Node: License45872
 
End Tag Table End Tag Table