unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* New version of todo-mode.el (announcement + user guide)
@ 2013-06-09 23:31 Stephen Berman
  2013-06-10 13:24 ` Bastien
                   ` (2 more replies)
  0 siblings, 3 replies; 37+ messages in thread
From: Stephen Berman @ 2013-06-09 23:31 UTC (permalink / raw)
  To: emacs-devel

I've written a new version of todo-mode.el, which I'd like to submit for
possible inclusion in Emacs.  It contains many improvements (IMO) and
adds many new features, and I hope todo-mode users and maybe also others
will find it useful.  Since this is not a completely new package but a
new version of a current Emacs library, I assume it's appropriate to
post the code here for review.  However, the size of the file is ~244k,
so should I compress it before posting, and if so, is there a preferred
compression (with gzip the file shrinks to ~58k, with bzip2 to ~46k,
with xz to ~48k)?

The new version still needs work and testing, but with enough of both I
hope it will become good enough to be part of Emacs and supersede the
current version.  Although I'm the maintainer of todo-mode.el, I don't
think it's within my prerogative to make that decision -- and even if it
were, I would still want the go-ahead from the core Emacs maintainers,
not only due to the new version's size (more than six and a half times
the size of the current todo-mode.el) but also because I've abandoned or
reimplemented almost all of the old version's code, and changed much of
its internals as well as significant parts of the UI.  Notwithstanding
all the changes and additions, those who are familiar with todo-mode.el
will still recognize its basic organization and handling of todo lists
and its basic UI in the new version, and I hope will find most of the
new features fairly plausible and intuitive.

In order for those who are interested to get an idea of -- and hopefully
give me feedback about -- the new version's functionality and usability
without having to read the code, I've drafted a detailed guide to its
UI, commands and most customization options, which is appended below.
The guide does not assume familiarity with todo-mode.el.  It should also
be useful to those who do want to examine the new version's code (I hope
some do, and help to improve it, since there are many parts of Emacs and
Lisp that I know little or nothing about).  Because of the guide's
length, I've added outline stars to the section titles, so enabling
outline-minor-mode may facilitate navigating through it.

The guide refers to the new version as "the Todos package" or simply
"Todos"; the file name is todos.el and the code uses the prefix
"todos-", so it's namespace clean with respect to todo-mode.el and can
be loaded without interfering with the latter.  If and when it's decided
to replace the old version with the new one, we could retain the old
name and prefix for continuity or go with the new name and prefix to
acknowledge the differences.  (The obvious alternative of calling the
package simply todo.el and keeping the current "todo-" prefix runs the
(probably slight) risk of causing confusion, since there already is (or
was) at least one third-party package with this name and prefix that at
least used to be available on the web.)

Steve Berman

========================================================================

The Todos package provides facilities for making, displaying, navigating
and editing todo lists.  A todo list is a list of todo items -- things
to do (in the widest sense) -- arranged in order of priority, with the
highest priority item at the top of the list and the lowest priority
item at the bottom.

The Todos user interface, which is described here, comprises a large
number of commands and user options distributed across five major modes.
The principle major mode is Todos mode; the other four (Todos Edit mode,
Todos Archive mode, Todos Categories mode, and Todos Filtered Items
mode) are subsidiary to and accessible from Todos mode.

* Todo Categories, Files and Items

In Todos each todo list is identified with a named category, so you can
group together thematically related todo items.  Each category is stored
in a file, which thus provides a further level of organization.  You can
create as many todo files, and in each as many categories, as you want.

All todo files reside in a single directory, whose location is specified
by the user option `todos-directory'.  This directory may also contain
other types of Todos files, which are discussed later (see the sections
Done Item Archives and Filtered Items).  Emacs recognizes Todos files by
their extension, so when you visit the files they are correctly
displayed in the appropriate mode.  When you interactively create a todo
file in Todos mode, the extension ".todo" is automatically added to the
base name you choose (as a rule, this name is also used for the other
types of Todos files, which have their own extensions).  As a user, you
only have to deal with the base name.

When you create a new todo file, you must also add at least one category
to it, and each todo item belongs to a category.  It is not possible to
have an uncategorized todo list, but you can always make a catch-all
category with a generic name like "Todo", which is in fact the default
name assigned to the first category when you create a new todo file, if
you don't provide a different name; you can change the default by
customizing `todos-initial-category'.

Each todo item is also a potential diary item, which means that if you
include a todo file in the Emacs diary file (see (emacs)Fancy Diary
Display), todo items that are not explicitly exluded (by being marked
with `todos-nondiary-marker') will be shown in the Fancy Diary display.
This effectively augments the Emacs diary with categorized diary
entries.

To make this possible, todo items must have the format of diary entries,
i.e., they have to begin with a date string recognized by the Emacs
diary¹ and calendar, and if they are longer than one line, all lines but
the first must begin with white space, in order to be seen in the Fancy
Diary display.  The Todos commands for inserting and editing todo items
ensure that these requirements are satisfied (see the section Other
Display Commands and Options).
-----
¹Two types of dates recognized by the Emacs diary are not supported in
the current Todos implementation: sexp diary entries and date strings in
which the year is omitted (however, the latter type is equivalent to
using `*' for an arbitrary year, which Todos does support).

The option `todos-include-in-diary' is nil by default, which means new
todo items are marked for exclusion from the diary.  Aside from changing
the default, you can also override it on each use of an item insertion
command, as well as change it with an editing command (see Item
Editing).

The Fancy Diary display is also Todos aware: since all items in the
Fancy Diary display are buttonized, if it displays an item from a Todos
file, clicking or typing <RETURN> on this item will switch to that file
and properly display the item's category, with point on the item.

* Todos Mode

To initialize your first todo file, invoke the command `todos-show'.
This prompts you for a file name (defaulting to `todos-initial-file'),
prompts you for the name of the first category (defaulting to
`todos-initial-category'), creates and visits the file and displays the
category in Todos mode, and then prompts you to enter the first item.
If you choose not to enter an item now, simply type `C-g', which leaves
the category empty but otherwise well-formed.  If you prefer not to be
prompted to enter an item on adding a new category, disable the option
`todos-add-item-if-new-category'.

** Todos Mode Entry Points

Once at least one todo file exists, invoking `todos-show' enters Todos
mode.  Invoked with a prefix argument, the command prompts for which
todo file to visit.  Otherwise, the first invocation of this command
after loading the Todos package visits the default todo file (option
`todos-default-todos-file') and shows its first category.  (You can get
a different display with the first invocation of `todos-show' by
customizing the option `todos-show-first'; these other possibilities are
noted below in the appropriate context.)

If you leave Todos mode and later invoke `todos-show' to re-enter it, by
default this returns you to the current (i.e., last displayed) category
of the current todo file, which is the one in the most recently selected
and still live buffer visiting a todos file.  If you disable the option
`todos-show-current-file', then non-initial invocations of `todos-show'
always return to the first or current category of the default todo file.

If you want to enter Todos mode and go directly to a specific category
instead the first or current category in the current or default todo
file, use the command `todos-jump-to-category'; see the section
Navigation for details.  You can also enter Todos mode by invoking a
todo item insertion command; see the section Item Insertion Commands for
details.

The most convenient way to use these commands to enter Todos mode is to
define global key bindings for them in your init file.  Good choices are
for `todos-show' and `todos-jump-to-category' are `C-c t' and `C-c j',
since these commands are bound to `t' and `j', respectively, in Todos
mode.  For invoking item insertion from outside of Todos mode, it is
useful to bind `todos-insertion-map', which is the key map containing
the bindings of all Todos item insertion commands, to `C-c i', since it
is bound to `i' in Todos mode; to complete the invocation, supply the
rest of the key sequence (details in the section on item insertion).

Finally, you can also visit a Todos file via `find-file' or Dired, like
any other file, and since Emacs recognizes it, the buffer will
automatically be in the appropriate Todos mode.  Moreover, as long as
the command you use to visit the file is listed in the option
`todos-visit-files-commands' (which by default contains `find-file' and
`dired-find-file'), it will also correctly display the file's first
category on first visiting the file (otherwise you have to use one of
the commands for navigating between categories in order to get a proper
display).

You can leave Todos mode by typing `q' (`todos-quit'), which does not
kill the current todo file buffer but buries it.  Doing this also saves
any changes you have made to the file, and leaves both the file and the
category that was displayed on quitting current for subsequent Todos
mode commands (unless the buffer made current by quitting is visiting
another file and category in Todos mode, in which case the latter become
current for Todos commands).

** Todos Mode Key Binding Conventions

For Todos commands to function properly, it is essential to maintain the
correct format at all three level of organization -- item, category, and
file.  Todos tries to minimize the risk of format corruption by hiding
certain parts of the format from the user, making the buffer read-only
and suppressing the self-insertion keys.  Consequently, it is normally
impossible to make changes to your todo files without explicitly
invoking Todos commands.

A beneficial side effect of this restrictiveness is that you can invoke
almost all Todos commands by typing ordinary printing characters, either
singly or in specified sequences, without using modifier keys, except
for the shift key for capitalization and the raw prefix argument `C-u';
numeric prefix arguments can be entered just by typing a number key.
The predefined key bindings in Todos are more or less mnemonic.  As a
rule, key sequences beginning with `C' are bound to commands applying to
categories, sequences beginning with `F' apply to (non-archive)
file-level commands, and those beginning with `A' apply to archives (a
special type of Todos file; see Done Item Archives).  Todos commands
applying to items, which constitute the majority, are bound to lower
case key sequences.

Almost all Todos mode commands fall into the following three types:
navigation, editing and display commands.

** Navigation

The navigation commands are for making another todo file, category, or
item the current one by moving point to it.² Since they are likely to be
used frequently and repetitively, it is convenient to have single lower
case keys for all of them, even those applying to categories and files.
-----
²Many editing commands can also do this by side effect, but since that
is not their main function, they are not included in this section.

Two of the navigation commands were already mentioned in the section on
Todos mode entry points:
- `t' (`todos-show') can be used in Todos mode to switch to another todo
  file that you can choose via minibuffer completion.  If a buffer is
  already visiting that file, it displays its current category; if
  invoking `t' opens the file, it display its first category (by
  default; see the option `todos-show-first' for other possibilities).
- `j' (`todos-jump-to-category') prompts for a category name, which you
  can choose via minibuffer completion.  The candidates for completion
  include the categories in the current todo file as well as those in
  the files listed in the option `todos-category-completions-files'.  If
  you type <RETURN> without choosing a category, the current category of
  the current todos file is automatically selected.  If you type the
  name of a non-existing category, you can add this to the file as a new
  category and jump to it.  If you invoke this command with a prefix
  argument, it first you prompts for which todo file to jump to (which
  you can also choose with minibuffer completion) and then for which
  category from that file; in this case, completion is only against the
  categories in the selected file.

It is also convenient to navigate back and forth sequentially between
the categories of a single todo file.  The categories of a todo file are
numbered consecutively starting with 1.³  The current category's number
and name appear in the mode line.
- `f' (`todos-forward-category') moves point to the first item of the
  category numerically directly following the current category.
- `b' (`todos-backward-category') moves point to the first item of the
  category numerically directly preceding the current category.
With `f' and `b' you can cycle through the categories, so for example,
if the last category is current and you type `f', then the first
category becomes current.
-----
³A category's number is automatically assigned when the category is
created: the category is appended to the end of the file, so its number
is simply the highest until another category is added.  There is no
command in Todos mode to reorder the numbering of the categories in a
todo file, but this is possible in Todos Categories mode; see below.

You can also navigate between the items in the current category:
- `n' (`todos-next-item') moves point down to the next item below the
  current one (i.e., to the item with the next lower priority).
- `p' (`todos-previous-item') moves point up to the item directly above
  the current one (i.e., to the item with the next higher priority).
These commands also accept a positive numeric prefix argument; e.g.,
typing `5 n' or `5 p' navigates in one step to the item five items lower
or higher than the current one.

Navigation to other types of Todos files is discussed in the relevant
sections below.

** Editing

Editing includes structural changes such as adding, moving and removing
whole categories or one or more items in a single category, as well as
textual changes to parts of these units (editing proper).  To save
changes you make to the current todo file, type `s' (`todos-save').
Changes are also saved on quitting Todos mode with `q'.

*** File Editing and Todos Edit Mode

There are two file-level editing commands:
- `F a' (`todos-add-file') is for adding a new todo file; it prompts for
  a name and creates the file in `todos-directory', adding the ".todo"
  extension.  It also prompts for the file's first category and, if
  option `todos-add-item-if-new-category' is enabled (the default), for
  that category's first item.  (To rename or delete a todo file, simply
  use standard Emacs file commands; note that you may then need to reset
  customizations whose values are or include Todos file names.)
- `F e' (`todos-edit-file') changes the buffer's major mode to Todos
  Edit mode.  In this mode the entire file is visible, the buffer is
  writeable and you can use the self-insertion keys and standard Emacs
  editing commands to make changes.  To return to Todos mode, type `C-x
  C-q' (`todos-edit-quit').

The latter command is not intended for normal editing of items and
categories, as it circumvents the restrictions mentioned above that
Todos imposes to protect against file format corruption (i.e., all
categories, not just the current one, and all internal formatting are
exposed and editable).  It is provided primarily as a convenience for
two types of use cases that are likely to arise infrequently.  One is to
be able to use the standard Emacs commands `query-replace' to replace a
piece of text that occurs in different categories throughout the file.
The other use case is to recover from a mistake, such as accidentally
deleting an item, since this cannot be undone in Todos mode.

Using `C-x C-q' to quit Todos Edit mode provides a measure of safety,
since it runs a file format check, signalling an error if the format has
become invalid.  However, this check cannot tell if the number of items
changed, which could result in the file containing inconsistent
information (see the section on Todos Categories mode for more details).
For this reason `F e' should be used with caution.

*** Category Editing

The following commands are available for editing at the category level
(additional category-level commands, which are extensions of item
commands, are listed below in the relevant context):
- `C a' adds a new category to the current todo file or, invoked with a
  prefix argument, to a file you choose.  This command is similar to
  using `j', but it only accepts a name of a nonexisting category in the
  file.
- `C r' renames the current category.
- `C m' moves the current category (with all its items) to another file.
- `C k' deletes the current category.⁴ To delete a category that
  contains items, you have to confirm your intent; if the category is
  empty, deletion is immediate.
