org-ql 非常强大,这两天专门学习了一下它的手册,优点很多。 检索条件全面,可以按照时间、属性、标签来检索。 检索结果可以保存为 org-mode 格式的链接,方便随时调用。 还可以和 dynamic block 结合,将 heading 整理成列表形式,并且可以进行更新。
以下是我整理的部分手册内容:
definition
针对 org-mode 的 query 语法。
project url
https://github.com/alphapapa/org-ql
How to use
安装org-ql
官方推荐用 quelpa 来安装,如果不使用它的话,直接用 straight 的方式也可以。
用法
命令
org-ql 提供 3 种类型的命令,不同命令支持 non-sexp,和 sexp 两种类型的指令:
-
直接跳转到对应的内容
-
org-ql-find
【仅支持 non-sexp 类型指令】
-
org-ql-find
在当前打开的 buffer 里进行检索 -
org-ql-find-in-agenda
在预设好的 (org-agenda-files) 里进行检索 -
org-ql-find-in-org-directory
在 org-directory 里的文件进行检索
-
-
-
检索结果将展示成类似 agenda 的视图
-
org-ql-search
【支持 non-sexp 和 sexp 两种类型的指令】 该指令提供如下变量:
-
BUFFERS-FILES
检索一系列 buffer 或 org 文件
-
buffer
从当前所有打开的 buffer 中进行检索 -
all
检 索所有的 Org 文件类型的 buffer -
agenda
在 (org-agenda-files) 指定的文件中检索
-
-
GROUPS
从 org-super-agenda-groups 定义的分类中进行检索
-
NARROW
When non-nil, don’t widen buffers before searching. Interactively, with prefix, leave narrowed.
-
SORT
一个,或一系列
org-ql
用于排序的指令,比如date
或priority
-
Bindiings 在结果展示 buffer 里使用的键盘快捷键
-
r
当调整了搜索的设置之后,刷新展示的结果 -
v
展示弹出窗口,类似 popups -
C-x C-s
将检索结果页保存为org-ql-views
-
-
-
org-ql-views
选择储存在
org-gl-views
里的视图,并展示出来-
Bindings
-
g
,r
刷新 -
v
以 popup 的方式进行展示 -
C-c C-s
将检索的视图,保存到org-ql-views
-
-
-
org-ql-view-sidebar
将
org-ql-views
的结果以侧边栏的方式展示出来 可用RET
或mouse-1
在当前的光标位置展示特定的结果 按下c
对光标位置展示的结果进行定义 -
org-ql-view-recent-items
展示
FILES
里,以DAYS
的范围内的检索结果。DAYS
通过TYPE
参数进行调整,包括ts
,ts-active
,ts-inactive
,clocked
,closed
,deadline
,plannning
, =scheduled =FILES
默认是org-agenda-files
指定的文件
-
-
检索结果以树状列表的形式在新开的 buffer 里展示
-
org-ql-sparse-tree
Arguments: (query &key keep-previous (buffer (current-buffer)))
从
BUFFERS
里检索特定的QUERY
条件,并以树状列表进行展示
-
QUERY 检索语法
-
原理
An org-ql query is a Lisp expression which may contain arbitrary expressions, as well as calling certain built-in predicates. It is byte-compiled into a predicate function which is tested with point on each heading in an Org buffer; when it returns non-nil, the heading matches the query. When possible, certain built-in predicates are optimized away to whole-buffer regular expression searches, which are much faster to search for than testing the predicate on each heading.
- 检索条件采用
<
,<=
,>=
,=
进行比较
- 检索条件采用
-
Non-sexp 检索语法
Sexp syntax Non-sexp syntax (todo) todo: (todo "SOMEDAY") todo:SOMEDAY (todo "SOMEDAY" "WAITING") todo:SOMEDAY,WAITING (ts :on today) ts:on=today (ts-active :from "2017-01-01" :to "2018-01-01") ts-active:from=2017-01-01,to=2018-01-01 (clocked :on -1) clocked:on=-1 (heading "quoted phrase" "word") heading:"quoted phrase",word (and (tags "book" "books") (priority "A")) tags:book,books priority:A (src :lang "elisp" :regexps ("defun")) src:defun,lang=elisp or src:lang=elisp,defun (and (tags "space") (not (regexp "moon"))) tags:space !moon (priority >= B) priority:A,B -
General predicates 一般检索条件
- category (&optional categories)
- done
- effort (&optional effort-or-comparator effort)
- habit
- heading (&rest strings)
- 缩写
h
- 缩写
- heading-regexp (&rest regexps)
- 缩写
h*
- 缩写
- level (level-or-comparator &optional level)
- link (&optional description-or-target &key description target regexp-p)
- outline-path (&rest strings)
- 缩写
olp
- 缩写
- outline-path-segment (&rest strings)
- 缩写
olps
- 缩写
- path (&rest regexps)
- priority (&rest args)
- property (property &optional value)
- regexp (&rest regexps)
- rifle (&rest strings)
- src (&key lang regexps)
- tags (&optional tags)
- tags-inherited (&optional tags)
- tags-local (&optional tags)
- tags-all (tags)
- tags-regexp (&rest regexps)
- todo (&optional keywords)
-
根据 headling 的层级进行检索
- ancestors (&optional query) 一级
- children (&optional query) 二级
- descendants (&optional query)
- parent (&optional query)
-
根据未来日期/时间条件进行检索
检索语句:
-
:from
从当前的 timestamp 开始之后 -
:to
从当前的 timestamp 开始之前 -
:on
仅检索 timestamp 当天 -
:with-time
检索两个 timestamp 期间
-
特定时间条件的
-
ts
选取带timestamp
的 entry -
ts-active
,ts-a
仅匹配仍在活跃的,带timestamp
的 entry -
ts-inactive
,ts-i
仅匹配非活跃的……
-
-
面向历史的
-
clocked
检索结束计时的 entry -
closed
检索已结束的 entry
-
-
面向未来的
-
deadline
包含 deadline 的 entry,除非提供了特定时间条件 -
planning
包含了 planing 的 timestamp 比如(deadline,scheduled 或 closed) -
scheduled
包含了 scheduled 的 entry
-
-
Functions / Macros
-
Agenda-like views
-
org-ql-block
需要与
org-agenda-custom-commands
进行结合 例子:(setq org-agenda-custom-commands '(("ces" "Custom: Agenda and Emacs SOMEDAY [#A] items" ((org-ql-block '(and (todo "SOMEDAY") (tags "Emacs") (priority "A")) ((org-ql-block-header "SOMEDAY :Emacs: High-priority"))) (agenda)))))
-
-
Listing / acting-on results
-
org-ql-select
(buffers-or-files query &key action narrow sort)
BUFFERS-OR-FILES is a one or a list of files and/or buffers.QUERY is an org-ql query sexp (quoted, since this is a function).
ACTION is a function which is called on each matching entry with point at the beginning of its heading. It may be:
element or nil: Equivalent to org-element-headline-parser.
element-with-markers: Equivalent to calling org-element-headline-parser, with markers added using org-ql–add-markers. Suitable for formatting with org-ql-agenda–format-element, allowing insertion into an Org Agenda-like buffer.
A sexp, which will be byte-compiled into a lambda function.
A function symbol.
If NARROW is non-nil, buffers are not widened (the default is to widen and search the entire buffer).
SORT is either nil, in which case items are not sorted; or one or a list of defined org-ql sorting methods (date, deadline, scheduled, closed, todo, priority, or random); or a user-defined comparator function that accepts two items as arguments and returns nil or non-nil.
例子:
;; Return list of to-do headings in inbox file with tags and to-do keywords: (org-ql-select "~/org/inbox.org" '(todo) :action #'org-get-heading) ;; => ("TODO Practice leaping tall buildings in a single bound :personal:" ...) ;; Without tags and to-do keywords: (org-ql-select "~/org/inbox.org" '(todo) :action '(org-get-heading t t)) ;; => ("Practice leaping tall buildings in a single bound" ...) ;; Return WAITING heading elements in agenda files: (org-ql-select (org-agenda-files) '(todo "WAITING") :action 'element) ;; => ((headline (:raw-value "Visit the moon" ...) ...) ...) ;; Since `element' is the default for ACTION, it may be omitted: (org-ql-select (org-agenda-files) '(todo "WAITING")) ;; => ((headline (:raw-value "Visit the moon" ...) ...) ...)
-
org-ql-query
(&key (select 'element-with-markers) from where order-by narrow)
和
org-ql-select
类似,但它的检索语法和 SQL 类似SELECT corresponds to the org-ql-select argument ACTION.
FROM corresponds to the org-ql-select argument BUFFERS-OR-FILES.
WHERE corresponds to the org-ql-select argument QUERY.
ORDER-BY corresponds to the org-ql-select argument SORT, which see.
NARROW corresponds to the org-ql-select argument NARROW.
-
-
Custom predicates 自定义检索条件
-
org-ql-defpred
(name args docstring &key body preambles normalizers)
org-ql–predicate-NAME. NAME may be a symbol or a list of symbols: if a list, the first is used as NAME and the rest are aliases. A function is only created for NAME, not for aliases, so a normalizer should be used to replace aliases with NAME in queries (keep reading).
ARGS is a cl-defun-style argument list. DOCSTRING is the function’s docstring.
BODY is the body of the predicate. It will be evaluated with point on the beginning of an Org heading and should return non-nil if the heading’s entry is a match.
PREAMBLES and NORMALIZERS are lists of pcase forms matched against Org QL query sexps. They are spliced into pcase forms in the definitions of the functions org-ql–query-preamble and org-ql–normalize-query, which see. Those functions are redefined when this macro is expanded, unless variable org-ql-defpred-defer is non-nil, in which case those functions should be redefined manually after defining predicates by calling org-ql–define-query-preamble-fn and org-ql–define-normalize-query-fn.
NORMALIZERS are used to normalize query expressions to standard forms. For example, when the predicate has aliases, the aliases should be replaced with predicate names using a normalizer. Also, predicate arguments may be put into a more optimal form so that the predicate has less work to do at query time. NOTE: Normalizers are applied to a query repeatedly until the query is fully normalized, so normalizers should be carefully written to avoid infinite loops.
PREAMBLES refer to regular expressions which may be used to search through a buffer directly to a potential match rather than testing the predicate body on each heading. (Naming things is hard.) In each pcase form in PREAMBLES, the pcase expression (not the pattern) should be a plist with the following keys, each value of which should be an expression which may refer to variables bound in the pattern:
:regexp Regular expression which searches directly to a potential match.
:case-fold Bound to case-fold-search around the regexp search.
:query Expression which should replace the query expression, or query if it should not be changed (e.g. if the regexp is insufficient to determine whether a heading matches, in which case the predicate’s body needs to be tested on the heading). If the regexp guarantees a match, this may be simply t, leaving the query expression with no work to do, which improves performance.
For convenience, within the pcase patterns, the symbol predicate-names is a special form which is replaced with a pattern matching any of the predicate’s name and aliases. For example, if NAME were:
(heading h)
Then if NORMALIZERS were:
((`(,predicate-names . ,args) `(heading ,@args)))
It would be expanded to:
((`(,(or 'heading 'h) . ,args) `(heading ,@args)))
-
Dynamic block
org-ql 可以和 org-mode 内置的 Daynamic Blocks 功能搭配使用。
:query An Org QL query expression in either sexp or non-sexp form.
:columns A list of columns, including heading, todo, property, priority, deadline, scheduled, closed. Each column may also be specified as a list with the second element being a header string. For example, to abbreviate the priority column: (priority “P”). For certain columns, like property, arguments may be passed by specifying the column type itself as a list. For example, to display a column showing the values of a property named milestone, with the header being abbreviated to M: ((property “milestone”) “M”).
:sort One or a list of Org QL sorting methods (see org-ql-select).
:take Optionally take a number of results from the front (a positive number) or the end (a negative number) of the results.
:ts-format Optional format string used to format timestamp-based columns.
例子:
#+BEGIN: org-ql :query "todo: priority:A,B" :columns (todo (priority "P") ((property "agenda-group") "Group") deadline heading) :sort (deadline priority) :take 7 :ts-format "%Y-%m-%d %H:%M"
| Todo | P | Group | Deadline | Heading |
|------+---+-------+------------------+---------------------------------------|
| TODO | A | | 2017-07-07 00:00 | Take over the world |
| TODO | B | | 2017-07-10 00:00 | Renew membership in supervillain club |
| TODO | A | plans | 2017-07-15 00:00 | Take over the universe |
| TODO | B | | 2017-07-21 00:00 | Internet |
| TODO | A | bills | 2017-08-01 00:00 | Spaceship lease |
| TODO | A | | | Skype with president of Antarctica |
| TODO | B | | | Take over Mars |
#+END:
Links
支持将 org-ql 与 org-mode 的 links 结合,在点击之后,直接展示 org-ql 检索的结果 你可以将当前 org-ql 检索结果的视图用 org-store-link 命令储存起来,然后再用 org-insert-link 将保存的结果取出,并记录在你想记录的位置
例子:
[[org-ql-search:todo:NEXT priority:A]]
[[org-ql-search:(and (todo "NEXT") (priority "A"))]]
Tips
org-ql view 的 buffer 可以通过 emacs 的 bookmark 命令标记为书签