Subject: 31.0.50; marking inconsistency between VC-Dir and dired-vc-next-action
From: Sean Whitton <[email-masked]>
To: [email-masked]
Date: Thu, 06 Mar 2025 11:56:59 +0800
List-Id: <debbugs-submit.debbugs.gnu.org>

X-debbugs-cc: [email-masked], [email-masked], [email-masked]

Try this:

1. make a random edit to src/emacs.c
2. open Dired in the root of emacs.git
3. use 'm' to mark src
4. go back up one line, use 'i' to insert src
5. move down to emacs.c, use 'm' to mark that as well
6. C-x v v

This gets you a VC-Dir in which both src/ and src/emacs.c are marked.

--8<---------------cut here---------------start------------->8---
                         ./
  *                      src/
  *  edited              src/emacs.c
--8<---------------cut here---------------end--------------->8---

But usually, you cannot get into this state.  If you try to mark src/
when src/emacs.c is already marked, you can't, and vice-versa.

This is not just a display inconsistency, because it changes the list of
files that vc-dir-deduce-fileset returns.

I think that dired-vc-next-action has the more useful behaviour.
Freely marking and unmarking individual entries in VC-Dir would make it
easier to use.  So I would like to make that possible.  We can guard it
behind a defcustom so people can retain the old marking behaviour if
they prefer it.

So my proposal to make things more consistent would be:

- a new defcustom, which when non-nil, allows freely marking both files
  in directories, and those directories themselves, in VC-Dir

  (I think we should default it to non-nil)

- fix dired-vc-next-action to respect that defcustom, i.e., when it is
  nil, dired-vc-next-action shouldn't generate a VC-Dir buffer with
  both src/ and src/emacs.c marked, in the example above

- change vc-dir-deduce-fileset to filter out individual files when the
  directory containing them is marked.  E.g.

  --8<---------------cut here---------------start------------->8---
                           ./
    *                      src/
    *  edited              src/emacs.c
  --8<---------------cut here---------------end--------------->8---
  Currently vc-dir-deduce-fileset returns ("src/" "src/emacs.c"),
  it should return just ("src/").

I think that for all the operations VC supports, passing a whole
directory along with some of the files in it is semantically equivalent
to just passing the whole directory.  If would have to be an esoteric,
highly VCS-specific operation to do anything other than that, I think?

For a case like this:
--8<---------------cut here---------------start------------->8---
                         ./
   *                     src/
   * edited              src/cm.c
     edited              src/emacs.c
--8<---------------cut here---------------end--------------->8---

the UI is a little confusing, because any operation will also act on
emacs.c, but it is not marked.  I would propose that we add another
symbol next to src/emacs.c, say '-', in a less prominently coloured
face, indicating that despite not having been explictly marked, it is
still effectively part of the fileset:

--8<---------------cut here---------------start------------->8---
                         ./
   *                     src/
   * edited              src/cm.c
   - edited              src/emacs.c
--8<---------------cut here---------------end--------------->8---
(imagine the '-' is in a different colour).

How does this design look?

-- 
Sean Whitton