- `C g' merges the items of one category into another category, which
  results in the first category being deleted.  Minibuffer completion of
  the name of the category merged to works as with the navigation
  command `j', and as with that command, passing a prefix argument,
  i.e., typing `C-u C g', prompts for a file and confines merging to a
  category in that file.
-----
⁴This binding is mnenomic for "kill" to parallel the binding `k' for
item deletion, since `d' is bound to another item editing command (see
below).

*** Item Editing

Todos provides commands for adding, deleting, relocating and textually
changing items.

**** Item Insertion Commands

There are many commands for adding new todo items.  The command names
contain the word "insert" instead of "add" and their key bindings are
sequences beginning with `i'.  The motivation for this terminology is
that speaking of adding an item to a category suggests appending it to
the top or bottom, whereas you can insert an item into the category
anywhere, giving each new item any priority in the list.

- `i i' (`todos-insert-item') is the basic command for inserting new
  items.  Called without a prefix argument, it prompts for the text of
  the item and its priority (a number between 1 and one more than the
  number of items already in the category), both of which you enter in
  the minibuffer, and inserts the item into the current category of the
  current todo file at the position in the list corresponding to the
  priority you chose.  Called with one prefix argument, it also prompts
  for a category, and called with two prefix arguments, it prompts for
  both a file and a category from that file, and inserts the item
  accordingly.  Category name completion works as with the navigation
  command `j'.

Each invocation of `i i' adds a header string to the item, which
includes at least the current date in the same format used by
`diary-insert-entry'.  You can control what other information is
included in the header by customizing the following options:
- `todos-always-add-time-string' to include or omit the current time;
- `todos-include-in-diary' to specify whether the item appears in the
  Fancy Diary display by adding or omitting `todos-nondiary-marker';
- `todos-diary-nonmarking' to add or omit `diary-nonmarking-symbol' to
  items displayed in the diary.

Instead of always adding the same header information to a new item, you
can use more specific insertion commands that let you decide what to
include in the item header each time you insert a new item.  And instead
of always being prompted to choose the new item's priority, you can
invoke a command to insert it at the position (hence with the priority)
of the item at point.  Finally, instead of always typing the text of the
new item in the minibuffer, you can invoke a command that makes the
selected region in an Emacs buffer automatically become the new item's
text.  The following paragraphs discuss how to invoke these commands by
typing certain key sequences.

There are eight parameters of item insertion in Todos, six concerning
the item header, and one each concerning its priority and its text.
Each unique combination of these parameters produces a different
insertion command.  The command `i i' realizes one of these
combinations.  For the commands that realize the remaining combinations
it is convenient to associate each parameter with a mnenomically chosen
key.  Then by typing certain sequences of these keys, you complete the
insertion command invocation that realizes the specified combination.
As with `i i', the effect of many of these commands also depends on the
values of the item insertion options mentioned above (see the examples
below).

Here is a list of the parameters and their associated keys, in the order
in which you must type them when building a key sequence (this order
roughly reflects the order in which the corresponding parts of the item
occur in a category listing):
(1) `y' for diary (non)inclusion; 
(2) `k' for adding or omitting `diary-nonmarking-symbol'; 
(3) `c' for adding the date header by clicking a date in the Emacs
        calendar, or 
    `d' for interactively entering the date header as a string of year,
        month and day number components in the minibuffer, or
    `n' for interactively entering the date header as a weekday name in
        the minibuffer;
(4) `t' for adding a time string to the header in the minibuffer
        (including the empty string, which amounts to omitting the
        time);
(5) `h' for inserting the new item in the position of the item at point
        ("here"), or
    `r' to use the text of the selected region as the item's text. 

Each insertion command key sequence begins (disregarding prefix
arguments) with `i', followed by one or more of these eight keys, in the
order listed.  But since some of the insertion parameters are mutually
exclusive, they occupy only five positions, so the complete (unprefixed)
sequences are maximally six keys long.  Shorter sequences are also
possible, since a parameter may be omitted.  But since the order in any
key sequence is fixed, if the last key in the sequence could be followed
by another insertion key, i.e., if the last key is not `h' or `r', it
has to be doubled to complete the sequence, otherwise, it would be
interpreted as a prefix sequence (this is why the binding for the basic
item insertion command is `i i' and not `i').

Here are some examples of item insertion command key sequences:
- `i h' inserts a new item at the position of the item at point (pushing
  the latter down) with a header containing the current date and,
  depending on the values of the mentioned options, possibly the current
  time and diary-related markings.
- `i y h' does the same as the preceding command, except that
  `todos-nondiary-marker' is added if `todos-include-in-diary' is
  non-nil and omitted if that option is nil; that is, the diary key `y'
  overrides the setting of this option.
- `i y t h' does the same as the preceding command, except that it
  prompts for a time string instead of automatically inserting the
  current time; however, typing <RETURN> at the prompt returns the
  current time if `todos-always-add-time-string' is non-nil, otherwise
  the empty string (i.e., no time string).
- `i y t t' does the same as the preceding command, except that it
  prompts for the item's priority and inserts it accordingly.

Note that the commands whose key sequences include `y', `k' or `t'
reverse the effect of the options `todos-include-in-diary',
`todos-diary-nonmarking' and `todos-always-add-time-string',
respectively, thus temporarily overriding their values.

The names of the item insertion commands correspond to their key
bindings, e.g., `i h' is bound to `todos-insert-item-here', `i y h' to
`todos-insert-item-diary-here', etc.  But since there are so many
combinations, instead of trying to memorize either the names or the key
sequences, you can, as usual, just type an initial part of a key
sequence (minimally `i'), followed by `C-h' to see the valid
completions.

An alternative for choosing the item's date from the calendar is also
available: if point is on a date in the calendar, typing `i t'
(`todos-insert-item-from-calendar') will prompt for a new item and its
priority and insert it in the current category.  Like `i i' and the
other item insertion commands, this also accepts one or two prefix
arguments for choosing the category via minibuffer completion.  Note,
however, that the key sequence `i t' is not defined in Todos mode but in
the Calendar mode keymap.  It is a convenient shortcut if you happen to
be using the calendar when you decide to make a new todo item.
(Contrast this with a command like `i c c', which pops open the calendar
after you have entered the item's text, and then you can choose a date
from the calendar.)

There is one more item insertion command, which does not derive from the
item insertion parameters:
- `i p' (`todos-copy-item') makes a complete copy of the item at point,
  including its header, prompts for its priority in the current category
  and inserts it accordingly.
This command is useful for quickly adding a todo item whose text or
header you want to differ only partly from that of an existing item:
after inserting the copy, you can quickly edit it as needed by using
commands described in the next section.

**** Editing Item Header and Text

There are a number of commands for editing an existing item's text or
header; these commands are bound to key sequences with `e'.

There are two commands for editing an item's text (and optionally,
manually editing its header):
- `e e' (`todos-edit-item') is for editing the text of the item in the
  minibuffer, so it is especially useful for short edits.  If called
  with a prefix argument (`C-u e e'), the item's header is also included
  in the minibuffer and so can be edited manually.
- `e m' (`todos-edit-multiline-item') is useful for more complex changes
  or for editing lengthy items, since you edit the item in its own
  buffer in Todos Edit mode.  When you have finished editing, type `C-x
  C-q' to return to Todos mode; this runs a format check to ensure the
  item is well-formed.  (Note that, unlike the command `F e' discussed
  above, this command does not expose you to the risk of putting the
  file in an inconsistent state, since it puts only the current item in
  Todos Edit mode.)

A number of commands are available for interactively editing all or part
of the item header, permitting quick edits and helping avoid formatting
errors.

There are three commands for editing any or all of the year, month and
day components of a date header:
- `e d t' successively prompts for changes to the date's year, month and
  day number, and if the option `todos-always-add-time-string' is
  non-nil, also for editing the time string (see also `e t' below).
- `e d a' directly changes the date to today's date.
- `e d c' pops up the Emacs calendar, and typing <RETURN> on a date in
  the calendar makes that date the item's date.
These commands also change a date header consisting of a weekday name to
a header with year, month and day components.  In contrast, each of the
following three commands changes only a single date component and has no
effect on a date header consisting of a weekday name:
- `e d y', `e d m' and `e d d' prompt for changing just the year, month
  or day number, respectively; but if invoked with a positive or
  negative numeric prefix argument, they directly increment or decrement
  the date component accordingly and automatically adjust the other date
  component if necessary.  For example, if the date string is "January
  1, 2013", typing `- 3 e d d' results in "December 29, 2012".

- `e d n' prompts for a weekday name and makes it the item's date
  header.  Note that this replaces an existing date string, it does not
  add the day name to the date string. 
- `e t' is for editing just the item's time string.  A time can be added
  both to a date string and to a weekday name.  If you type <RETURN> at
  the prompt, this omits a time string from the header, or deletes an
  existing time string.
- `e y y' is for changing the item's diary inclusion status, by adding
  or removing `todos-nondiary-marker'.
- `e y k' is for changing the item's diary marking status, by adding or
  removing `diary-nonmarking-symbol' (this command has an effect only if
  the item is not marked for exclusion from the diary).
Parallel to the latter two commands are the corresponding category-level
commands `C e y' and `C e k', which add `todos-nondiary-marker' and
`diary-nonmarking-symbol', respectively, to all todo items in the
current category; if invoked with a prefix argument, these markings are
removed from all items in the category.

**** Item Relocation and Removal

In addition to inserting a new todo item and textually editing an
existing item, you can also move an item to another category (i.e.,
recategorize it), change its priority within its category, delete it
from the category and file, or mark it as a "done" item, which removes
it from the todo list but does not delete it.

There are three ways to change a todo item's priority: 
- `r' raises its priority by one, exchanging its position in the list
  with that of the item directly above it.
- `l' lowers its priority by one, exchanging its position in the list
  with that of the item directly below it.
- `#' prompts for a number and relocates the item to the corresponding
  position in the list.  For example, entering "3" makes the item the
  third in the category, i.e., gives it third highest priority.  You can
  also pass the desired priority as a numeric prefix argument, e.g.,
  `3 #' gives the item third highest priority without prompting.
  (Prefix arguments have no effect with `r' or `l'.)

You can also move and delete items:
- `m' moves the item at point to another category.  This prompts for a
  category to move the item to, displays that category, prompts for the
  priority of the moved item in the category moved to and inserts the
  item accordingly.  Minibuffer completion of the name of the category
  moved to works as with the navigation command `j', and as with that
  command, passing a prefix argument prompts for a file and moves the
  item to a category in that file; and if the category name you enter is
  new, then you are asked whether to add the category to the file, and
  if you affirm, the item is moved to the new category.
