commit
a086743480
|
@ -17,6 +17,52 @@
|
|||
:END:
|
||||
|
||||
** Details
|
||||
|
||||
*** Enhancements to secondary agenda filtering
|
||||
|
||||
**** You can now refining the current filter by an additional criterion
|
||||
When filtering an existing agenda view with =/=, you can
|
||||
now narrow down the existing selection by an additional
|
||||
condition. Do do this, use =\= instead of =/= to add the
|
||||
aditional criterion. You can also press =+= or =-= after
|
||||
=/= to add a positive or negative condition. A condition
|
||||
can be a TAG, or an effort estimate limit, see below.
|
||||
|
||||
**** It is now possible to filter for effort estimates
|
||||
This means to filter the agenda for the value of the Effort
|
||||
property. For this you should best set up global allowed
|
||||
values for effort estimates, with
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-global-properties
|
||||
'(("Effort_ALL" . "0 0:10 0:30 1:00 2:00 3:00 4:00")))
|
||||
#+end_src
|
||||
|
||||
You may then select effort limits with single keys in the
|
||||
filter. It works like this: After =/= or =\=, first select
|
||||
the operater which you want to use to compare effort
|
||||
estimates:
|
||||
|
||||
: < Select entries with effort smaller than or equal to the limit
|
||||
: > Select entries with effort larger than or equal to the limit
|
||||
: = Select entries with effort equal to the limit
|
||||
|
||||
After that, you can press a single digit number which is
|
||||
used as an index to the allowed effort estimates.
|
||||
|
||||
If you do not use digits to fast-select tags, you can even
|
||||
skip the operator, which will then default to
|
||||
`org-agenda-filter-effort-default-operator', which is by
|
||||
default =<=.
|
||||
|
||||
Thanks to Manish for the great idea to include fast effort
|
||||
filtering into the agenda filtering process.
|
||||
|
||||
**** The mode line will show the active filter
|
||||
For example, if there is a filter in place that does select
|
||||
for HOME tags, against EMAILtags, and for tasks with an
|
||||
estimated effort smaller than 30 minutes, the mode-line with
|
||||
show =+HOME-EMAIL+<0:30=
|
||||
|
||||
*** Setting tags has now its own binding, =C-c C-q=
|
||||
|
||||
|
|
61
doc/org.texi
61
doc/org.texi
|
@ -4863,10 +4863,10 @@ you want to clock your time). For a specific buffer you can use
|
|||
@end example
|
||||
|
||||
@noindent
|
||||
or you can set up these values globally by customizing the variables
|
||||
@code{org-global-properties} and @code{org-columns-default-format}. In
|
||||
particular if you want to use this setup also in the agenda, a global setup
|
||||
may be advised.
|
||||
or, even better, you can set up these values globally by customizing the
|
||||
variables @code{org-global-properties} and @code{org-columns-default-format}.
|
||||
In particular if you want to use this setup also in the agenda, a global
|
||||
setup may be advised.
|
||||
|
||||
The way to assign estimates to individual items is then to switch to column
|
||||
mode, and to use @kbd{S-@key{right}} and @kbd{S-@key{left}} to change the
|
||||
|
@ -4882,6 +4882,10 @@ option @code{org-agenda-columns-add-appointments-to-effort-sum}. The
|
|||
appointments on a day that take place over a specified time interval will
|
||||
then also be added to the load estimate of the day.
|
||||
|
||||
Effort estimates can be used in secondary agenda filtering that is triggered
|
||||
with the @kbd{/} key in the agenda (@pxref{Agenda commands}). If you have
|
||||
these estimates defined consistently, two or three key presses will narrow
|
||||
down the list to stuff that fits into an available time slot.
|
||||
|
||||
@node Capture, Agenda Views, Dates and Times, Top
|
||||
@chapter Capture
|
||||
|
@ -5835,9 +5839,7 @@ sequence in which they are found in the agenda files.
|
|||
|
||||
Sorting can be customized using the variable
|
||||
@code{org-agenda-sorting-strategy}, and may also include criteria based on
|
||||
the estimated effort of an entry.
|
||||
@c FIXME: link!!!!!!!!
|
||||
|
||||
the estimated effort of an entry (@pxref{Effort estimates}).
|
||||
|
||||
@node Agenda commands, Custom agenda views, Presentation and sorting, Agenda Views
|
||||
@section Commands in the agenda buffer
|
||||
|
@ -5994,17 +5996,48 @@ that entry would be in the original buffer (taken from a property, from a
|
|||
@code{org-columns-default-format}), will be used in the agenda.
|
||||
|
||||
@tsubheading{Secondary filtering and query editing}
|
||||
@cindex filtering, by tag and effort, in agenda
|
||||
@cindex tag filtering, in agenda
|
||||
@cindex effort filtering, in agenda
|
||||
@cindex query editing, in agenda
|
||||
|
||||
@kindex /
|
||||
@item /
|
||||
Filter the current agenda view with respect to a tag. You will be prompted
|
||||
for a tag selection letter. Pressing @key{TAB} at that prompt will offer use
|
||||
completion to select a tag (including any tags that do not have a selection
|
||||
character). The command then hides all entries that do not contain or
|
||||
inherit this tag. When called with prefix arg, remove the entries that
|
||||
@emph{do} have the tag. A second @kbd{/} at the prompt will unhide any
|
||||
hidden entries.
|
||||
Filter the current agenda view with respect to a tag and/or effort estimates.
|
||||
The difference between this and a custom agenda commands is that filtering is
|
||||
very fast, so that you can switch quickly between different filters without
|
||||
having to recreate the agenda.
|
||||
|
||||
You will be prompted for a tag selection letter. Pressing @key{TAB} at that
|
||||
prompt will offer use completion to select a tag (including any tags that do
|
||||
not have a selection character). The command then hides all entries that do
|
||||
not contain or inherit this tag. When called with prefix arg, remove the
|
||||
entries that @emph{do} have the tag. A second @kbd{/} at the prompt will
|
||||
turn off the filter and unhide any hidden entries. If the first key you
|
||||
press is either @kbd{+} or @kbd{-}, the previous filter will be narrowed by
|
||||
requiring or forbidding the selected additional tag. Instead of pressing
|
||||
@kbd{+} or {-}, you can also use the @kbd{\} command.
|
||||
|
||||
In order to filter for effort estimates, you should set-up allowed
|
||||
efforts globally, for example
|
||||
@lisp
|
||||
(setq org-global-properties
|
||||
'(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00")))
|
||||
@end lisp
|
||||
You can then filter for an effort by first typing an operator, one of @kbd{<},
|
||||
@kbd{>}, and @kbd{=}, and then the one-digit index of an effort estimate in
|
||||
your array of allowed values, where @kbd{0} means the 10th value. The filter
|
||||
will then restrict to entries with effort smaller-or-equal, equal, or
|
||||
larger-or-equal than the selected value. If the digits 0-9 are not used as
|
||||
fast access keys to tags, you can also simply press the index digit directly
|
||||
without an operator. In this case, @kbd{<} will be assumed.
|
||||
|
||||
@kindex \
|
||||
@item \
|
||||
Narrow the current agenda filter by an additional condition. When called with
|
||||
prefix arg, remove the entries that @emph{do} have the tag, or that do match
|
||||
the effort criterion. You can achieve the same effect by pressing @kbd{+} or
|
||||
@kbd{-} as the first key after the @kbd{/} command.
|
||||
|
||||
@kindex [
|
||||
@kindex ]
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
(org-add-log-note): Mask prefix argument when immediately storing
|
||||
the note.
|
||||
|
||||
* org-agenda.el (org-agenda-filter-effort-default-operator): New
|
||||
option.
|
||||
|
||||
2008-10-19 James TD Smith <ahktenzero@mohorovi.cc>
|
||||
|
||||
* org.el (org-add-log-setup): Bugfix; code to find insertion point
|
||||
|
@ -13,6 +16,12 @@
|
|||
|
||||
2008-10-18 Carsten Dominik <dominik@science.uva.nl>
|
||||
|
||||
* org-agenda.el (org-agenda-filter-tags,org-agenda-filter-form):
|
||||
New variables.
|
||||
(org-prepare-agenda): Reset the filter tags.
|
||||
(org-agenda-filter-by-tag, org-agenda-filter-by-tag-show-all):
|
||||
Show filter tags in mode line.
|
||||
|
||||
* org-table.el (orgtbl-to-html): Bind `html-table-tag' for the
|
||||
formatter.
|
||||
|
||||
|
|
|
@ -387,6 +387,14 @@ or `C-c a #' to produce the list."
|
|||
(repeat :tag "Projects are *not* stuck if they have an entry with TAG being any of" (string))
|
||||
(regexp :tag "Projects are *not* stuck if this regexp matches\ninside the subtree")))
|
||||
|
||||
(defcustom org-agenda-filter-effort-default-operator "<"
|
||||
"The default operator for effort estimate filtering.
|
||||
If you select an effort estimate limit with first pressing an operator,
|
||||
this one will be used."
|
||||
:group 'org-agenda-custom-commands
|
||||
:type '(choice (const :tag "less or equal" "<")
|
||||
(const :tag "greater or equal"">")
|
||||
(const :tag "equal" "=")))
|
||||
|
||||
(defgroup org-agenda-skip nil
|
||||
"Options concerning skipping parts of agenda files."
|
||||
|
@ -1169,6 +1177,7 @@ The following commands are available:
|
|||
(org-defkey org-agenda-mode-map "{" 'org-agenda-manipulate-query-add-re)
|
||||
(org-defkey org-agenda-mode-map "}" 'org-agenda-manipulate-query-subtract-re)
|
||||
(org-defkey org-agenda-mode-map "/" 'org-agenda-filter-by-tag)
|
||||
(org-defkey org-agenda-mode-map "\\" 'org-agenda-filter-by-tag-refine)
|
||||
|
||||
(defvar org-agenda-keymap (copy-keymap org-agenda-mode-map)
|
||||
"Local keymap for agenda entries from Org-mode.")
|
||||
|
@ -1958,6 +1967,7 @@ higher priority settings."
|
|||
(defun org-prepare-agenda (&optional name)
|
||||
(setq org-todo-keywords-for-agenda nil)
|
||||
(setq org-done-keywords-for-agenda nil)
|
||||
(setq org-agenda-filter-tags nil)
|
||||
(if org-agenda-multi
|
||||
(progn
|
||||
(setq buffer-read-only nil)
|
||||
|
@ -4117,48 +4127,125 @@ When this is the global TODO list, a prefix argument will be interpreted."
|
|||
(goto-line line)
|
||||
(recenter window-line)))
|
||||
|
||||
|
||||
(defvar org-global-tags-completion-table nil)
|
||||
(defun org-agenda-filter-by-tag (strip &optional char)
|
||||
(defvar org-agenda-filter-tags nil)
|
||||
(defvar org-agenda-filter-form nil)
|
||||
(defun org-agenda-filter-by-tag (strip &optional char narrow)
|
||||
"Keep only those lines in the agenda buffer that have a specific tag.
|
||||
The tag is selected with its fast selection letter, as configured.
|
||||
With prefix argument STRIP, remove all lines that do have the tag."
|
||||
With prefix argument STRIP, remove all lines that do have the tag.
|
||||
A lisp caller can specify CHAR. NARROW means that the new tag should be
|
||||
used to narrow the search - the interactive user can also press `-' or `+'
|
||||
to switch to narrowing."
|
||||
(interactive "P")
|
||||
(let (char a tag tags (inhibit-read-only t))
|
||||
(message "Select tag [%s] or no tag [ ], [TAB] to complete, [/] to restore: "
|
||||
(mapconcat
|
||||
(lambda (x) (if (cdr x) (char-to-string (cdr x)) ""))
|
||||
org-tag-alist-for-agenda ""))
|
||||
(let* ((alist org-tag-alist-for-agenda)
|
||||
(tag-chars (mapconcat
|
||||
(lambda (x) (if (cdr x) (char-to-string (cdr x)) ""))
|
||||
alist ""))
|
||||
(efforts (org-split-string
|
||||
(or (cdr (assoc (concat org-effort-property "_ALL")
|
||||
org-global-properties))
|
||||
"0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00 8:00" "")))
|
||||
(effort-op org-agenda-filter-effort-default-operator)
|
||||
(effort-prompt "")
|
||||
(inhibit-read-only t)
|
||||
(current org-agenda-filter-tags)
|
||||
char a tag tags)
|
||||
(unless char
|
||||
(message
|
||||
"%s by tag [%s ], [TAB], [/]:off, [+-]:narrow, [>=<]:effort: "
|
||||
(if narrow "Narrow" "Filter") tag-chars)
|
||||
(setq char (read-char)))
|
||||
(when (member char '(?+ ?-))
|
||||
;; Narrowing down
|
||||
(cond ((equal char ?-) (setq strip t narrow t))
|
||||
((equal char ?+) (setq strip nil narrow t)))
|
||||
(message
|
||||
"Narrow by tag [%s ], [TAB], [/]:off, [>=<]:effort: " tag-chars)
|
||||
(setq char (read-char)))
|
||||
(when (member char '(?< ?> ?=))
|
||||
;; An effort operator
|
||||
(setq effort-op (char-to-string char))
|
||||
(loop for i from 0 to 9 do
|
||||
(setq effort-prompt
|
||||
(concat
|
||||
effort-prompt " ["
|
||||
(if (= i 9) "0" (int-to-string (1+ i)))
|
||||
"]" (nth i efforts))))
|
||||
(setq alist nil) ; to make sure it will be interpreted as effort.
|
||||
(message "Effort%s: %s " effort-op effort-prompt)
|
||||
(setq char (read-char))
|
||||
(when (equal char ?\t)
|
||||
(unless (local-variable-p 'org-global-tags-completion-table (current-buffer))
|
||||
(org-set-local 'org-global-tags-completion-table
|
||||
(org-global-tags-completion-table)))
|
||||
(let ((completion-ignore-case t))
|
||||
(setq tag (completing-read
|
||||
"Tag: " org-global-tags-completion-table))))
|
||||
(cond
|
||||
((equal char ?/) (org-agenda-filter-by-tag-show-all))
|
||||
((or (equal char ?\ )
|
||||
(setq a (rassoc char org-tag-alist-for-agenda))
|
||||
(and tag (setq a (cons tag nil))))
|
||||
(org-agenda-filter-by-tag-show-all)
|
||||
(setq tag (car a))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (not (eobp))
|
||||
(if (get-text-property (point) 'org-marker)
|
||||
(progn
|
||||
(setq tags (get-text-property (point) 'tags))
|
||||
(if (not tag)
|
||||
(if (or (and strip (not tags))
|
||||
(and (not strip) tags))
|
||||
(org-agenda-filter-by-tag-hide-line))
|
||||
(if (or (and (member tag tags) strip)
|
||||
(and (not (member tag tags)) (not strip)))
|
||||
(org-agenda-filter-by-tag-hide-line)))
|
||||
(beginning-of-line 2))
|
||||
(beginning-of-line 2)))))
|
||||
(t (error "Invalid tag selection character %c" char)))))
|
||||
(when (or (< char ?0) (> char ?9))
|
||||
(error "Need 1-9,0 to select effort" )))
|
||||
(when (equal char ?\t)
|
||||
(unless (local-variable-p 'org-global-tags-completion-table (current-buffer))
|
||||
(org-set-local 'org-global-tags-completion-table
|
||||
(org-global-tags-completion-table)))
|
||||
(let ((completion-ignore-case t))
|
||||
(setq tag (completing-read
|
||||
"Tag: " org-global-tags-completion-table))))
|
||||
(cond
|
||||
((equal char ?/) (org-agenda-filter-by-tag-show-all))
|
||||
((or (equal char ?\ )
|
||||
(setq a (rassoc char alist))
|
||||
(and (>= char ?0) (<= char ?9)
|
||||
(setq n (if (= char ?0) 9 (- char ?0 1))
|
||||
tag (concat effort-op (nth n efforts))
|
||||
a (cons tag nil)))
|
||||
(and tag (setq a (cons tag nil))))
|
||||
(org-agenda-filter-by-tag-show-all)
|
||||
(setq tag (car a))
|
||||
(setq org-agenda-filter-tags
|
||||
(cons (concat (if strip "-" "+") tag)
|
||||
(if narrow current nil)))
|
||||
(setq org-agenda-filter-form (org-agenda-filter-make-matcher))
|
||||
(org-agenda-set-mode-name)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (not (eobp))
|
||||
(if (get-text-property (point) 'org-marker)
|
||||
(progn
|
||||
(setq tags (get-text-property (point) 'tags))
|
||||
(if (not (eval org-agenda-filter-form))
|
||||
(org-agenda-filter-by-tag-hide-line))
|
||||
(beginning-of-line 2))
|
||||
(beginning-of-line 2)))))
|
||||
(t (error "Invalid tag selection character %c" char)))))
|
||||
|
||||
(defun org-agenda-filter-by-tag-refine (strip &optional char)
|
||||
"Refine the current filter. See `org-agenda-filter-by-tag."
|
||||
(interactive "P")
|
||||
(org-agenda-filter-by-tag strip char 'refine))
|
||||
|
||||
(defun org-agenda-filter-make-matcher ()
|
||||
(let (f f1)
|
||||
(dolist (x org-agenda-filter-tags)
|
||||
(if (member x '("-" "+"))
|
||||
(setq f1 '(not tags))
|
||||
(if (string-match "[<=>]" x)
|
||||
(setq f1 (org-agenda-filter-effort-form x))
|
||||
(setq f1 (list 'member (substring x 1) 'tags)))
|
||||
(if (equal (string-to-char x) ?-)
|
||||
(setq f1 (list 'not f1))))
|
||||
(push f1 f))
|
||||
(cons 'and (nreverse f))))
|
||||
|
||||
(defun org-agenda-filter-effort-form (e)
|
||||
"Return the form to compare the effort of the current line with what E says.
|
||||
E looks line \"+<2:25\"."
|
||||
(let (op)
|
||||
(setq e (substring e 1))
|
||||
(setq op (string-to-char e) e (substring e 1))
|
||||
(setq op (if (equal op ?<) '<= (if (equal op ?>) '>= '=)))
|
||||
(list 'org-agenda-compare-effort (list 'quote op)
|
||||
(org-hh:mm-string-to-minutes e))))
|
||||
|
||||
(defun org-agenda-compare-effort (op value)
|
||||
(let ((eff (get-text-property 'effort-minutes)))
|
||||
(if (not eff)
|
||||
nil ; we don't have an effort defined
|
||||
(funcall op eff value))))
|
||||
|
||||
(defvar org-agenda-filter-overlays nil)
|
||||
|
||||
|
@ -4183,7 +4270,10 @@ With prefix argument STRIP, remove all lines that do have the tag."
|
|||
|
||||
(defun org-agenda-filter-by-tag-show-all ()
|
||||
(mapc 'org-delete-overlay org-agenda-filter-overlays)
|
||||
(setq org-agenda-filter-overlays nil))
|
||||
(setq org-agenda-filter-overlays nil)
|
||||
(setq org-agenda-filter-tags nil)
|
||||
(setq org-agenda-filter-form nil)
|
||||
(org-agenda-set-mode-name))
|
||||
|
||||
(defun org-agenda-manipulate-query-add ()
|
||||
"Manipulate the query by adding a search term with positive selection.
|
||||
|
@ -4522,6 +4612,9 @@ so that the date SD will be in that range."
|
|||
(if org-agenda-include-diary " Diary" "")
|
||||
(if org-agenda-use-time-grid " Grid" "")
|
||||
(if org-agenda-show-log " Log" "")
|
||||
(if org-agenda-filter-tags
|
||||
(concat " {" (mapconcat 'identity org-agenda-filter-tags "") "}")
|
||||
"")
|
||||
(if org-agenda-archives-mode
|
||||
(if (eq org-agenda-archives-mode t)
|
||||
" Archives"
|
||||
|
|
Loading…
Reference in New Issue