Subject: 28.0.50; RET in todo-edit-mode indents too much
From: Stephen Berman <[email-masked]>
To: [email-masked]
Date: Thu, 27 Aug 2020 13:39:51 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

0. emacs -Q
1. M-x todo-show RET
   (This will either visit an existing todo file or, if there isn't one,
   prompt to create it, along with its first category and item.  Point
   will then be on the item.)
2. Type `em' to edit the item at point in todo-edit-mode.
3. Type RET to add a new line to the item.
   => This should insert a single tab 3 columns wide (the default value
   of todo-indent-to-here) at the start of the new line to satisfy the
   todo-mode file format, but instead two tabs are inserted (which also
   satisfies the format but is superfluous and here unexpected -- that
   is the bug).

In todo-edit-mode `newline' (bound to RET) is remapped to
`newline-and-indent' and indent-line-function is set to todo-indent,
which calles `indent-to' with `todo-indent-to-here' as args.  So typing
RET inserts a tab 3 columns wide (by default).  But by default
electric-indent-mode is enabled and that calls indent-according-to-mode,
which on typing RET again inserts a tab.  Hence, two tabs.

When the rewrite of todo-mode.el was added to Emacs (2013-06-19)
electric-indent-mode was still disabled by default, and I hadn't been
using it and it didn't occur to me that it could interact badly with
todo-mode (and there haven't been bug reports about that till now).
After the default was changed to enable electric-indent-mode
(2013-11-29), I added the line `(electric-indent-mode -1)' to my init
file, so I never saw the two tabs in my use of todo-mode.  But recently
I removed that line from my init file and then ran into this issue.

Setting electric-indent-inhibit to t in todo-edit-mode does not fix the
issue: it prevents reindentation but still calls
indent-according-to-mode from electric-indent-post-self-insert-function,
so two tabs are still inserted.  But adding the line
`(electric-indent-local-mode -1)' to todo-edit-mode does do the job.
However, I think a different approach is better.

Currently, `newline' is remapped to `newline-and-indent' not only in
todo-edit-mode but also in todo-mode, and `indent-line-function' is set
to `todo-indent' in both of these modes and well as in todo-archive-mode
and todo-filtered-items-mode.  But all of these modes except for
todo-edit-mode are read-only modes, so inserting a newline by typing RET
isn't even possible in them, therefore those settings are useless in
those modes and it was a mistake to have them there at all.  Moreover,
todo-edit-quit, which is called to exit todo-edit-mode, runs a format
check that inserts a tab at the beginning of each non-initial line of
the edited item if they don't begin with whitespace; this makes using
`newline-and-indent' unnecessary to ensure a proper format.  (The doc
string of todo-edit-quit doesn't explicitly say a tab is inserted, only
"make sure the following lines are indented", but that seems sufficient.
When editing an entire todo file instead of a single item, the format
check simply signals a user error if there are non-initial item lines
lacking initial whitespace, because editing an entire file risks
corrupting the file format in various ways.)

So my preference is to clean up and simplify todo-mode.el by removing
the remapping of `newline' and only setting `indent-line-function' to
`todo-indent' in todo-edit-mode.  Then, typing RET in todo-edit-mode
inserts a single tab if electric-indent-mode is enabled, and if it is
disabled, no tab is inserted on typing RET, but one is then inserted by
todo-edit-quit, thus preserving the required todo-mode file format.

I will commit a patch for this to master, as well as three tests of
indentation in todo mode, referencing the number of this bug report.
(Ironically, till now the todo mode data file in the Emacs test
directory contained a multiline item whose non-initial lines begin with
two tabs: I wrote this file in a clean environment in which
electric-indent-mode was enabled (as it is by default), but didn't
notice the extra tabs until I wrote the tests accompanying the fix for
this bug report.  I've removed those extra tabs as part of the commit.)

In GNU Emacs 28.0.50 (build 19, x86_64-pc-linux-gnu, GTK+ Version 3.24.17, cairo version 1.17.3)
 of 2020-08-27 built on strobe-jhalfs
Repository revision: 4cf5d2ebee5ac45a435c991e4c0ad12be619d26b
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12008000
System Description: Linux From Scratch SVN-20200401

Configured using:
 'configure 'CFLAGS=-Og -g3' PKG_CONFIG_PATH=/opt/qt5/lib/pkgconfig'

Configured features:
XPM JPEG TIFF GIF PNG RSVG CAIRO SOUND DBUS GSETTINGS GLIB NOTIFY
INOTIFY ACL GNUTLS LIBXML2 FREETYPE HARFBUZZ ZLIB TOOLKIT_SCROLL_BARS
GTK3 X11 XDBE XIM MODULES THREADS LIBSYSTEMD PDUMPER LCMS2