- `k' deletes the todo item at point (the binding is mnenomic for
  "kill", since `d' is used for marking items as done; but note that `k'
  does not put the item into the kill ring).  This command requires
  confirmation that you want to delete the item, since you cannot undo
  the deletion in Todos mode.  (You could use `F e' to recover the item,
  but be aware that this would put the file in an inconsistent state,
  which you can recover from, but not without a risk; see the warning in
  the section on Todos Categories mode.)

A note about confirming commands: Todos commands that require user
confirmation use a modified form of `y-or-n-p', which by default only
accepts `y' or `Y', but not <SPC>, as an affirmative answer.  This is to
diminish the risk of unintentionally executing the command, which is
especially important with commands that do deletion, since there is no
Todos command to undo a deletion.  If you want to be able to use SPC for
confirmation with `y-or-n' questions, enable the option
`todos-y-with-space'.

***** Done Items

When the activity or thing that a todo item is about has been done, it
is natural to eliminate the item from the todo list.  But instead of
deleting it permanently, you may prefer to keep a record of your
accomplishments by marking the item as done.  In Todos, this removes the
done item from the todo list, so as not to clutter it up, and stores it
elsewhere.  Such stored items form a record or diary of things done.
The Todos package provides two such stores: the "done items" section of
a Todos category, and done item archives.

- `d' (`todos-item-done') removes the todo item at point from the todo
  list, appends to the original header a header consisting of
  `todos-done-string' (by default "DONE ") and the current date, and if
  `todos-always-add-time-string' is enabled, also the current time, and
  adds the resulting string to the top of the done items section of the
  category.  Invoked with a prefix argument, it also prompts you to
  enter a comment, which is appended to the end of the done item,
  prefixed with `todos-comment-string' (by default "COMMENT: ").

A category's done items section is located below the last todo (i.e.,
not done) item in the category.  By default this section is hidden from
view.  There are two commands for viewing done items:
- `C v' or `v' makes the hidden done items section of the current
  category visible, and also hides it again.  Since this command is a
  toggle, for convenience it also has the single key binding `v'.  If
  you always want to see the done items section on entering a category,
  enable the option `todos-show-with-done'; you can still use `C v' or
  `v' to hide (and unhide) it.
- `F V' or `V' toggles the standard category display in the current todo
  file, i.e., displays only the done items section of each category in
  the file, or if this is visible, hides it again and displays only the
  todo items section.

Three commands are provided for editing done items:
- `e c' (`todos-edit-done-item-comment'): If you type this when point is
  on a done item that has a comment, you can edit the text of the
  comment.  If you invoke it with a prefix argument (`C-u e c'), the
  comment is deleted on confirmation.  If the done item does not have a
  comment, `e c' allows you to add one.
- `m' moves the done item at point to the top of the done items section
  of another category.  This is useful in case, after having relocated
  an item to its category's done items section, you create a category
  that is better suited to the content of the done item than its current
  category, so you can recategorize the done item.
- `u': If you decide the done item at point is not done after all, this
  command "undoes" it, i.e., restores it to the todo list of its
  category, with the priority you choose for it.  If the done item has a
  comment, you are asked whether to delete it from the restored item. 

* Done Item Archives and Todos Archive Mode

When the done items section of a category itself starts to become
cluttered, or if you just want to store some accomplished todo items in
a separate file, you can move them to a Todos archive.  This is a file
with exactly the same structure as a todo file, i.e., divided into
categories, but differs in that the categories contain only done items.
Todos archives reside, like todo files, in `todos-directory' but have
the extension ".toda" instead of ".todo".

Todos mode provides the following command for archiving items:
- `A d' (`todos-archive-done-item') archives the done item at point.
  Invoked with a prefix argument, it archives all done items in the
  current todo category.  If an archive for the current todo file
  already exists and contains a category with the same name as the
  current todo category, then this command moves the done item to the
  top of the corresponding archive category.  If the archive exists but
  it does not have a corresponding category, this command creates the
  category in the archive and moves the done item to it.  If no archive
  for the todo file exists, the command creates both the archive file,
  using the same base name as that of the todo file, as well as the
  category, and moves the done item to it.

Typing `A d' is also the only way within the Todos package to create an
archive file and its categories.  Consequently, as a rule each archive
file corresponds to exactly one todo file and has the same base name as
this file, and each category in an archive file corresponds to and has
the same name as a category in the corresponding todo file.  Exceptions
can only arise if you delete a todo file but not the corresponding
archive, or if you delete a category in a todo file that has a
corresponding category in an archive.

You might be inclined to do the latter if you have archived all the
items from a given todo category and you don't plan to add new items to
it.  In particular, if you have numerous such empty categories in a todo
file, this can make sequential navigation in the file annoying.  You can
avoid this annoyance by deleting these categories, but only at the cost
of putting the todo file out of synch with the archive file.

You may find it preferable not to delete empty todo categories but to
enable the option `todos-skip-archived-categories'.  When this is
non-nil, such empty todo categories are skipped over by the sequential
category navigation commands `f' and `b', so they don't distract you
while navigating and you maintain the structural correspondence between
todo and archive files (you can also still jump to empty todo categories
with `j').

If you rename a todo category that has a corresponding category in an
archive, the archive category is also automatically identically renamed.
Likewise, if you move such a todo category to another file; in this
case, if there is no archive file corresponding to the todo file the
category is moved to, then the archive is automatically created and the
archived category is moved to it.

There are two commands in Todos mode for visiting archive files:
- `A f' (`todos-find-archive') switches to a buffer displaying the
  archived category corresponding to the current todo category.  If the
  todo category has no archived items, the command asks if you want to
  visit the archive anyway.  If there is no archive for this todo file,
  it asks if you want to visit another archive, which you can select via
  minibuffer completion.
- `A c' (`todos-choose-archive') prompts you for an archive to visit,
  whether or not the current todo file has an archive.

As with todo files, you can also visit a Todos archive by invoking a
standard Emacs file-visiting command; this displays the first (on the
initial invocation) or current category of the archive.

When you visit a Todos archive, the buffer is in Todos Archive mode.  It
displays categories just as in Todos mode, except that they only contain
done items.  It provides the same sequential navigation commands as
Todos mode: `f' and `b' navigate between the categories of the current
archive, and `n' and `p' navigate between the done items of the current
archive category.

The commands `t' and `j' are also available in Todos Archive mode, and
they work the same as in Todos mode, which means they can only be used
to return to Todos mode: `t' prompt for and switch to a todo file, and
with `j' you can only jump to a todo category.  These commands exclude
archives because an archive file has the same base name as the
corresponding todo file, so the commands cannot know which type of file
you want to visit.  For this reason, there is a special command in Todos
Archive mode for jumping to another archive category or visiting another
archive file:

- `a' (`todos-jump-to-archive-category') prompts for a category in the
  current archive and jumps to it.  Called with a prefix argument, it
  prompts for another archive, then for a category in it and jumps to
  that category.

None of the Todos mode editing commands are available in Todos Archive
mode, since archives are meant to be static records of accomplished todo
items.  Should you, however, archive an item by mistake or simply change
your mind about the archival status of an item, you can "unarchive" it:
- `u' restores the done item at point to the top of the done items
  section of the corresponding category in the corresponding todo file,
  i.e., an unarchived item remains a done item.  When the last item in
  an archive category has been unarchived, the category is automatically
  deleted from the archive.  If this was the only category in the
  archive, the archive file is also automatically deleted.

Since it is natural to visit an archive from the corresponding todo
file, it would be convenient to easily return to the todo file when you
have finished browsing the archive.  If you type `q' to quit Todos
Archive mode, this switches to the corresponding todo file and shows the
todo category corresponding to the archive category you were just
visiting.

* Marked Items

For many item editing commands it can make sense and be convenient to
apply them simultaneously to more than one item in the current category.
Todos facilitates this by means of marked items.

- `*' (`todos-toggle-mark-item') marks the item at point if it is
  unmarked, and removes the mark it is already marked.  The mark is a
  string specified by the option `todos-item-mark' (by default "*")
  appended in front of the item header (more precisely, in front of the
  item's priority number or prefix; for details of the latter, see the
  section Todos Display Features).  After marking the current item, the
  command advances point to the next item.  It also accepts a numeric
  prefix argument, which allows toggling the mark of multiple
  consecutive items.

- `C *' marks all todo items in the current category.
- `C u' unmarks all todo item in the current category.
You can also use these two commands to mark or unmark all done items in
the category, but only when only the done items section is being
displayed, i.e., after invoking `C V' or `V'.

The following commands operate on marked items: `k' (deleting), `m'
(moving to another category), `d' (moving to the done items section;
note that `C-u d' adds the same comment to all marked items), `A d'
(archiving), `u' (both in Todos mode for undoing a done item and in
Todos Archive mode for unarchiving an item), as well as the commands for
editing the item header (those beginning with the prefix `e d' as well
as `e t', `e y y' and `e y k').  The item insertion, textual editing and
priority changing commands do not operate on marked items.

If you use `m', `d', `A d' or `u' on multiple noncontiguous marked
items, the relocated items retain their relative order but are now
listed consecutively en bloc.

You can mark both todo and done items, but note that only `m' can apply
to both; other commands only affect either marked todo or marked done
items, so if both types of items are marked, invoking these commmands
has no effect and informs you of your erroneous attempt.

* Todos Categories Mode: Table of Categories and Item Counts

It can be helpful to have a compact overview of the categories in a todo
file and the types of items it contains; Todos provides a tabular view
of this information.

- `F c' (`todos-show-categories-table') typed in Todos mode or Todos
  Archive mode switches to a buffer displaying a table that gives an
  overview of the categories in the current todo or archive file.  This
  buffer is in Todos Categories mode.

The table consists of a column containing the names of the categories in
the file, followed by columns containing counts of certain types of
items in each category.  With todo files there are four count types: all
todo (i.e., not done) items, diary items (i.e., those todo items lacking
the `todos-nondiary-marker', which hence can appear in the Fancy Diary
display), done (but not archived) items, and archived items.  With
archive files all items are done, so the table only has a column for
this count.  The final row of the table gives total item counts across
all categories in the file.

Above each column of the table is a labelled button you can press by
clicking with the mouse or by typing <RETURN> on it.  Pressing an item
count button sorts the table alternately in ascending or descending
order according to the type of count.  Pressing the category button
alternates between the initial numerical order of the categories and
alphabetical order.  In numerical order the column of category names is
preceded by a column containing the corresponding category numbers; this
column is not displayed in the alphabetical listing.  Instead of
pressing the buttons, you can also sort the table by typing the
following keys:
- `c' to sort by category numerically or alphabetically;
- `t' to sort by todo item counts;
- `y' to sort by diary item counts;
- `d' to sort by done item counts;
- `a' to sort by archived item counts.

Each row of the table is also buttonized; pressing one of these exits
the buffer (killing it), returns to the buffer of the file from which
you had invoked `F c', and displays the category that was named in the
row button you pressed (i.e., pressing this button jumps to that
category).  However, if the category named in the row is in a todo file
and all of its items have been archived, and you have enabled the option
`todos-skip-archived-categories', then pressing the button jumps to the
archive category instead of the empty todo category.  You can recognize
such categories by their items counts in the table -- all but the
archived counts are zero -- and in addition, their lines in the table
are also distinguished from the others by a different face.

You can navigate around the table:
- `n' or `TAB' advances to the next button.
- `p' or `S-TAB' (backtab) goes to the previous button.
These commands are cyclic, e.g. when point is on the last button,
pressing `n' moves it to the first button.

Typing `q' exits Todos Categories mode, killing the buffer and returning
to the current category in the Todos mode or Todos Archive mode buffer
from which you had invoked `F c'.

Todos Categories mode provides a function with which you can
persistantly change the numbering of the categories in the current file,
effectively reordering them for sequential navigation by `f' and `b' in
Todos mode and Todos Archive mode.  This functionality is only available
when the table displays the categories in their numerical order.  It
works just like reprioritizing items in Todos mode:
- `r' raises the current line of the table (the one the cursor is on),
  decreasing the category number by one.
- `l' lowers the current line of the table and increases category number
  by one.
- `#' prompts for a number between 1 and the number of categories in the
  file and reorders the table accordingly.  If invoked with a numeric
  prefix argument within the allowed range, the table is reordered
  without prompting.
The reordering done by these commands remains in effect when you return
to Todos mode or Todos Archive mode and, as long as you save the todos
or archive file after reordering, in subsequent sessions as well.

_*WARNING*_
It is important to be aware that renumbering the categories does not
change the textual order of the categories in the file.  This is
significant if you should invoke `F e' to edit the entire file manually
and in so doing alter the number of items in a category: this will make
the item count shown in the table of categories of this file
inconsistent with the actual number.  You can repair this inconsistency
by invoking the command `todos-repair-categories-sexp' (which lacks a
key binding, since it is meant to be a rarely needed rescue operation).
But this will revert any renumbering of the categories you have made, so
you will have to renumber them again.  This is the reason why you should
exercise caution when using `F e'.  

Aside from explicitly invoking `F c' to display the table of categories,
you can also arrange to have it displayed on the first invocation of
`todos-show' for a given file (i.e., either using `todos-show' to
initiate a Todos session, or calling it in Todos mode to visit another
todo file).  To do this customize the option `todos-show-first'.

* Searching, Filtered Items and Todos Filtered Items Mode

It can be useful to be able to locate and examine all todo items that
fit certain criteria, regardless of which category they belong to.
Todos mode provides two ways to do this.

- `S' (`todos-search'; the key is capital `S') prompts for a regular
  expression, searches from the beginning of the current todo file and
  displays the category containing the first match it finds, with the
  match highlighted.  If there are further matches, a message saying how
  many are left is displayed and you are asked if you want to go to the
  next match.  When you reach the last match, or if you decide not to go
  to further matches, you are asked whether the match highlighting
  should be removed.
- `X' (`todos-clear-matches') removes any highlighting added by `S'.
  This is so you can leave the matches highlighted at the end of the
  search and remove the highlighting later.
These commands are also available in Todos Archive mode.

A more powerful alternative to sequential searching is item filtering,
by which items from different categories that match specified criteria
are gathered and displayed in a new buffer as a kind of virtual
category in a distinct mode, Todos Filtered Items mode.  

** Filtering Items

Todos provides three cross-categorial filters: a general filter for
items matching a user-entered regular expression, as with the search
command; and two specific filters, one for diary-displayable items
(i.e., those lacking `todos-nondiary-marker') and one for top priority
items (more on the latter below).  The commands for each filter come in
pairs, one for filtering just the current todo file and one for
filtering a user-specified list of todo files.  Thus, there are six item
filtering commands:⁵
- `F r r' (`todos-filter-regexp-items')
- `F r m' (`todos-filter-regexp-items-multifile')
- `F y y' (`todos-filter-diary-items')
- `F y m' (`todos-filter-diary-items-multifile')
- `F t t' (`todos-filter-top-priorities')
- `F t m' (`todos-filter-top-priorities-multifile')
-----
⁵The use of `F' in the key sequences of these commands naturally recalls
"filter", but is also consistent with the Todos mnenomic key binding
convention, since the commands involve one or more whole files.

There are two ways to specify which files the multifile filtering
commands apply to.  If there are files you want to filter every time you
use these commands, customize the option `todos-filter-files'.  If you
leave this option empty (the default), invoking a multifile filtering
command pops up a buffer similar to the Customization buffer for
`todos-filter-files', in which you can select files to filter just for
this invocation.

Diary and top priority items are by definition non-done todo items, but
when filtering by regular expression, you can extend the scope of the
command to done items by enabling the option `todos-filter-done-items'.
Then `F r r' and `F r m' will gather both matching todo and matching
done items (including done items from any archive files corresponding to
the selected todo files) into the virtual category of filtered items.

There are several ways to specify how many items in each category count
as top priorities and hence get filtered by `F t t' and `F t m':
- The option `todos-top-priorities' specifies a single default number
  for all categories and all todo files; its default value is 1, which
  means just the highest priority item in every category is filtered,
  unless otherwise specified.
- The option `todos-top-priorities-overrides' lists file-wide overrides
  of `todos-top-priorities' as well as category-specific overrides.  It
  is empty by default.  However, using the Custom facility to set this
  option would be tedious and error-prone, so instead you should use the
  commands `F t s' and `C t s'.  The former sets (i.e., overrides) the
  default number of top priorities for all categories in the current
  todo file, and the latter sets the number of top priorities for the
  current category.  To exclude a category or file from filtering by `F
  t t' and `F t m', set the number to 0.
- You can invoke `F t t' and `F t m' with a numeric prefix argument,
  which specifies the number of top priorities in each category just for
  this invocation, overriding both `todos-top-priorities-overrides' and
  `todos-top-priorities'.

** Todos Filtered Items Mode Commands

The output of the item filtering commands looks similar to a regular
Todos category, but it is not contained in any todo file and does not
have a name on being created, so it is not a "real" category but a
"virtual" category.  Another difference is the lack of a done items
section; either there are no done items in the list (when the filtered
items are diary or top priority items), or these are displayed in the
same list as todo items (if you filtered by regular expression and
allowed done items).  A further difference is that the items have an
additional header, between the item's date/time header and its text,
specifying which category (and if you invoked a multifile command, also
which file) the item comes from, and if you filtered by regular
expression, also whether the item comes from a Todos archive.

The sequential item navigation commands `n' and `p' work the same in
Todos Filtered Items mode as in Todos mode, as do the file and category
jumping commands `t' and `j'; however, the sequential category
navigation commands are unavailable, since virtual categories of
filtered items are not ordered with respect to "real" categories.  In
addition, Todos Filtered Items mode provides a special navigation
command:
- `g' or <RETURN> (`todos-go-to-source-item') typed with point on a
  filtered item switches the buffer to the item's source file (in Todos
  mode or Todos Archive mode, as the case may be) and displays its
  category, with point on the item.

Filtered items cannot be textually edited, moved to another category,
marked done or archived like items in a real todo category, since these
would then be out of synch with each other.  But there is one type of
editing command that does work in Todos Filtered Items mode: changing an
item's priority:
- `r', `l' or `#', respectively raises, lowers, or sets the current
  item's priority in the virtual category.

Using these commands, you can create a cross-categorial (and even
cross-file) prioritized list of filtered items.  However, there is a
restriction on these commands in Todos Filtered Items mode: you cannot
change the relative priorities of items from the same real category,
since that would make the filtered list inconsistent with the source
todo list.

** Files of Filtered Items

Typing `s' in Todos Filtered Items mode saves the buffer of filtered
items to a file in `todos-directory'.  Files of items filtered by
regular expression have the extension ".todr", those with filtered diary
items have ".tody" and those with filtered top priorities have ".todt";
the extensions are added automatically the first time you write the
buffer to a file.

