Merge branch 'improve-fast-todo-selection'

This commit is contained in:
Carsten Dominik 2019-08-16 08:49:43 +02:00
commit 92c2265794
3 changed files with 112 additions and 94 deletions

View File

@ -721,12 +721,19 @@ cursor still in the line to make the changes known to Org mode.
:DESCRIPTION: Dates and notes for progress.
:END:
Org mode can automatically record a timestamp and optionally a note
when you mark a TODO item as DONE, or even each time you change the
state of a TODO item. This system is highly configurable, settings
can be on a per-keyword basis and can be localized to a file or even
a subtree. For information on how to clock working time for a task,
see [[*Clocking Work Time]].
To record a timestamp and a note when changing a TODO state, call the
command ~org-todo~ with a prefix argument.
#+attr_texinfo: :sep ,
- {{{kbd(C-u C-c C-t)}}} ::
Prompt for a note and record a the time of the TODO state change.
Org mode can also automatically record a timestamp and optionally a
note when you mark a TODO item as DONE, or even each time you change
the state of a TODO item. This system is highly configurable,
settings can be on a per-keyword basis and can be localized to a file
or even a subtree. For information on how to clock working time for a
task, see [[*Clocking Work Time]].
*** Closing items
:PROPERTIES:

View File

@ -3671,17 +3671,9 @@ The most important commands to work with TODO entries are:
interface; this is the default behavior when
~org-use-fast-todo-selection~ is non-~nil~.
The same rotation can also be done "remotely" from the agenda buffer
with the {{{kbd(t)}}} command key (see [[*Commands in the Agenda
Buffer]]).
- {{{kbd(C-u C-c C-t)}}} ::
#+kindex: C-u C-c C-t
When TODO keywords have no selection keys, select a specific keyword
using completion; otherwise force cycling through TODO states with
no prompt. When ~org-use-fast-todo-selection~ is set to ~prefix~,
use the fast selection interface.
The same state changing can also be done "remotely" from the agenda
buffer with the {{{kbd(t)}}} command key (see [[*Commands in the
Agenda Buffer]]).
- {{{kbd(S-RIGHT)}}} {{{kbd(S-LEFT)}}} ::
@ -3756,8 +3748,8 @@ TODO items in particular (see [[*Tags]]).
#+cindex: TODO workflow
#+cindex: workflow states as TODO keywords
You can use TODO keywords to indicate different /sequential/ states in
the process of working on an item, for example[fn:36]:
You can use TODO keywords to indicate different, possibly /sequential/
states in the process of working on an item, for example[fn:36]:
#+begin_src emacs-lisp
(setq org-todo-keywords
@ -3774,12 +3766,13 @@ With this setup, the command {{{kbd(C-c C-t)}}} cycles an entry from
=TODO= to =FEEDBACK=, then to =VERIFY=, and finally to =DONE= and
=DELEGATED=. You may also use a numeric prefix argument to quickly
select a specific state. For example {{{kbd(C-3 C-c C-t)}}} changes
the state immediately to =VERIFY=. Or you can use {{{kbd(S-LEFT)}}}
to go backward through the sequence. If you define many keywords, you
can use in-buffer completion (see [[*Completion]]) or even a special
one-key selection scheme (see [[*Fast access to TODO states]]) to insert
these words into the buffer. Changing a TODO state can be logged with
a timestamp, see [[*Tracking TODO state changes]], for more information.
the state immediately to =VERIFY=. Or you can use {{{kbd(S-RIGHT)}}}
and {{{kbd(S-LEFT)}}} to go forward and backward through the states.
If you define many keywords, you can use in-buffer completion (see
[[*Completion]]) or a special one-key selection scheme (see [[*Fast
access to TODO states]]) to insert these words into the buffer.
Changing a TODO state can be logged with a timestamp, see [[*Tracking
TODO state changes]], for more information.
*** TODO keywords as types
:PROPERTIES:
@ -3794,14 +3787,18 @@ The second possibility is to use TODO keywords to indicate different
/types/ of action items. For example, you might want to indicate that
items are for "work" or "home". Or, when you work with several people
on a single project, you might want to assign action items directly to
persons, by using their names as TODO keywords. This would be set up
like this:
persons, by using their names as TODO keywords. This type of
functionality is actually much better served by using tags (see
[[*Tags]]), so the TODO implementation is kept just for backward
compatibility.
Using TODO types, it would be set up like this:
#+begin_src emacs-lisp
(setq org-todo-keywords '((type "Fred" "Sara" "Lucy" "|" "DONE")))
#+end_src
In this case, different keywords do not indicate a sequence, but
In this case, different keywords do not indicate states, but
rather different types. So the normal work flow would be to assign
a task to a person, and later to mark it DONE. Org mode supports this
style by adapting the workings of the command {{{kbd(C-c
@ -4055,20 +4052,30 @@ the contributed module =org-depend.el=.
#+cindex: progress logging
#+cindex: logging, of progress
Org mode can automatically record a timestamp and optionally a note
when you mark a TODO item as DONE, or even each time you change the
state of a TODO item. This system is highly configurable, settings
can be on a per-keyword basis and can be localized to a file or even a
subtree. For information on how to clock working time for a task, see
[[*Clocking Work Time]].
To record a timestamp and a note when changing a TODO state, call the
command ~org-todo~ with a prefix argument.
- {{{kbd(C-u C-c C-t)}}} (~org-todo~) ::
#+kindex: C-u C-c C-t
Prompt for a note and record a the time of the TODO state change.
The note is inserted as a list item below the headline, but can also
be placed into a drawer, see [[*Tracking TODO state changes]].
If you want to be more systematic, Org mode can automatically record a
timestamp and optionally a note when you mark a TODO item as DONE, or
even each time you change the state of a TODO item. This system is
highly configurable, settings can be on a per-keyword basis and can be
localized to a file or even a subtree. For information on how to
clock working time for a task, see [[*Clocking Work Time]].
*** Closing items
:PROPERTIES:
:DESCRIPTION: When was this entry marked as done?
:END:
The most basic logging is to keep track of /when/ a certain TODO item
was marked as done. This can be achieved with[fn:41]
The most basic automatic logging is to keep track of /when/ a certain
TODO item was marked as done. This can be achieved with[fn:41]
#+begin_src emacs-lisp
(setq org-log-done 'time)
@ -4090,7 +4097,7 @@ a note along with the timestamp, use[fn:42]
#+end_src
#+texinfo: @noindent
You are then be prompted for a note, and that note is stored below the
You are then prompted for a note, and that note is stored below the
entry with a =Closing Note= heading.
*** Tracking TODO state changes
@ -4102,16 +4109,16 @@ entry with a =Closing Note= heading.
#+vindex: org-log-states-order-reversed
#+vindex: org-log-into-drawer
#+cindex: @samp{LOG_INTO_DRAWER}, property
When TODO keywords are used as workflow states (see [[*TODO keywords as workflow states][*Workflow states]]),
you might want to keep track of when a state change occurred and maybe
take a note about this change. You can either record just a
timestamp, or a time-stamped note. These records are inserted after
the headline as an itemized list, newest first[fn:43]. When taking a
lot of notes, you might want to get the notes out of the way into a
drawer (see [[*Drawers]]). Customize the variable ~org-log-into-drawer~
to get this behavior---the recommended drawer for this is called
=LOGBOOK=[fn:44]. You can also overrule the setting of this variable
for a subtree by setting a =LOG_INTO_DRAWER= property.
You might want to automatically keep track of when a state change
occurred and maybe take a note about this change. You can either
record just a timestamp, or a time-stamped note. These records are
inserted after the headline as an itemized list, newest first[fn:43].
When taking a lot of notes, you might want to get the notes out of the
way into a drawer (see [[*Drawers]]). Customize the variable
~org-log-into-drawer~ to get this behavior---the recommended drawer
for this is called =LOGBOOK=[fn:44]. You can also overrule the
setting of this variable for a subtree by setting a =LOG_INTO_DRAWER=
property.
Since it is normally too much to record a note for every state, Org
mode expects configuration on a per-keyword basis for this. This is
@ -4125,7 +4132,7 @@ example, with the setting
#+end_src
#+texinfo: @noindent
to record a timestamp without a note for TODO keywords configured with
To record a timestamp without a note for TODO keywords configured with
=@=, just type {{{kbd(C-c C-c)}}} to enter a blank note when prompted.
#+vindex: org-log-done
@ -4170,11 +4177,13 @@ specific settings like =TODO(!)=. For example:
:END:
#+end_example
#+kindex: C-u C-u C-u C-c C-t
#+kindex: C-u C-c C-t
#+cindex: @samp{LOGGING}, forcing
Even if you have not set up logging for a state, you can force logging
the state change by giving three {{{kbd(C-u)}}} to the =org-todo=
command, i.e. press {{{kbd(C-u C-u C-u C-c C-t)}}}.
the state change by giving a {{{kbd(C-u)}}} to the =org-todo=
command, i.e. press {{{kbd(C-u C-c C-t)}}}. If you only occasionally
want to log a state change note, this may be the most efficient and
least distracting way to do so.
*** Tracking your habits
:PROPERTIES:
@ -9771,7 +9780,9 @@ the other commands, point needs to be in the desired line.
#+kindex: t
#+findex: org-agenda-todo
Change the TODO state of the item, both in the agenda and in the
original Org file.
original Org file. A prefix arg is passed through to the ~org-todo~
command, so for example a {{{kbd(C-u)}}} prefix are will trigger
taking a note to document the state change.
- {{{kbd(C-S-RIGHT)}}} (~org-agenda-todo-nextset~) ::
@ -10927,8 +10938,9 @@ a major LaTeX mode like AUCTeX in order to speed-up insertion of
environments and math templates. Inside Org mode, you can make use of
some of the features of CDLaTeX mode. You need to install
=cdlatex.el= and =texmathp.el= (the latter comes also with AUCTeX)
from [[https://staff.fnwi.uva.nl/c.dominik/Tools/cdlatex/]]. Do not use
CDLaTeX mode itself under Org mode, but use the light version Org
using [[https://melpa.org/][MELPA]] with the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Package-Installation.html][Emacs packaging system]] or alternatively from
[[https://staff.fnwi.uva.nl/c.dominik/Tools/cdlatex/]]. Do not use
CDLaTeX mode itself under Org mode, but use the special version Org
CDLaTeX minor mode that comes as part of Org. Turn it on for the
current buffer with {{{kbd(M-x org-cdlatex-mode)}}}, or for all Org
files with

View File

@ -2117,31 +2117,35 @@ more information."
:type '(choice (const sequence)
(const type)))
(defcustom org-use-fast-todo-selection t
(defcustom org-use-fast-todo-selection 'auto
"\\<org-mode-map>\
Non-nil means use the fast todo selection scheme with `\\[org-todo]'.
This variable describes if and under what circumstances the cycling
mechanism for TODO keywords will be replaced by a single-key, direct
selection scheme.
selection scheme, where the choices are displayed in a little window.
When nil, fast selection is never used.
When nil, fast selection is never used. This means that the command
will always switch to the next state.
When the symbol `prefix', it will be used when `org-todo' is called
with a prefix argument, i.e. `\\[universal-argument] \\[org-todo]' \
in an Org buffer, and
`\\[universal-argument] t' in an agenda buffer.
When it is the symbol `auto', fast selection is whenever selection
keys have been defined.
When t, fast selection is used by default. In this case, the prefix
argument forces cycling instead.
`expert' is like `auto', but no special window with the keyword
will be shown, choices will only be listed in the prompt.
In all cases, the special interface is only used if access keys have
actually been assigned by the user, i.e. if keywords in the configuration
are followed by a letter in parenthesis, like TODO(t)."
:group 'org-todo
:set (lambda (var val)
(cond
((eq var t) (set var 'auto))
((eq var 'prefix) (set var nil))
(t (set var val))))
:type '(choice
(const :tag "Never" nil)
(const :tag "By default" t)
(const :tag "Only with C-u C-c C-t" prefix)))
(const :tag "Automatically, when key letter have been defined" auto)
(const :tag "Automatically, but don't show the selection window" expert)))
(defcustom org-provide-todo-statistics t
"Non-nil means update todo statistics after insert and toggle.
@ -9995,20 +9999,20 @@ By default the available states are \"TODO\" and \"DONE\". So, for this
example: when the item starts with TODO, it is changed to DONE.
When it starts with DONE, the DONE is removed. And when neither TODO nor
DONE are present, add TODO at the beginning of the heading.
You can set up single-charcter keys to fast-select the new state. See the
`org-todo-keywords' and `org-use-fast-todo-selection' for details.
With `\\[universal-argument]' prefix ARG, change the keyword selection method. \
See the docstring
of the varible `org-use-fast-todo-selection' for more details.
With numeric prefix ARG, switch to that state.
With `\\[universal-argument]' prefix ARG, force logging the state change \
and take a
logging note.
With a `\\[universal-argument] \\[universal-argument]' prefix, switch to the \
next set of TODO \
keywords (nextset).
Another way to achieve this is `S-C-<right>'.
With a `\\[universal-argument] \\[universal-argument] \\[universal-argument]' \
prefix, force logging the state change and take
a logging note.
With a `\\[universal-argument] \\[universal-argument] \\[universal-argument] \\[universal-argument]' \
prefix, circumvent any state blocking.
With numeric prefix arg, switch to the Nth state.
With a numeric prefix arg of 0, inhibit note taking for the change.
With a numeric prefix arg of -1, cancel repeater to allow marking as DONE.
@ -10034,7 +10038,7 @@ When called through ELisp, arg is also interpreted in the following way:
(let ((org-blocker-hook org-blocker-hook)
commentp
case-fold-search)
(when (equal arg '(256))
(when (equal arg '(64))
(setq arg nil org-blocker-hook nil))
(when (and org-blocker-hook
(or org-inhibit-blocking
@ -10051,7 +10055,7 @@ When called through ELisp, arg is also interpreted in the following way:
(looking-at "\\(?: *\\|[ \t]*$\\)"))
(let* ((match-data (match-data))
(startpos (copy-marker (line-beginning-position)))
(force-log (and (equal arg '(64)) (prog1 t (setq arg nil))))
(force-log (and (equal arg '(4)) (prog1 t (setq arg nil))))
(logging (save-match-data (org-entry-get nil "LOGGING" t t)))
(org-log-done org-log-done)
(org-log-repeat org-log-repeat)
@ -10071,34 +10075,22 @@ When called through ELisp, arg is also interpreted in the following way:
(member (member this org-todo-keywords-1))
(tail (cdr member))
(org-state (cond
((and org-todo-key-trigger
(or (and (equal arg '(4))
(eq org-use-fast-todo-selection 'prefix))
(and (not arg) org-use-fast-todo-selection
(not (eq org-use-fast-todo-selection
'prefix)))))
;; Use fast selection.
(org-fast-todo-selection this))
((and (equal arg '(4))
(or (not org-use-fast-todo-selection)
(not org-todo-key-trigger)))
;; Read a state with completion.
(completing-read
"State: " (mapcar #'list org-todo-keywords-1)
nil t))
((eq arg 'right)
;; Next state
(if this
(if tail (car tail) nil)
(car org-todo-keywords-1)))
((eq arg 'left)
;; Previous state
(unless (equal member org-todo-keywords-1)
(if this
(nth (- (length org-todo-keywords-1)
(length tail) 2)
org-todo-keywords-1)
(org-last org-todo-keywords-1))))
((and (eq org-use-fast-todo-selection t) (equal arg '(4))
(setq arg nil))) ;hack to fall back to cycling
((and org-todo-key-trigger org-use-fast-todo-selection)
;; Use fast selection.
(org-fast-todo-selection this))
(arg
;; User or caller requests a specific state.
(cond
@ -10600,7 +10592,8 @@ prefer a state in the current sequence over on in another sequence."
(lambda (x)
(if (stringp (car x)) (string-width (car x)) 0))
fulltable)))
(expert nil)
(expert (equal org-use-fast-todo-selection 'expert))
(prompt "")
(fwidth (+ maxlen 3 1 3))
(ncol (/ (- (window-width) 4) fwidth))
tg cnt e c tbl subtable
@ -10609,7 +10602,9 @@ prefer a state in the current sequence over on in another sequence."
(save-window-excursion
(if expert
(set-buffer (get-buffer-create " *Org todo*"))
(org-switch-to-buffer-other-window (get-buffer-create " *Org todo*")))
(delete-other-windows)
(set-window-buffer (split-window-vertically) (get-buffer-create " *Org todo*"))
(org-switch-to-buffer-other-window " *Org todo*"))
(erase-buffer)
(setq-local org-done-keywords done-keywords)
(setq tbl fulltable cnt 0)
@ -10620,9 +10615,11 @@ prefer a state in the current sequence over on in another sequence."
(unless (= cnt 0)
(setq cnt 0)
(insert "\n"))
(setq prompt (concat prompt "{"))
(insert "{ "))
((equal e '(:endgroup))
(setq ingroup nil cnt 0 in-current-sequence nil)
(setq prompt (concat prompt "}"))
(insert "}\n"))
((equal e '(:newline))
(unless (= cnt 0)
@ -10640,6 +10637,7 @@ prefer a state in the current sequence over on in another sequence."
(setq tg (org-add-props tg nil 'face
(org-get-todo-face tg)))
(when (and (= cnt 0) (not ingroup)) (insert " "))
(setq prompt (concat prompt "[" (char-to-string c) "] " tg " "))
(insert "[" c "] " tg (make-string
(- fwidth 4 (length tg)) ?\ ))
(when (and (= (setq cnt (1+ cnt)) ncol)
@ -10651,7 +10649,8 @@ prefer a state in the current sequence over on in another sequence."
(insert "\n")
(goto-char (point-min))
(unless expert (org-fit-window-to-buffer))
(message "[a-z..]:Set [SPC]:clear")
(message (concat "[a-z..]:Set [SPC]:clear"
(if expert (concat "\n" prompt) "")))
(setq c (let ((inhibit-quit t)) (read-char-exclusive)))
(setq subtable (nreverse subtable))
(cond