org-agenda的好帮手:org-agenda-skip-function
之前一直想自定义一个angeda视图,用来显示所有 state 为 NEXT
且 scheduled time不超过今天的事项。
刷选 state 为 NEXT
的事项很容易,只需要在 org-agenda-custom-commands
中的 type
设为 todo
, match
设为 "NEXT"
就行了,
但是要过滤 scheduled time该怎么做呢?
我一直都找不到实现的方法,直到有一天发现了 org-agenda-skip-function
这个变量。
下面是 org-agenda-skip-function
的doc-string
org-agenda-skip-function is a variable defined in ‘org-agenda.el’. Its value is nil This variable may be risky if used as a file-local variable. Documentation: Function to be called at each match during agenda construction. If this function returns nil, the current match should not be skipped. Otherwise, the function must return a position from where the search should be continued. This may also be a Lisp form, it will be evaluated. Never set this variable using ‘setq’ or so, because then it will apply to all future agenda commands. If you do want a global skipping condition, use the option ‘org-agenda-skip-function-global’ instead. The correct usage for ‘org-agenda-skip-function’ is to bind it with ‘let’ to scope it dynamically into the agenda-constructing command. A good way to set it is through options in ‘org-agenda-custom-commands’.
根据这个说法 org-agenda 会在生成 agenda view 时调用 org-agenda-skip-function
所指向的函数来过滤不需要的事项。
也就是说,通过定义这个函数,我们可以以任意条件来过滤要显示的事项。
这个过滤函数的结构一般是这样的
(let* ((next-headline (save-excursion (or (outline-next-heading) (point-max)))) (subtree-end (save-excursion (org-end-of-subtree t))) (subtree-valid (过滤条件判断))) (unless subtree-valid next-headline))
比如我的agenda实现是这样的:
(defun org/schedule-until (&optional time) "List Agenda items that scheduled until TIME." (let* ((next-headline (save-excursion (or (outline-next-heading) (point-max)))) (subtree-end (save-excursion (org-end-of-subtree t))) (scheduled-time (org-get-scheduled-time (point))) (time (or time (format-time-string "%Y-%m-%d 23:59:59"))) (time (apply #'encode-time (org-parse-time-string time))) (subtree-valid (or (null scheduled-time) (time-less-p scheduled-time time)))) (until subtree-valid next-headline))) (setq org-agenda-custom-commands '(("n" "Next" todo "NEXT" ((org-agenda-overriding-header "NEXT") (org-agenda-skip-function 'org/schedule-until)))))