With filtered top priority or diary items, the file is automatically
named on first saving it, using as the base name either the same base
name as the single todo file it was generated from, or combining the
base names of the todos files used in multifile filtering commands.
With items filtered by regular expression, it can be useful to save
separate lists generated from the same file(s) using different regular
expressions, so when saving such a list, you are prompted for a short
identifying string to add to the file name.

When you invoke one of the item filtering commands without a prefix
argument and a corresponding file already exists, the command visits
this file (if, for the current file or chosen files, there are multiple
files of items filtered by regular expression, you are prompted to
choose one).  To force generation of a new filtered list, invoke the
command with a prefix argument (in the case of top priority items,
either numeric as described above, or the raw prefix argument `C-u' to
use the values of `todos-top-priorities-overrides' or
`todos-top-priorities').

Aside from explicitly invoking an item filtering command to display a
saved list of items filtered by a given method from given todos files,
there are two other ways to visit a saved file of filtered items:
- `F f' (`todos-find-filtered-items-file') visits whichever file of
  filtered items you choose, via minibuffer completion, from among all
  saved filtered items files.
- As with tables of categories, by customizing `todos-show-first' you
  can have the first invocation of `todos-show' for a given todo file
  display the corresponding saved file of filtered items.  If there is
  no saved filtered items list for the file, `todos-show' simply
  defaults to visiting the file and displaying its first category, as
  usual.

* Todos Display Features

You can change the appearance of Todos buffers in a variety of ways.  

** Faces

Each of the Todos modes uses faces to distinguish various aspects of the
display, both structural and informational.  The `todos-faces'
customization group contains a complete list of Todos faces and brief
descriptions of their use.

For example, the faces for the date and time strings of todo item
headers by default inherit the attributes of the corresponding faces
used by the Emacs diary; but when the date and time of a Todos diary
item (i.e., an item lacking `todos-nondiary-marker') is earlier than the
current date and time, they are displayed in a different face.  In this
way, you can readily recognize diary items that have "expired" and act
accordingly (e.g., by tagging them as done or by updating the
deadlines).

** Item Prefix

In the default display of (real or virtual) categories in Todos mode,
Todos Archive mode and Todos Filtered Item mode the items are visually
numbered in ascending order, starting with "1" on the top item,
displayed to the left of its header (date/time string).  With todo items
the numbers indicate each item's priority in the list, so when you
reprioritize an item with `#' or moving it with `m', these numbers make
it easier to choose the item's new priority.  The numbering also lets
you to see at a glance how many items there are in the list.  When an
item is inserted, deleted, or moved, the numbering is automatically
updated.  In Todos mode, the todo and done items sections in each
category are separately numbered.

If you prefer not to have item numbering displayed, disable the option
`todos-number-prefix'; then the display of each item starts by default
simply with its header.  But you can also replace the numbering with a
visually distinctive string of your choice by customizing the option
`todos-prefix' (the empty string by default).  Another alternative is to
temporarily hide the item numbering:
- `F N' or `N' toggles between displaying item numbering and displaying
  the `todos-prefix' string in the current Todos file (todo, archive, or
  saved virtual category of filtered items; the command also works in
  buffers of filtered items that have not yet been written to a file.)

In the todo items section of each Todos mode category, the item prefix
(whether a priority number or a fixed string) of the top priority items
(determined as specified above) is displayed in a different face from
the prefix of the other items, so you see at a glance how many items in
the category are top priorities.

** Other Display Commands and Options

There are two additional toggle commands that affect display in the
current file:
- `F h' or `h' hides the item headers, or shows them if they are hidden.
  With done items, only the done header (i.e. the done tag and date-time
  string inserted when the item was marked done) is hidden, the original
  date-time string is not. With filtered items, the category (or
  category-file) tag is not hidden.
- `F H' or `H' highlights the current item, or removes its highlighting.
  When item highlighting is enabled, it follows navigation by `n' or
  `p'.  If you want to have current item highlighting by default, enable
  the option `todos-highlight-item'.  `F H' or `H' will still toggle it.

There are two options which affect the display of items whose content is
longer than one screen line:
- `todos-indent-to-here' sets the amount of indentation for all lines
  after the first in multiline todo items, which is necessary in order
  for todo diary items to be fully visible in the Fancy Diary display.
  The default indentation is 3 spaces.  For a uniform appearance this
  option applies to all items, i.e., diary and nondiary todo items and
  also done items.
- `todos-wrap-lines' allows you to choose between inserting and editing
  multiline todo item as multiple logical lines with hard line breaks or
  as multiple visual lines using Visual Line mode; the latter is the
  default.  Since multiparagraph items also contain hard line breaks in
  Visual Line mode, for a uniform appearance this display shows
  indentation on wrapped lines by using a wrap-prefix of
  `todos-indent-to-here' spaces.
The indentation inserted after a hard newline is actually a tab
character, and the Todos modes that display items bind `tab-width' to
`todos-indent-to-here', so if you change the default value of the
latter, the next time you visit a Todos file, the indentation will
reflect your change.

By default, the todo and done items sections of a todo category are
visually separated by a line as wide as the window the buffer is
displayed in.  You can change the appearance and width of the separator
by customizing `todos-done-separator-string'; you can also change the
face of the separator string.

There are also several options for changing the appearance in Todos
Categories mode and Todos Filtered Items mode, beyond those mentioned
above in the sections on these modes; see the customization groups
`todos-categories' and `todos-filtered' for details.

* Printing Todos Buffers

If you print a Todos buffer using one of the standard Emacs printing
commands, it does not look exactly like what you see in the buffer.
This is because some of the display features are non-printable
(specifically, those using overlays, word-wrap and wrap-prefix).  Todos
provides two print commands that produce output which include printable
counterparts of such display features:
- `P B' sends the output directly to your printer.
- `P F' prompts you for a file name to write the output to and saves it.

By default, Todos uses `ps-print-buffer-with-faces' to make the
printable version; you can change this by setting the option
`todos-print-function'.

* Legacy Todo Mode Files

Users of the original todo-mode.el will recognize from the preceding
description of the Todos package that, although the two packages share
the same basic user interface and handling of todo items, there are some
incompatible differences between them, such as the done items sections
(there are also other file format incompatibilities behind the scenes
that are normally not visible to users).

The most significant incompatibility concerns the item prefix.  In
todo-mode.el the prefix is part of the item string itself, so in order
for the item to be displayable in the Emacs diary, the prefix must be a
date/time pattern recognizable by the diary (although the todo item also
has its own date/time header).  Moreover, since all items have the same
prefix, this means that either all or no items are shown in the Fancy
Diary display on any given date.  This considerably restricts the
practicality of including todo items in the diary.  In contrast, Todos
uses overlays for item priority numbering or prefixes, and item-specific
diary-compatible date/time headers and special marks for todo items to
be excluded from the diary, so you can determine for each item whether
and when an it is displayed in the diary.

Due to these incompatibilities, files created with the original
todo-mode.el cannot be displayed or edited in Todos.  To overcome this,
the command `todos-convert-legacy-files' is available in Todos mode
(there is no key binding for it, since it shouldn't be necessary to use
it often).  This converts the two files whose names are the values of
`todo-file-do' and `todo-file-done' to valid Todos todo and archive
files, respectively, and saves them in `todos-directory'.  (A delicate
part of the conversion concerns the customizable format of item
date/time headers in todo-mode.el; see the documentation string of
`todos-todo-mode-date-time-regexp' for details.)




^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-09 23:31 New version of todo-mode.el (announcement + user guide) Stephen Berman
@ 2013-06-10 13:24 ` Bastien
  2013-06-10 14:35   ` Stephen Berman
  2013-06-13 10:59 ` Vitalie Spinu
  2013-08-31  3:55 ` Jambunathan K
  2 siblings, 1 reply; 37+ messages in thread
From: Bastien @ 2013-06-10 13:24 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel

Hi Stephen,

Stephen Berman <stephen.berman@gmx.net> writes:

> I've written a new version of todo-mode.el, which I'd like to submit for
> possible inclusion in Emacs.

I'm interested in testing it -- I've played with the current version
of todo-mode.el (included in Emacs trunk), but since you say the UI
has been largely revamped, I'd like to invest in the new UI.

Can you share the new version somewhere?  I could not find any link.

Thanks in advance!

-- 
 Bastien



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-10 13:24 ` Bastien
@ 2013-06-10 14:35   ` Stephen Berman
  2013-06-10 14:49     ` Bastien
  2013-06-10 14:52     ` New version of todo-mode.el (announcement + user guide) Óscar Fuentes
  0 siblings, 2 replies; 37+ messages in thread
From: Stephen Berman @ 2013-06-10 14:35 UTC (permalink / raw)
  To: Bastien; +Cc: emacs-devel

On Mon, 10 Jun 2013 15:24:02 +0200 Bastien <bzg@gnu.org> wrote:

> Hi Stephen,
>
> Stephen Berman <stephen.berman@gmx.net> writes:
>
>> I've written a new version of todo-mode.el, which I'd like to submit for
>> possible inclusion in Emacs.
>
> I'm interested in testing it -- I've played with the current version
> of todo-mode.el (included in Emacs trunk), but since you say the UI
> has been largely revamped, I'd like to invest in the new UI.
>
> Can you share the new version somewhere?  I could not find any link.

Thanks for your interest.  I haven't uploaded the code to a public site
yet, because I think this is the appropriate forum, and also the easiest
way for me to make it available is to post it here, but since the size
of the file is ~244k, I don't know if that's acceptable for the mailing
list.  I think it would be if I compressed it, but I'm still waiting for
the go-ahead from the list admin or someone else who knows.

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-10 14:35   ` Stephen Berman
@ 2013-06-10 14:49     ` Bastien
  2013-06-10 20:51       ` New version of todo-mode.el (code) Stephen Berman
  2013-06-10 14:52     ` New version of todo-mode.el (announcement + user guide) Óscar Fuentes
  1 sibling, 1 reply; 37+ messages in thread
From: Bastien @ 2013-06-10 14:49 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel

Stephen Berman <stephen.berman@gmx.net> writes:

> I think it would be if I compressed it, but I'm still waiting for
> the go-ahead from the list admin or someone else who knows.

I suggest you go ahead and send the compressed version on the list.
If this is not acceptable, it will not be accepted and publishing it
elsewhere will be the solution.  But I guess it will be accepted.

Best,

-- 
 Bastien



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-10 14:35   ` Stephen Berman
  2013-06-10 14:49     ` Bastien
@ 2013-06-10 14:52     ` Óscar Fuentes
  2013-06-10 20:52       ` Stephen Berman
  1 sibling, 1 reply; 37+ messages in thread
From: Óscar Fuentes @ 2013-06-10 14:52 UTC (permalink / raw)
  To: emacs-devel; +Cc: Stephen Berman

Stephen Berman <stephen.berman@gmx.net> writes:

> Thanks for your interest.  I haven't uploaded the code to a public site
> yet, because I think this is the appropriate forum, and also the easiest
> way for me to make it available is to post it here, but since the size
> of the file is ~244k, I don't know if that's acceptable for the mailing
> list.  I think it would be if I compressed it, but I'm still waiting for
> the go-ahead from the list admin or someone else who knows.

What about gnu-emacs-sources mailing list?

https://lists.gnu.org/mailman/listinfo/gnu-emacs-sources

Please note that discussions should go to either this mailing list or
help-gnu-emacs.

Also, it takes no time to create an account on Launchpad (if you are a
bzr user) or gitorius/github/whatever (if you are a git user.) Doing so
has several important advantages.




^ permalink raw reply	[flat|nested] 37+ messages in thread

* New version of todo-mode.el (code)
  2013-06-10 14:49     ` Bastien
@ 2013-06-10 20:51       ` Stephen Berman
  2013-08-30 18:31         ` Jambunathan K
  0 siblings, 1 reply; 37+ messages in thread
From: Stephen Berman @ 2013-06-10 20:51 UTC (permalink / raw)
  To: Bastien; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 3616 bytes --]

On Mon, 10 Jun 2013 16:49:14 +0200 Bastien <bzg@gnu.org> wrote:

> Stephen Berman <stephen.berman@gmx.net> writes:
>
>> I think it would be if I compressed it, but I'm still waiting for
>> the go-ahead from the list admin or someone else who knows.
>
> I suggest you go ahead and send the compressed version on the list.
> If this is not acceptable, it will not be accepted and publishing it
> elsewhere will be the solution.  But I guess it will be accepted.

Your argument (plus an unfortunate mistake I just made, which I posted
separately about) convinces me, so here it is (I hope), compressed with
bzip2.  I'm also attaching a patch for diary-lib.el, which is needed if
todo files made using the package are included in the diary file for the
Fancy Diary display.

Steve Berman

*** /home/steve/bzr/emacs/trunk/lisp/calendar/diary-lib.el	2013-06-05 11:41:31.000000000 +0200
--- /home/steve/bzr/emacs/todos/lisp/calendar/diary-lib.el	2013-06-10 22:28:48.000000000 +0200
***************
*** 1040,1063 ****
    "Jump to the diary entry for the BUTTON at point."
    (let* ((locator (button-get button 'locator))
           (marker (car locator))
!          markbuf file)
      ;; If marker pointing to diary location is valid, use that.
      (if (and marker (setq markbuf (marker-buffer marker)))
          (progn
            (pop-to-buffer markbuf)
!           (goto-char (marker-position marker)))
        ;; Marker is invalid (eg buffer has been killed).
        (or (and (setq file (cadr locator))
                 (file-exists-p file)
                 (find-file-other-window file)
                 (progn
                   (when (eq major-mode (default-value 'major-mode)) (diary-mode))
                   (goto-char (point-min))
!                  (if (re-search-forward (format "%s.*\\(%s\\)"
!                                                 (regexp-quote (nth 2 locator))
!                                                 (regexp-quote (nth 3 locator)))
!                                         nil t)
!                      (goto-char (match-beginning 1)))))
            (message "Unable to locate this diary entry")))))
  
  (defun diary-fancy-display ()
--- 1040,1073 ----
    "Jump to the diary entry for the BUTTON at point."
    (let* ((locator (button-get button 'locator))
           (marker (car locator))
!          markbuf file opoint)
!     ;; FIXME: Is there a better way to conditionally require todos.el?
!     (catch 'found
!       (dolist (f diary-included-files)
! 	(when (string-match "\\.todo\\'" f)
! 	  (require 'todos)
! 	  (throw 'found nil))))
      ;; If marker pointing to diary location is valid, use that.
      (if (and marker (setq markbuf (marker-buffer marker)))
          (progn
            (pop-to-buffer markbuf)
! 	  (when (eq major-mode 'todos-mode) (widen))
!           (goto-char (marker-position marker))
! 	  (todos-diary-goto-entry))
        ;; Marker is invalid (eg buffer has been killed).
        (or (and (setq file (cadr locator))
                 (file-exists-p file)
                 (find-file-other-window file)
                 (progn
                   (when (eq major-mode (default-value 'major-mode)) (diary-mode))
+ 		 (when (eq major-mode 'todos-mode) (widen))
                   (goto-char (point-min))
!                  (when (re-search-forward (format "%s.*\\(%s\\)"
! 						  (regexp-quote (nth 2 locator))
! 						  (regexp-quote (nth 3 locator)))
! 					  nil t)
! 		   (goto-char (match-beginning 1))
! 		   (todos-diary-goto-entry))))
            (message "Unable to locate this diary entry")))))
  
  (defun diary-fancy-display ()


[-- Attachment #2: todos.el -- new version of todo-mode.el --]
[-- Type: application/x-bzip2, Size: 46008 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-10 14:52     ` New version of todo-mode.el (announcement + user guide) Óscar Fuentes
@ 2013-06-10 20:52       ` Stephen Berman
  2013-06-11  0:20         ` Stefan Monnier
  0 siblings, 1 reply; 37+ messages in thread
From: Stephen Berman @ 2013-06-10 20:52 UTC (permalink / raw)
  To: Óscar Fuentes; +Cc: emacs-devel

On Mon, 10 Jun 2013 16:52:28 +0200 Óscar Fuentes <ofv@wanadoo.es> wrote:

> The following message is a courtesy copy of an article
> that has been posted to gmane.emacs.devel as well.
>
> Stephen Berman <stephen.berman@gmx.net> writes:
>
>> Thanks for your interest.  I haven't uploaded the code to a public site
>> yet, because I think this is the appropriate forum, and also the easiest
>> way for me to make it available is to post it here, but since the size
>> of the file is ~244k, I don't know if that's acceptable for the mailing
>> list.  I think it would be if I compressed it, but I'm still waiting for
>> the go-ahead from the list admin or someone else who knows.
>
> What about gnu-emacs-sources mailing list?

I assume that mailing list has the same size limit as emacs-devel, but
anyway, as I said in my announcement post, this is not a completely new
package but a new version of an existing Emacs library, so I think
emacs-devel is the appropriate list.

> Also, it takes no time to create an account on Launchpad (if you are a
> bzr user) or gitorius/github/whatever (if you are a git user.) Doing so
> has several important advantages.

I'd consider doing that if the Emacs maintainers decide not to accept
this package, but my hope is that they will accept it and then
development can continue in the trunk, or perhaps, as a fallback, in
ELPA.  So I've gone ahead and posted it here.

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-10 20:52       ` Stephen Berman
@ 2013-06-11  0:20         ` Stefan Monnier
  2013-06-11 18:36           ` Stephen Berman
  0 siblings, 1 reply; 37+ messages in thread
From: Stefan Monnier @ 2013-06-11  0:20 UTC (permalink / raw)
  To: Stephen Berman; +Cc: Óscar Fuentes, emacs-devel

> I'd consider doing that if the Emacs maintainers decide not to accept
> this package, but my hope is that they will accept it and then

I don't see any problem with you switching to this new fancier
todo-mode.el, with the only request that you try to preserve some
compatibility with todo files made with the old mode.


        Stefan



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-11  0:20         ` Stefan Monnier
@ 2013-06-11 18:36           ` Stephen Berman
  2013-06-11 21:48             ` Stefan Monnier
                               ` (2 more replies)
  0 siblings, 3 replies; 37+ messages in thread
From: Stephen Berman @ 2013-06-11 18:36 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

On Mon, 10 Jun 2013 20:20:18 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote:

>> I'd consider doing that if the Emacs maintainers decide not to accept
>> this package, but my hope is that they will accept it and then
>
> I don't see any problem with you switching to this new fancier
> todo-mode.el, with the only request that you try to preserve some
> compatibility with todo files made with the old mode.

Thank you for the vote of confidence.  Regarding compatibility, as
explained in the last section of the user guide I posted, the way the
new and old todo file formats treat the item date header makes them
practically incompatible.  However, I've provided a command which
converts a copy of an old-style todo file into new-style one and a copy
of an old-style `todo-file-done' file into a new-style todo archive
file.  I've tested this with the default value of the date/time header
string used by the old version, and it should also work with custom
values that satisfy certain conditions, but this would need more testing
and it's not unlikely that some manual post-editing would be necessary.
I hope this is an acceptable approach.  If so, then I have a number of
questions about how to proceed:

- The first thing to decide is where and under what name to install the
  new version.  Should I simply replace the old version?  This would
  essentially force users of the old version to convert to and learn to
  use the new version.  In principle, that should not be a problem, but
  since I'm the only one who's used the new version so far, there are
  certain to be use cases and configurations I didn't test well enough
  or even think of at all, so there could well be a period of
  instability for these users.
- Alternatively, I could install the new version alongside the old
  version.  In fact, the code I posted is ready for this, since the file
  is called todos.el and it uses the prefix "todos-", so it can be
  loaded without interfering with the old version.  This would allow
  people to test the new version while still being able to use the old
  version.  The disadvantage of this is inertia: since people wouldn't
  have to use the new version, it may get less testing.
- A third alternative is to install the new version as posted with the
  new name and prefix in place of the old version and move that to
  lisp/obsolete/, so people could still use it but would have more
  incentive to use the new version.

- Although I eliminated, changed or reimplemented almost all the code in
  the old version, there are bits here and there that I've retained, as
  well as the basic concepts and UI of handling todo lists.  So should
  the original author, Oliver Seidel, still be listed as an author, or
  is it sufficient to acknowledge him in the commentary (as I do in the
  code I posted)?

- If Glenn Morris approves, can I install the patch I included for
  diary-lib.el?  Without this, if a todo file is included in the Emacs
  diary, then when a todo item appears as an entry in the Fancy Diary
  display and you click on it, you may not jump to the right item in the
  todo file.  It's not a showstopper, but should be supported for proper
  integration with the diary.  But maybe there's a better way of getting
  the right behavior than this patch.  (BTW, I think this issue already
  exists for the current version of todo-mode.el.)

- The code makes use of a powerset function, which Emacs doesn't have.
  I tried but couldn't come up with my own algorithm but found a
  recursive Common Lisp implementation and an iterative one in C on a
  website whose content is licensed under the GFDL.  I reimplemented the
  latter in Elisp, so at least the code is not literally copied.  Is
  this a cause for concern with respect to copyright assignment?

- I've tried to follow the Emacs coding conventions and used checkdoc,
  but one of the things I'm uncertain about is the new "<prefix>--"
  convention.  Since this is not a general-purpose library, basically
  every function and variable in it is not meant for use by other
  packages.  On the other hand, some clearly internal functions, such as
  the powerset function, could be used by other packages, but more
  likely they would be redefined using the package prefix.  So for the
  time being I haven't applied this convention but I'd be happy to do so
  in specific cases, or if the guidelines for using it can be spelled
  out more precisely.

- I also have a question about documentation.  The user guide I posted
  is certainly too long and detailed for the commentary section of the
  source code, and I guess also for the Emacs manual.  Should I try to
  destill it down to a reasonable manual entry, added to the diary
  chapter?  If so, I'd be grateful for suggestions about what to omit or
  how to make it otherwise suitable.  Alternatively, if it is deemed
  worthwhile including all the information, it could be added as
  separate manual.

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-11 18:36           ` Stephen Berman
@ 2013-06-11 21:48             ` Stefan Monnier
  2013-06-12 21:37               ` Stephen Berman
  2013-06-12 17:28             ` Glenn Morris
  2013-06-12 18:30             ` Wolfgang Jenkner
  2 siblings, 1 reply; 37+ messages in thread
From: Stefan Monnier @ 2013-06-11 21:48 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel

> Thank you for the vote of confidence.  Regarding compatibility, as
> explained in the last section of the user guide I posted, the way the
> new and old todo file formats treat the item date header makes them
> practically incompatible.

Too bad, but not surprising.

> However, I've provided a command which converts a copy of an old-style
> todo file into new-style one and a copy of an old-style
> `todo-file-done' file into a new-style todo archive file.

That's not sufficient for people who use the same TODO file on various
machines whereas those machines don't all have the same Emacs version
(hence some will have the old todo-mode and others will have the new one).

> - A third alternative is to install the new version as posted with the
>   new name and prefix in place of the old version and move that to
>   lisp/obsolete/, so people could still use it but would have more
>   incentive to use the new version.

That sounds like the better solution.  Even better if the old and the
new code can be both in use at the same time (e.g. if you have
converted some of your todo files but not all).

> - Although I eliminated, changed or reimplemented almost all the code in
>   the old version, there are bits here and there that I've retained, as
>   well as the basic concepts and UI of handling todo lists.  So should
>   the original author, Oliver Seidel, still be listed as an author, or
>   is it sufficient to acknowledge him in the commentary (as I do in the
>   code I posted)?

I don't see why we shouldn't keep him in the list of authors.

> - If Glenn Morris approves, can I install the patch I included for
>   diary-lib.el?

I'm OK with whatever he agrees with in this respect.

> - The code makes use of a powerset function, which Emacs doesn't have.
>   I tried but couldn't come up with my own algorithm but found a
>   recursive Common Lisp implementation and an iterative one in C on a
>   website whose content is licensed under the GFDL.  I reimplemented the
>   latter in Elisp, so at least the code is not literally copied.  Is
>   this a cause for concern with respect to copyright assignment?

It sounds borderline.

> - I've tried to follow the Emacs coding conventions and used checkdoc,
>   but one of the things I'm uncertain about is the new "<prefix>--"

Lots of packages don't follow this convention.  It's not a problem.

> - I also have a question about documentation.  The user guide I posted
>   is certainly too long and detailed for the commentary section of the
>   source code, and I guess also for the Emacs manual.  Should I try to
>   destill it down to a reasonable manual entry, added to the diary
>   chapter?  If so, I'd be grateful for suggestions about what to omit or
>   how to make it otherwise suitable.  Alternatively, if it is deemed
>   worthwhile including all the information, it could be added as
>   separate manual.

Either way is fine by me, but a separate todo-mode Texinfo manual sounds
perfectly acceptable.


        Stefan



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-11 18:36           ` Stephen Berman
  2013-06-11 21:48             ` Stefan Monnier
@ 2013-06-12 17:28             ` Glenn Morris
  2013-06-12 21:26               ` Stefan Monnier
  2013-06-12 21:37               ` Stephen Berman
  2013-06-12 18:30             ` Wolfgang Jenkner
  2 siblings, 2 replies; 37+ messages in thread
From: Glenn Morris @ 2013-06-12 17:28 UTC (permalink / raw)
  To: Stephen Berman; +Cc: Stefan Monnier, emacs-devel

Stephen Berman wrote:

> - If Glenn Morris approves, can I install the patch I included for
>   diary-lib.el?

Fine by me, though if possible I think it would be better to add some
new diary hooks(s) so that you can do whatever it is you want to do
without needing to put todo-specific stuff in diary-lib. But feel free.

> - I also have a question about documentation.  The user guide I posted
>   is certainly too long and detailed for the commentary section of the
>   source code, and I guess also for the Emacs manual.

It is longer than the entire current todo-mode.el is...

(244k will make it about the 15th largest Lisp file in Emacs.
I doubt anyone has time to review that in detail.)



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-11 18:36           ` Stephen Berman
  2013-06-11 21:48             ` Stefan Monnier
  2013-06-12 17:28             ` Glenn Morris
@ 2013-06-12 18:30             ` Wolfgang Jenkner
  2013-06-12 21:38               ` Stephen Berman
  2 siblings, 1 reply; 37+ messages in thread
From: Wolfgang Jenkner @ 2013-06-12 18:30 UTC (permalink / raw)
  To: Stephen Berman; +Cc: Stefan Monnier, emacs-devel

On Tue, Jun 11 2013, Stephen Berman wrote:

> - The code makes use of a powerset function, which Emacs doesn't have.
>   I tried but couldn't come up with my own algorithm but found a
>   recursive Common Lisp implementation and an iterative one in C

The straightforward recursive implementation can be rewritten as an
iterative one by conceptually doing left- instead of right-folding.

(defun my-powerset (list)
  "Return the powerset of LIST."
  (let ((powerset (list nil)))
    (dolist (elt list (mapcar 'reverse powerset))
      (nconc powerset (mapcar (apply-partially 'cons elt) powerset)))))

Here are some other (more or less serious) variations on the theme:

https://groups.google.com/forum/?fromgroups#!topic/comp.lang.lisp/gxWw9x3TvAI

Wolfgang



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-12 17:28             ` Glenn Morris
@ 2013-06-12 21:26               ` Stefan Monnier
  2013-06-12 21:37               ` Stephen Berman
  1 sibling, 0 replies; 37+ messages in thread
From: Stefan Monnier @ 2013-06-12 21:26 UTC (permalink / raw)
  To: Glenn Morris; +Cc: Stephen Berman, emacs-devel

>> - If Glenn Morris approves, can I install the patch I included for
>> diary-lib.el?
> Fine by me, though if possible I think it would be better to add some
> new diary hooks(s) so that you can do whatever it is you want to do
> without needing to put todo-specific stuff in diary-lib.

I strongly second this.


        Stefan



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-11 21:48             ` Stefan Monnier
@ 2013-06-12 21:37               ` Stephen Berman
  2013-06-13  1:06                 ` Stefan Monnier
  0 siblings, 1 reply; 37+ messages in thread
From: Stephen Berman @ 2013-06-12 21:37 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

On Tue, 11 Jun 2013 17:48:34 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote:

>> Thank you for the vote of confidence.  Regarding compatibility, as
>> explained in the last section of the user guide I posted, the way the
>> new and old todo file formats treat the item date header makes them
>> practically incompatible.
>
> Too bad, but not surprising.
>
>> However, I've provided a command which converts a copy of an old-style
>> todo file into new-style one and a copy of an old-style
>> `todo-file-done' file into a new-style todo archive file.
>
> That's not sufficient for people who use the same TODO file on various
> machines whereas those machines don't all have the same Emacs version
> (hence some will have the old todo-mode and others will have the new one).

I was kind of hoping todo-mode users would be so wowed by the new
version that they'd convert their old files and not look back... but I
didn't consider the use-case you mention.  I'll try to write a command
that converts from the new to the old format, but this may not be so
straightforward, because the new format has structure at all three
organizational levels (item, category, and file) for which there's no
correspondence in the old format.  (Likewise, there's nothing in the new
format corresponding to use of todo-prefix in the old format, but I
consider that difference to be one of the main advantages of the new
version.  In fact, I think the way the old version interacts with the
Emacs diary is rather buggy, at least for my usage, and the fact that
there have been no bug reports about that leads me to believe that few
if any todo-mode users include the todo file in the diary -- or they
have a very different pattern of use from mine (which is what lead to me
work on the new version).)

>> - A third alternative is to install the new version as posted with the
>>   new name and prefix in place of the old version and move that to
>>   lisp/obsolete/, so people could still use it but would have more
>>   incentive to use the new version.
>
> That sounds like the better solution.  Even better if the old and the
> new code can be both in use at the same time (e.g. if you have
> converted some of your todo files but not all).

I want to be sure what you're saying here: are you saying there's
something better than making the old version obsolete?  Or are you
saying it is ok to make it obsolete?  (Your parenthetical example is a
bit confusing, because the old version only supports using one todo file
at a time.  I guess you could have several todos files, but to switch
between them you'd have to unload todo-mode.el, change the value of
todo-file-do and reload the package.  The fact that you can
simultaneously use multiple todo files is another big advantage of the
new version -- and probably also the main stumbling block in converting
from the new to the old format.)

>> - Although I eliminated, changed or reimplemented almost all the code in
>>   the old version, there are bits here and there that I've retained, as
>>   well as the basic concepts and UI of handling todo lists.  So should
>>   the original author, Oliver Seidel, still be listed as an author, or
>>   is it sufficient to acknowledge him in the commentary (as I do in the
>>   code I posted)?
>
> I don't see why we shouldn't keep him in the list of authors.

Ok.

>> - If Glenn Morris approves, can I install the patch I included for
>>   diary-lib.el?
>
> I'm OK with whatever he agrees with in this respect.

I agree with him that a hook would be better, but if I can't figure out
how to do it that way, I'll probably use the patch as a fallback.  (I
just saw your response to Glenn as I was about to post this; see my
response to him about the problems I see with adding a hook, though that
could well just be my lack of insight.)

>> - The code makes use of a powerset function, which Emacs doesn't have.
>>   I tried but couldn't come up with my own algorithm but found a
>>   recursive Common Lisp implementation and an iterative one in C on a
>>   website whose content is licensed under the GFDL.  I reimplemented the
>>   latter in Elisp, so at least the code is not literally copied.  Is
>>   this a cause for concern with respect to copyright assignment?
>
> It sounds borderline.

That's a bit intimidating.  Maybe the code Wolfgang Jenkner posted in
this thread could be used instead -- even better if it were just added
to Emacs.  Juri Linkov also posted one a little while ago, which was
actually essentially the same as the Common Lisp recursive definition.
Is this really subject to copyright?

>> - I've tried to follow the Emacs coding conventions and used checkdoc,
>>   but one of the things I'm uncertain about is the new "<prefix>--"
>
> Lots of packages don't follow this convention.  It's not a problem.

Ok.

>> - I also have a question about documentation.  The user guide I posted
>>   is certainly too long and detailed for the commentary section of the
>>   source code, and I guess also for the Emacs manual.  Should I try to
>>   destill it down to a reasonable manual entry, added to the diary
>>   chapter?  If so, I'd be grateful for suggestions about what to omit or
>>   how to make it otherwise suitable.  Alternatively, if it is deemed
>>   worthwhile including all the information, it could be added as
>>   separate manual.
>
> Either way is fine by me, but a separate todo-mode Texinfo manual sounds
> perfectly acceptable.

I'll probably do that then, since it should be easier than trying to
pare it down.

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-12 17:28             ` Glenn Morris
  2013-06-12 21:26               ` Stefan Monnier
@ 2013-06-12 21:37               ` Stephen Berman
  2013-06-13  1:18                 ` Stefan Monnier
  1 sibling, 1 reply; 37+ messages in thread
From: Stephen Berman @ 2013-06-12 21:37 UTC (permalink / raw)
  To: Glenn Morris; +Cc: Stefan Monnier, emacs-devel

On Wed, 12 Jun 2013 13:28:35 -0400 Glenn Morris <rgm@gnu.org> wrote:

> Stephen Berman wrote:
>
>> - If Glenn Morris approves, can I install the patch I included for
>>   diary-lib.el?
>
> Fine by me, though if possible I think it would be better to add some
> new diary hooks(s) so that you can do whatever it is you want to do
> without needing to put todo-specific stuff in diary-lib. But feel free.

Thanks for the go-ahead.  I do agree with you that a hook would be
better and in fact gave it some thought, but couldn't see how to do it
using an existing hook.  I didn't consider adding a new hook, and I'm
not sure I what that should be.  The problem is, after the button is
clicked in the Fancy Diary display, if the todo file is in a buffer, it
will probably be narrowed, so it has to be widened before going to the
position of the marker, and then it has to be narrowed again afterwards
to get the proper display.  So either there have to be two hooks
sandwiching the goto-char for the marker, or the latter has to be passed
to the hook function.  Neither really seems much better than the ad hoc
patch I posted, but it's not unlikely I'm overlooking a better
alternative.  If you have any ideas, I'm all ears.

>> - I also have a question about documentation.  The user guide I posted
>>   is certainly too long and detailed for the commentary section of the
>>   source code, and I guess also for the Emacs manual.
>
> It is longer than the entire current todo-mode.el is...

Yes, but then the new version is nearly seven times longer than the old
one.  Still, I'd welcome suggestions for slimming down the
documentation.  Maybe when others use the package some of the features
will be found to be dispensible.

> (244k will make it about the 15th largest Lisp file in Emacs.
> I doubt anyone has time to review that in detail.)

I don't expect that (though I'd welcome any feedback).  The package has
had an excessively long genesis (I'm not a fast coder) and I was
probably strategically unwise not to post earlier, less featureful,
versions.

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-12 18:30             ` Wolfgang Jenkner
@ 2013-06-12 21:38               ` Stephen Berman
  2013-06-13  1:24                 ` Wolfgang Jenkner
  0 siblings, 1 reply; 37+ messages in thread
From: Stephen Berman @ 2013-06-12 21:38 UTC (permalink / raw)
  To: emacs-devel; +Cc: Stefan Monnier

On Wed, 12 Jun 2013 20:30:45 +0200 Wolfgang Jenkner <wjenkner@inode.at> wrote:

> On Tue, Jun 11 2013, Stephen Berman wrote:
>
>> - The code makes use of a powerset function, which Emacs doesn't have.
>>   I tried but couldn't come up with my own algorithm but found a
>>   recursive Common Lisp implementation and an iterative one in C
>
> The straightforward recursive implementation can be rewritten as an
> iterative one by conceptually doing left- instead of right-folding.
>
> (defun my-powerset (list)
>   "Return the powerset of LIST."
>   (let ((powerset (list nil)))
>     (dolist (elt list (mapcar 'reverse powerset))
>       (nconc powerset (mapcar (apply-partially 'cons elt) powerset)))))

This is nice.  Maybe you could get it added to Emacs and then I could
just invoke it.  Or if the mainainers don't want a powerset function,
would you be willing to contribute it to my package, if the ones I used
aren't usable for copyright reasons?

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-12 21:37               ` Stephen Berman
@ 2013-06-13  1:06                 ` Stefan Monnier
  2013-06-13 20:53                   ` Stephen Berman
  0 siblings, 1 reply; 37+ messages in thread
From: Stefan Monnier @ 2013-06-13  1:06 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel

> didn't consider the use-case you mention.  I'll try to write a command
> that converts from the new to the old format, but this may not be so

Don't bother.  A conversion forward is important, but a conversion
backward much less so.  Instead it's important to be able to use the
old-style format in newer Emacsen.

>> That sounds like the better solution.  Even better if the old and the
>> new code can be both in use at the same time (e.g. if you have
>> converted some of your todo files but not all).
> I want to be sure what you're saying here: are you saying there's
> something better than making the old version obsolete?  Or are you
> saying it is ok to make it obsolete?

Making it obsolete is fine.

> (Your parenthetical example is a bit confusing, because the old
> version only supports using one todo file at a time.  I guess you
> could have several todos files, but to switch between them you'd have
> to unload todo-mode.el, change the value of todo-file-do and reload
> the package.  The fact that you can simultaneously use multiple todo
> files is another big advantage of the new version -- and probably also
> the main stumbling block in converting from the new to the
> old format.)

I was thinking of the case where the user wants to transition
progressively, so she keeps her old-style todo file but also starts to
use a new-style todo file.
But maybe it's not important to support this use case.

>> It sounds borderline.
> That's a bit intimidating.  Maybe the code Wolfgang Jenkner posted in
> this thread could be used instead -- even better if it were just added
> to Emacs.  Juri Linkov also posted one a little while ago, which was
> actually essentially the same as the Common Lisp recursive definition.
> Is this really subject to copyright?

No, it sounds fine, thank you.  They're all sufficiently trivial.


        Stefan



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-12 21:37               ` Stephen Berman
@ 2013-06-13  1:18                 ` Stefan Monnier
  2013-06-13 20:53                   ` Stephen Berman
  0 siblings, 1 reply; 37+ messages in thread
From: Stefan Monnier @ 2013-06-13  1:18 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel

> Thanks for the go-ahead.  I do agree with you that a hook would be
> better and in fact gave it some thought, but couldn't see how to do it
> using an existing hook.  I didn't consider adding a new hook, and I'm
> not sure I what that should be.  The problem is, after the button is
> clicked in the Fancy Diary display, if the todo file is in a buffer, it
> will probably be narrowed, so it has to be widened before going to the
> position of the marker, and then it has to be narrowed again afterwards
> to get the proper display.  So either there have to be two hooks
> sandwiching the goto-char for the marker, or the latter has to be passed
> to the hook function.  Neither really seems much better than the ad hoc
> patch I posted, but it's not unlikely I'm overlooking a better
> alternative.  If you have any ideas, I'm all ears.

I think a way to do this is with a diary-goto-marker-function hook.
The default value could be `goto-char'.  And your todo-mode can change
it via something like:

    (add-function :around diary-goto-marker-function
                  (lambda (orig-fun &rest args)
                    (when (derived-mode-p 'todo-mode) (widen))
                    (apply orig-fun args)
                    (todos-diary-goto-entry)))

-- Stefan



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-12 21:38               ` Stephen Berman
@ 2013-06-13  1:24                 ` Wolfgang Jenkner
  2013-06-13 20:54                   ` Stephen Berman
  0 siblings, 1 reply; 37+ messages in thread
From: Wolfgang Jenkner @ 2013-06-13  1:24 UTC (permalink / raw)
  To: Stephen Berman; +Cc: Stefan Monnier, emacs-devel

On Wed, Jun 12 2013, Stephen Berman wrote:

> would you be willing to contribute it to my package, if the ones I used
> aren't usable for copyright reasons?

Sure (there are also some differences in performance).

Wolfgang



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-09 23:31 New version of todo-mode.el (announcement + user guide) Stephen Berman
  2013-06-10 13:24 ` Bastien
@ 2013-06-13 10:59 ` Vitalie Spinu
  2013-06-13 20:54   ` Stephen Berman
  2013-08-31  3:55 ` Jambunathan K
  2 siblings, 1 reply; 37+ messages in thread
From: Vitalie Spinu @ 2013-06-13 10:59 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel

 >> Stephen Berman <stephen.berman@gmx.net>
 >> on Mon, 10 Jun 2013 01:31:09 +0200 wrote:

 > I've written a new version of todo-mode.el, which I'd like to submit for
 > possible inclusion in Emacs.  

I am a bit confused. I have never used todo-mode and my naive impression
was that most people are using org-mode for todos nowadays.

What can todo-mode do that org-mode cannot?

If their functionality is similar, then why to spend the effort on two
separate projects that are both part of emacs?

    Vitalie




^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-13  1:06                 ` Stefan Monnier
@ 2013-06-13 20:53                   ` Stephen Berman
  0 siblings, 0 replies; 37+ messages in thread
From: Stephen Berman @ 2013-06-13 20:53 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

On Wed, 12 Jun 2013 21:06:57 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote:

>> didn't consider the use-case you mention.  I'll try to write a command
>> that converts from the new to the old format, but this may not be so
>
> Don't bother.  A conversion forward is important, but a conversion
> backward much less so.  Instead it's important to be able to use the
> old-style format in newer Emacsen.
>
>>> That sounds like the better solution.  Even better if the old and the
>>> new code can be both in use at the same time (e.g. if you have
>>> converted some of your todo files but not all).
>> I want to be sure what you're saying here: are you saying there's
>> something better than making the old version obsolete?  Or are you
>> saying it is ok to make it obsolete?
>
> Making it obsolete is fine.
>
>> (Your parenthetical example is a bit confusing, because the old
>> version only supports using one todo file at a time.  I guess you
>> could have several todos files, but to switch between them you'd have
>> to unload todo-mode.el, change the value of todo-file-do and reload
>> the package.  The fact that you can simultaneously use multiple todo
>> files is another big advantage of the new version -- and probably also
>> the main stumbling block in converting from the new to the
>> old format.)
>
> I was thinking of the case where the user wants to transition
> progressively, so she keeps her old-style todo file but also starts to
> use a new-style todo file.
> But maybe it's not important to support this use case.
>
>>> It sounds borderline.
>> That's a bit intimidating.  Maybe the code Wolfgang Jenkner posted in
>> this thread could be used instead -- even better if it were just added
>> to Emacs.  Juri Linkov also posted one a little while ago, which was
>> actually essentially the same as the Common Lisp recursive definition.
>> Is this really subject to copyright?
>
> No, it sounds fine, thank you.  They're all sufficiently trivial.

Ok, thanks for the clarifications.  As soon as the diary-lib issue is
resolved, I'll move on to installing the new version.

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-13  1:18                 ` Stefan Monnier
@ 2013-06-13 20:53                   ` Stephen Berman
  2013-06-14  0:21                     ` Stefan Monnier
  0 siblings, 1 reply; 37+ messages in thread
From: Stephen Berman @ 2013-06-13 20:53 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

On Wed, 12 Jun 2013 21:18:29 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote:

>> Thanks for the go-ahead.  I do agree with you that a hook would be
>> better and in fact gave it some thought, but couldn't see how to do it
>> using an existing hook.  I didn't consider adding a new hook, and I'm
>> not sure I what that should be.  The problem is, after the button is
>> clicked in the Fancy Diary display, if the todo file is in a buffer, it
>> will probably be narrowed, so it has to be widened before going to the
>> position of the marker, and then it has to be narrowed again afterwards
>> to get the proper display.  So either there have to be two hooks
>> sandwiching the goto-char for the marker, or the latter has to be passed
>> to the hook function.  Neither really seems much better than the ad hoc
>> patch I posted, but it's not unlikely I'm overlooking a better
>> alternative.  If you have any ideas, I'm all ears.
>
> I think a way to do this is with a diary-goto-marker-function hook.
> The default value could be `goto-char'.  And your todo-mode can change
> it via something like:
>
>     (add-function :around diary-goto-marker-function
>                   (lambda (orig-fun &rest args)
>                     (when (derived-mode-p 'todo-mode) (widen))
>                     (apply orig-fun args)
>                     (todos-diary-goto-entry)))

Thank you for this excellent "advice" ;-).  It works very nicely --
except for one wrinkle: after loading todos.el (which requires
'diary-lib) I have to eval diary-goto-entry (or load diary-lib) again in
order for the advice to take effect.  Without doing that it's as if the
advice were not activated.  But I see nothing about activating advice in
nadvice.el.  Here's what I added to diary-lib.el:

(defvar diary-goto-location-function 'goto-char
  "Function called by `diary-goto-entry' to jump to a diary entry.
Major modes that require special handling of the source file of
the diary entry can assign a suitable function to this variable.")

(defun diary-goto-entry (button)
  "Jump to the diary entry for the BUTTON at point."
  (let* ((locator (button-get button 'locator))
         (marker (car locator))
         markbuf file)
    ;; If marker pointing to diary location is valid, use that.
    (if (and marker (setq markbuf (marker-buffer marker)))
        (progn
          (pop-to-buffer markbuf)
	  (funcall diary-goto-location-function (marker-position marker)))
      ;; Marker is invalid (eg buffer has been killed).
      (or (and (setq file (cadr locator))
               (file-exists-p file)
               (find-file-other-window file)
               (progn
                 (when (eq major-mode (default-value 'major-mode)) (diary-mode))
                 (goto-char (point-min))
                 (if (re-search-forward (format "%s.*\\(%s\\)"
                                                (regexp-quote (nth 2 locator))
                                                (regexp-quote (nth 3 locator)))
                                        nil t)
                     (funcall diary-goto-location-function (match-beginning 1)))))
          (message "Unable to locate this diary entry")))))

and here's what I added to todos-mode:

(define-derived-mode todos-mode special-mode "Todos"
  "Major mode for displaying, navigating and editing Todo lists.

\\{todos-mode-map}"
;; other initializations ...
  (add-function :around diary-goto-location-function
		(lambda (orig-fun &rest args)
		  (when (derived-mode-p 'todos-mode) (widen))
		  (apply orig-fun args)
		  (todos-diary-goto-entry))))

What am I doing wrong?

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-13  1:24                 ` Wolfgang Jenkner
@ 2013-06-13 20:54                   ` Stephen Berman
  0 siblings, 0 replies; 37+ messages in thread
From: Stephen Berman @ 2013-06-13 20:54 UTC (permalink / raw)
  To: emacs-devel; +Cc: Stefan Monnier

On Thu, 13 Jun 2013 03:24:07 +0200 Wolfgang Jenkner <wjenkner@inode.at> wrote:

> On Wed, Jun 12 2013, Stephen Berman wrote:
>
>> would you be willing to contribute it to my package, if the ones I used
>> aren't usable for copyright reasons?
>
> Sure (there are also some differences in performance).

Thanks!

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-13 10:59 ` Vitalie Spinu
@ 2013-06-13 20:54   ` Stephen Berman
  0 siblings, 0 replies; 37+ messages in thread
From: Stephen Berman @ 2013-06-13 20:54 UTC (permalink / raw)
  To: Vitalie Spinu; +Cc: emacs-devel

On Thu, 13 Jun 2013 12:59:36 +0200 Vitalie Spinu <spinuvit@gmail.com> wrote:

>  >> Stephen Berman <stephen.berman@gmx.net>
>  >> on Mon, 10 Jun 2013 01:31:09 +0200 wrote:
>
>  > I've written a new version of todo-mode.el, which I'd like to submit for
>  > possible inclusion in Emacs.  
>
> I am a bit confused. I have never used todo-mode and my naive impression
> was that most people are using org-mode for todos nowadays.

I share that impression.

> What can todo-mode do that org-mode cannot?

I can't compare them because I'm too unfamiliar with Org.  I briefly
looked at it when it first appeared but preferred Todo mode's UI to
Org's, and I was already involved with adding features to Todo mode to
suit my needs, so I didn't pursue Org further.

> If their functionality is similar, then why to spend the effort on two
> separate projects that are both part of emacs?

I've only spent time and effort on Todo mode.  Maybe there are some
other people who use the old version and will find the new one useful,
and perhaps others will too.  There are lots of application domains for
which Emacs has more than one package.

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-13 20:53                   ` Stephen Berman
@ 2013-06-14  0:21                     ` Stefan Monnier
  2013-06-14 21:37                       ` Stephen Berman
  0 siblings, 1 reply; 37+ messages in thread
From: Stefan Monnier @ 2013-06-14  0:21 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel

> Thank you for this excellent "advice" ;-).  It works very nicely --
> except for one wrinkle: after loading todos.el (which requires
> 'diary-lib) I have to eval diary-goto-entry (or load diary-lib) again in
> order for the advice to take effect.  Without doing that it's as if the
> advice were not activated.  But I see nothing about activating advice in
> nadvice.el.  Here's what I added to diary-lib.el:

Contrary to advice, which has all kinds of subtle distinction between
defining an advice, enabling an advice, and activating an advice,
nadvice just has add-function (or advice-add) which
works more like add-hook (i.e. kind of defines/enables/activates all at
once).

> (define-derived-mode todos-mode special-mode "Todos"
>   "Major mode for displaying, navigating and editing Todo lists.

> \\{todos-mode-map}"
> ;; other initializations ...
>   (add-function :around diary-goto-location-function
> 		(lambda (orig-fun &rest args)
> 		  (when (derived-mode-p 'todos-mode) (widen))
> 		  (apply orig-fun args)
> 		  (todos-diary-goto-entry))))

This doesn't make sense: you `add-function' to the global value of
diary-goto-location-function, but you do it in the mode function,
i.e. once per todo-mode buffer.

Either do it locally (i.e. in the todo-mode function but with

   (add-function :around (local diary-goto-location-function)
 		(lambda (orig-fun &rest args)
 		  (widen)
 		  (apply orig-fun args)
 		  (todos-diary-goto-entry)))

Or do it globally, (i.e. at the top-level of todo-mode.el).


        Stefan



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-14  0:21                     ` Stefan Monnier
@ 2013-06-14 21:37                       ` Stephen Berman
  2013-06-15  0:40                         ` Glenn Morris
  2013-06-15  1:49                         ` Stefan Monnier
  0 siblings, 2 replies; 37+ messages in thread
From: Stephen Berman @ 2013-06-14 21:37 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

On Thu, 13 Jun 2013 20:21:01 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote:

>> Thank you for this excellent "advice" ;-).  It works very nicely --
>> except for one wrinkle: after loading todos.el (which requires
>> 'diary-lib) I have to eval diary-goto-entry (or load diary-lib) again in
>> order for the advice to take effect.  Without doing that it's as if the
>> advice were not activated.  But I see nothing about activating advice in
>> nadvice.el.  Here's what I added to diary-lib.el:
>
> Contrary to advice, which has all kinds of subtle distinction between
> defining an advice, enabling an advice, and activating an advice,
> nadvice just has add-function (or advice-add) which
> works more like add-hook (i.e. kind of defines/enables/activates all at
> once).

Ah, ok, thanks for clarifying.

>> (define-derived-mode todos-mode special-mode "Todos"
>>   "Major mode for displaying, navigating and editing Todo lists.
>
>> \\{todos-mode-map}"
>> ;; other initializations ...
>>   (add-function :around diary-goto-location-function
>> 		(lambda (orig-fun &rest args)
>> 		  (when (derived-mode-p 'todos-mode) (widen))
>> 		  (apply orig-fun args)
>> 		  (todos-diary-goto-entry))))
>
> This doesn't make sense: you `add-function' to the global value of
> diary-goto-location-function, but you do it in the mode function,
> i.e. once per todo-mode buffer.
>
> Either do it locally (i.e. in the todo-mode function but with
>
>    (add-function :around (local diary-goto-location-function)
>  		(lambda (orig-fun &rest args)
>  		  (widen)
>  		  (apply orig-fun args)
>  		  (todos-diary-goto-entry)))
>
> Or do it globally, (i.e. at the top-level of todo-mode.el).

Thanks.  Doing it locally still doesn't work, I guess because the
function is called from the Fancy Diary buffer, not from Todos mode.
But it works when it's added at top-level.  Moreover, it turns out that
using :around isn't right, at least not without making it much more
complicated AFAICT.  It's much more straightforward to use :override.
So I'd like to make the following change to diary-lib.el:


*** /data/steve/bzr/emacs/trunk/lisp/calendar/diary-lib.el	2013-06-05 11:41:31.000000000 +0200
--- /data/steve/bzr/emacs/quickfixes/lisp/calendar/diary-lib.el	2013-06-14 23:34:12.000000000 +0200
***************
*** 1032,1038 ****
  (define-obsolete-function-alias 'simple-diary-display
    'diary-simple-display "23.1")
  
! (define-button-type 'diary-entry 'action #'diary-goto-entry
    'face 'diary-button 'help-echo "Find this diary entry"
    'follow-link t)
  
--- 1032,1045 ----
  (define-obsolete-function-alias 'simple-diary-display
    'diary-simple-display "23.1")
  
! (defvar diary-goto-entry-function 'diary-goto-entry
!   "Function called to jump to a diary entry.
! Modes that require special handling of the included file
! containing the diary entry can assign a suitable function to this
! variable.")
! 
! (define-button-type 'diary-entry
!   'action (lambda (button) (funcall diary-goto-entry-function button))
    'face 'diary-button 'help-echo "Find this diary entry"
    'follow-link t)

  
Any objections?

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-14 21:37                       ` Stephen Berman
@ 2013-06-15  0:40                         ` Glenn Morris
  2013-06-15  1:49                         ` Stefan Monnier
  1 sibling, 0 replies; 37+ messages in thread
From: Glenn Morris @ 2013-06-15  0:40 UTC (permalink / raw)
  To: Stephen Berman; +Cc: Stefan Monnier, emacs-devel


Fine by me.



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-14 21:37                       ` Stephen Berman
  2013-06-15  0:40                         ` Glenn Morris
@ 2013-06-15  1:49                         ` Stefan Monnier
  2013-06-15 12:52                           ` Stephen Berman
  1 sibling, 1 reply; 37+ messages in thread
From: Stefan Monnier @ 2013-06-15  1:49 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel

> But it works when it's added at top-level.  Moreover, it turns out that
> using :around isn't right, at least not without making it much more
> complicated AFAICT.  It's much more straightforward to use :override.

I don't see why, but it doesn't matter.

> ! (defvar diary-goto-entry-function 'diary-goto-entry
> !   "Function called to jump to a diary entry.
> ! Modes that require special handling of the included file
> ! containing the diary entry can assign a suitable function to this
> ! variable.")
> ! 
> ! (define-button-type 'diary-entry
> !   'action (lambda (button) (funcall diary-goto-entry-function button))

Fine by me,


        Stefan



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-15  1:49                         ` Stefan Monnier
@ 2013-06-15 12:52                           ` Stephen Berman
  2013-06-16  0:44                             ` Stefan Monnier
  0 siblings, 1 reply; 37+ messages in thread
From: Stephen Berman @ 2013-06-15 12:52 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

On Fri, 14 Jun 2013 21:49:35 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote:

>> But it works when it's added at top-level.  Moreover, it turns out that
>> using :around isn't right, at least not without making it much more
>> complicated AFAICT.  It's much more straightforward to use :override.
>
> I don't see why, but it doesn't matter.

I'll try explaining anyway, since if you see a way to do it that I'm
overlooking, I'd like to know.  There are two situations that
diary-goto-entry handles (which entails two calls of the modified
function): where a valid marker points to the diary entry location, and
where there is no such marker.  When the entry comes from a todo file in
a live buffer, narrowing is in effect, so before finding the location,
the buffer has to be widened, and then afterwards narrowed again, to
restore the proper display.  But what happens between widening and
re-narrowing is different in the two situations (indicated below by the
arrows pointing to the code executed by the :around advice) and I see no
straightforward way to cover them both with a single :around advice.
(Note that widening just before the third goto-char, which would allow
the simple :around advice you suggested, is too late.)

(defun diary-goto-entry (button)
  "Jump to the diary entry for the BUTTON at point."
  (let* ((locator (button-get button 'locator))
         (marker (car locator))
         markbuf file opoint)
    ;; If marker pointing to diary location is valid, use that.
    (if (and marker (setq markbuf (marker-buffer marker)))
        (progn
          (pop-to-buffer markbuf)
1a=>	  (when (eq major-mode 'todos-mode) (widen))
          (goto-char (marker-position marker))
1b=>	  (todos-diary-goto-entry))
      ;; Marker is invalid (eg buffer has been killed).
      (or (and (setq file (cadr locator))
               (file-exists-p file)
               (find-file-other-window file)
               (progn
                 (when (eq major-mode (default-value 'major-mode)) (diary-mode))
2a=>		 (when (eq major-mode 'todos-mode) (widen))
                 (goto-char (point-min))
                 (when (re-search-forward (format "%s.*\\(%s\\)"
						  (regexp-quote (nth 2 locator))
						  (regexp-quote (nth 3 locator)))
					  nil t)
		   (goto-char (match-beginning 1))
2b=>		   (todos-diary-goto-entry))))
          (message "Unable to locate this diary entry")))))

Actually, I don't see why the first situation, using a valid marker, is
needed.  I suppose executing that code is quicker than doing a regexp
search, but I doubt it's noticeable, perhaps unless the file is really
huge.  If diary-goto-entry were changed to always search for the entry,
then the simple :around advice would be fine.  If it isn't changed, I
think using :override advice is the simplest alternative.

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-15 12:52                           ` Stephen Berman
@ 2013-06-16  0:44                             ` Stefan Monnier
  2013-06-16 22:52                               ` Stephen Berman
  0 siblings, 1 reply; 37+ messages in thread
From: Stefan Monnier @ 2013-06-16  0:44 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel

> restore the proper display.  But what happens between widening and
> re-narrowing is different in the two situations (indicated below by the

You could unify the two with something like

(defvar diary-goto-entry-function
    (lambda (pos)
      (if (number-or-marker-p pos) (goto-char pos))
        (goto-char (point-min))
        (when (re-search-forward (format "%s.*\\(%s\\)"
                                         (regexp-quote (car locator))
                                         (regexp-quote (nth 1 locator)))
                                 nil t)
          (goto-char (match-beginning 1))))
  "Function called to jump to a diary entry.
Called with one argument which can be either a simple buffer position,
or a description of the form (FOO BAR) where FOO is some leading text
and BAR is the actual text of the entry.")

(defun diary-goto-entry (button)
  "Jump to the diary entry for the BUTTON at point."
  (let* ((locator (button-get button 'locator))
         (marker (car locator))
         (file (nth 1 locator))
         (place (cond
                 ;; If marker pointing to diary location is valid, use that.
                 ((and marker (marker-buffer marker))
                  (cons (marker-buffer marker) marker))
                 ;; Marker is invalid (eg buffer has been killed).
                 ((and file (file-exists-p file))
                  (cons (find-file-noselect file) (cddr locator)))
                 (t (message "Unable to locate this diary entry") nil))))
    (when place
      (pop-to-buffer (car place))
      (funcall diary-goto-entry-function (cdr place)))))

> Actually, I don't see why the first situation, using a valid marker, is
> needed.

I don't have any opinion on that part because I don't use this part of
the diary.


        Stefan



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-16  0:44                             ` Stefan Monnier
@ 2013-06-16 22:52                               ` Stephen Berman
  2013-06-17  0:37                                 ` Stefan Monnier
  2013-06-17 19:50                                 ` Glenn Morris
  0 siblings, 2 replies; 37+ messages in thread
From: Stephen Berman @ 2013-06-16 22:52 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

On Sat, 15 Jun 2013 20:44:03 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote:

>> restore the proper display.  But what happens between widening and
>> re-narrowing is different in the two situations (indicated below by the
>
> You could unify the two with something like
>
> (defvar diary-goto-entry-function
>     (lambda (pos)
>       (if (number-or-marker-p pos) (goto-char pos))
>         (goto-char (point-min))
>         (when (re-search-forward (format "%s.*\\(%s\\)"
>                                          (regexp-quote (car locator))
>                                          (regexp-quote (nth 1 locator)))
>                                  nil t)
>           (goto-char (match-beginning 1))))
>   "Function called to jump to a diary entry.
> Called with one argument which can be either a simple buffer position,
> or a description of the form (FOO BAR) where FOO is some leading text
> and BAR is the actual text of the entry.")
>
> (defun diary-goto-entry (button)
>   "Jump to the diary entry for the BUTTON at point."
>   (let* ((locator (button-get button 'locator))
>          (marker (car locator))
>          (file (nth 1 locator))
>          (place (cond
>                  ;; If marker pointing to diary location is valid, use that.
>                  ((and marker (marker-buffer marker))
>                   (cons (marker-buffer marker) marker))
>                  ;; Marker is invalid (eg buffer has been killed).
>                  ((and file (file-exists-p file))
>                   (cons (find-file-noselect file) (cddr locator)))
>                  (t (message "Unable to locate this diary entry") nil))))
>     (when place
>       (pop-to-buffer (car place))
>       (funcall diary-goto-entry-function (cdr place)))))
>

Ok, thanks.  So, you can use :around advice if you build the two types
of entry locating operations into the auxiliary function -- but not
without reimplementing diary-goto-entry accordingly.  Note, however,
that FOO can't just be "some leading text" but really has to be the
entry's date string, i.e. (nth 2 locator) [(car locator) is a typo, as
is (nth 1 locator), that should be 3 instead of 1; also I think it's
cleaner to use (nth 2 pos) and (nth 3 pos) and in diary-goto-entry cons
file to locator instead of (cddr locator)], otherwise either the wrong
or no entry will be found.  In other words, diary-goto-entry-function
can really only have that exact function as its value, so might be
better defined as a defconst.

>> Actually, I don't see why the first situation, using a valid marker, is
>> needed.
>
> I don't have any opinion on that part because I don't use this part of
> the diary.

So I think we now have three alternatives to choose from:
1. Keep diary-goto-entry as it is and add the variable
   diary-goto-entry-function with default value 'diary-goto-entry, which
   other packages can override (though the overriding function will
   still have to contain the same entry locating operations).
2. Change diary-goto-entry as above and add the variable (or defconst)
   diary-goto-entry-function, which other packages can modify with
   :around advice.
3. If using a marker to locate the entry is not necessary, then we could
   use the following somewhat simpler definitions (here, too, maybe the
   defvar should be a defconst):

   (defvar diary-goto-entry-function
     (lambda (pos)
       (let ((specifier (regexp-quote (nth 2 pos)))
             (literal (regexp-quote (nth 3 pos))))
         (goto-char (point-min))
         (if (re-search-forward (format "%s.*\\(%s\\)" specifier literal) nil t)
   	  (goto-char (match-beginning 1))))))
   
   (defun diary-goto-entry (button)
     "Jump to the diary entry for the BUTTON at point."
     (let* ((locator (button-get button 'locator))
   	    (file (cadr locator)))
       (if (not (and (file-exists-p file) (find-file-other-window file)))
           (message "Unable to locate this diary entry")
         (when (eq major-mode (default-value 'major-mode)) (diary-mode))
         (funcall diary-goto-entry-function locator))))

   This works with :around advice according to my tests. Glenn, is there
   some situation where it's necessary or highly advantageous to use a
   marker to locate the diary entry?

If all three alternatives are equally viable, is there any reason to
prefer one over the others?

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-16 22:52                               ` Stephen Berman
@ 2013-06-17  0:37                                 ` Stefan Monnier
  2013-06-17 19:50                                 ` Glenn Morris
  1 sibling, 0 replies; 37+ messages in thread
From: Stefan Monnier @ 2013-06-17  0:37 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel

> without reimplementing diary-goto-entry accordingly.  Note, however,
> that FOO can't just be "some leading text" but really has to be the
> entry's date string,

I called them FOO and BAR because I know nothing about this code and so
don't know what these are really supposed to be.

> i.e. (nth 2 locator) [(car locator) is a typo, as
> is (nth 1 locator), that should be 3 instead of 1;

No, the error is that it should be (car pos) and (nth 1 pos), since
`locator' is an undefined variable (if I were to use dynamic-scoping,
I wouldn't bother passing a `pos' argument).

But again: I know nothing about those `locator's, so I have no idea what
is a good argument to pass to diary-goto-entry-function.  My suggestion
was only based on the code you sent.


        Stefan



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-16 22:52                               ` Stephen Berman
  2013-06-17  0:37                                 ` Stefan Monnier
@ 2013-06-17 19:50                                 ` Glenn Morris
  2013-06-17 22:33                                   ` Stephen Berman
  1 sibling, 1 reply; 37+ messages in thread
From: Glenn Morris @ 2013-06-17 19:50 UTC (permalink / raw)
  To: Stephen Berman; +Cc: Stefan Monnier, emacs-devel

Stephen Berman wrote:

>    This works with :around advice according to my tests. Glenn, is there
>    some situation where it's necessary or highly advantageous to use a
>    marker to locate the diary entry?

Don't know. It predates me. I added the other thing as a fallback for
killed buffers. At least, this is what vc-annotate tells me.



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-17 19:50                                 ` Glenn Morris
@ 2013-06-17 22:33                                   ` Stephen Berman
  0 siblings, 0 replies; 37+ messages in thread
From: Stephen Berman @ 2013-06-17 22:33 UTC (permalink / raw)
  To: Glenn Morris; +Cc: Stefan Monnier, emacs-devel

On Mon, 17 Jun 2013 15:50:35 -0400 Glenn Morris <rgm@gnu.org> wrote:

> Stephen Berman wrote:
>
>>    This works with :around advice according to my tests. Glenn, is there
>>    some situation where it's necessary or highly advantageous to use a
>>    marker to locate the diary entry?
>
> Don't know. It predates me. I added the other thing as a fallback for
> killed buffers. At least, this is what vc-annotate tells me.

Ok.  Then for now I'll go with this alternative:

>>    Keep diary-goto-entry as it is and add the variable
>>    diary-goto-entry-function with default value 'diary-goto-entry, which
>>    other packages can override (though the overriding function will
>>    still have to contain the same entry locating operations).

since it's least intrusive to diary-lib.el, though it means code
duplication in the overriding todo-mode function.  We can always decide
to change it later.

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (code)
  2013-06-10 20:51       ` New version of todo-mode.el (code) Stephen Berman
@ 2013-08-30 18:31         ` Jambunathan K
  2013-09-08 21:09           ` Stephen Berman
  0 siblings, 1 reply; 37+ messages in thread
From: Jambunathan K @ 2013-08-30 18:31 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel


Stephan

I have sent a bug report your way.  You have been using todo-mode for a
good part of upwards of a decade(?)[1] Definitely, there are aspects of
it which had you hooked.

I would appreciate if you could augment the Info documentation with a
use-case and a note about suggested workflow.  I haven't explored the
filters or sorting routines, btw.

[1] This is what made me try todo-mode in first place.




^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (announcement + user guide)
  2013-06-09 23:31 New version of todo-mode.el (announcement + user guide) Stephen Berman
  2013-06-10 13:24 ` Bastien
  2013-06-13 10:59 ` Vitalie Spinu
@ 2013-08-31  3:55 ` Jambunathan K
  2 siblings, 0 replies; 37+ messages in thread
From: Jambunathan K @ 2013-08-31  3:55 UTC (permalink / raw)
  To: Stephen Berman; +Cc: emacs-devel


Wrt, todo-mode vs org-mode, there was a question:

  Does Org do that already?

The answer to the above question by can be found by answering another
question:

  Can I use a Samurai sword as shavin blade? [1]

The essential difference is in (and derives from) their underlying data
model.

Todo-mode uses a format defined by diary

   (info "(emacs) Diary")
   (info "(emacs) Format of Diary File")

Org-mode is a rebel.  Org-mode rolls it's own data format.  Org allows
importing of diary entries but actively encourges NON-reliance on diary
file.

    (info "(org) Weekly/daily agenda")

Furthermore, Org's agenda buffer (which is the equivalent of diary
display) is incompatible with diary format. [2]

----------------------------------------------------------------

In the obsolete version of legacy todo-mode file [3], I see mentions of
Carsten Dominik.  So I believe Carsten was very familiar with todo-mode
and his experience with todo-mode also fed in to design of Org-mode.

,----
| ;;      Carsten Dominik <dominik@strw.LeidenUniv.nl> suggested that
| ;;
| ;;          "&%%(todo-cp)"
| ;;
| ;;      might be nicer and to that effect a function has been declared
| ;;      further down in the code.  You may wish to auto-load this.
| ;;
| ;;      Carsten also writes that that *changing* the prefix after the
| ;;      todo list is already established is not as simple as changing
| ;;      the variable - the todo files have to be changed by hand.
`----

----------------------------------------------------------------

[1] I hope the answer is NO.  I haven't seen or used samurai sword.  I
just use it because it sounds fancy.  May be Wikipedia mentions it, I
don't know...

[2] Incompatible, atleast with factory settings of Org and Diary.  

For example, if I create a single TODO item In Org, copy the daily
agenda verbatim to the diary file, I see that the whole calendar lights
up with entries.  

My gut feeling is that with some simple processing of Org agenda buffer
and with some simple diary customization (of date format), it should be
possible for Org to "export" to a standard Emacs diary file.

[3] lisp/obsolete/otodo-mode.el



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: New version of todo-mode.el (code)
  2013-08-30 18:31         ` Jambunathan K
@ 2013-09-08 21:09           ` Stephen Berman
  0 siblings, 0 replies; 37+ messages in thread
From: Stephen Berman @ 2013-09-08 21:09 UTC (permalink / raw)
  To: Jambunathan K; +Cc: emacs-devel

On Sat, 31 Aug 2013 00:01:51 +0530 Jambunathan K <kjambunathan@gmail.com> wrote:

> I have sent a bug report your way.  You have been using todo-mode for a
> good part of upwards of a decade(?)[1] Definitely, there are aspects of
> it which had you hooked.
>
> I would appreciate if you could augment the Info documentation with a
> use-case and a note about suggested workflow.  I haven't explored the
> filters or sorting routines, btw.
>
> [1] This is what made me try todo-mode in first place.

As I replied to essentially the same request in your bug#15225 report, I
may consider fleshing out some of the hints about use-cases and
workflows in the manual, but I want to avoid giving the impression that
other uses are unsupported.  Perhaps you can refer me to another Emacs
manual that you consider exemplary in this respect.

Steve Berman



^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2013-09-08 21:09 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-09 23:31 New version of todo-mode.el (announcement + user guide) Stephen Berman
2013-06-10 13:24 ` Bastien
2013-06-10 14:35   ` Stephen Berman
2013-06-10 14:49     ` Bastien
2013-06-10 20:51       ` New version of todo-mode.el (code) Stephen Berman
2013-08-30 18:31         ` Jambunathan K
2013-09-08 21:09           ` Stephen Berman
2013-06-10 14:52     ` New version of todo-mode.el (announcement + user guide) Óscar Fuentes
2013-06-10 20:52       ` Stephen Berman
2013-06-11  0:20         ` Stefan Monnier
2013-06-11 18:36           ` Stephen Berman
2013-06-11 21:48             ` Stefan Monnier
2013-06-12 21:37               ` Stephen Berman
2013-06-13  1:06                 ` Stefan Monnier
2013-06-13 20:53                   ` Stephen Berman
2013-06-12 17:28             ` Glenn Morris
2013-06-12 21:26               ` Stefan Monnier
2013-06-12 21:37               ` Stephen Berman
2013-06-13  1:18                 ` Stefan Monnier
2013-06-13 20:53                   ` Stephen Berman
2013-06-14  0:21                     ` Stefan Monnier
2013-06-14 21:37                       ` Stephen Berman
2013-06-15  0:40                         ` Glenn Morris
2013-06-15  1:49                         ` Stefan Monnier
2013-06-15 12:52                           ` Stephen Berman
2013-06-16  0:44                             ` Stefan Monnier
2013-06-16 22:52                               ` Stephen Berman
2013-06-17  0:37                                 ` Stefan Monnier
2013-06-17 19:50                                 ` Glenn Morris
2013-06-17 22:33                                   ` Stephen Berman
2013-06-12 18:30             ` Wolfgang Jenkner
2013-06-12 21:38               ` Stephen Berman
2013-06-13  1:24                 ` Wolfgang Jenkner
2013-06-13 20:54                   ` Stephen Berman
2013-06-13 10:59 ` Vitalie Spinu
2013-06-13 20:54   ` Stephen Berman
2013-08-31  3:55 ` Jambunathan K

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).