Hi Tino,
Thanks so much for your detailed and very helpful comments.
I've made almost all your suggested changes, and for the few
exceptions, I changed the code in the direction I think you
intended.
Below, I give specific responses to each of your points.
Please take a look. There are a few questions/points for
your consideration therein.
I haven't had a chance yet to split the commit to isolate the
saved filters fix, but I will do that tomorrow and submit
appropriate patches and bug reports. (Below, I do describe the
bug more precisely and give an example.)
I still thought it would be useful to respond to your
suggestions now. I've attached a patch file of the most recent
commit on my branch against the current master for reference.
Thanks again for all your feedback and help!
Regards, Chris
> ibuffer-filter-by-filename-extension
>
> I would call this:
> ibuffer-filter-by-extension
> or
> ibuffer-filter-by-file-extension
I agree that those are simpler. I had gone with the more complicated
name to make clear that also filters on whether the buffer is visiting a
file. But that is also clear with the simpler name.
I've used file-extension to make clear that this applies to file buffers
only. By related reasoning, I've also changed filename-directory and
filename-base to directory and basename; see the note below in
response to your basename comment for how I've handled these in the
revision.
> ibuffer-filter-by-filename-root
I have eliminated this as you suggested.
> You mention somewhere in the patch:
> ;; This should probably be called pathname but kept for backward compatibility
> The word 'filename' is right...
Good point. I've eliminated this comment.
> ibuffer-filter-by-filename-base
> I would call this:
> ibuffer-filter-by-basename
>
> But what i would do, instead of defining this command and binding it
> to '/ F' i would define instead:
I see your point, but I still think there are good reasons to keep this
one. This filter is useful to prevent inadvertent matching both against
random parts of a file's path and against utility (non-file) buffers
with systematically related names. I think this is a fairly common use
case. (For me, this is one of the filters I use most often
interactively.) Moreover, the buffer name and the buffer file name need
not be the same (e.g., with uniquify/ multiple files of the same name,
or the edge case of explicit renaming).
The buffer name filter you suggest is already available as
ibuffer-filter-by-name (/ n).
Here's what I've done on this:
1. Add a `ibuffer-filter-by-visiting-file' (/ v) that selects
buffers that are visiting a file. This is useful in its own
right (see next item). It also makes '/ n' + '/ v' [that is,
(and (name . "...") (visiting-file))] almost the same as
my '/ F', or put another way, makes '/ F' a more precise
shortcut.
2. Changed `ibuffer-filter-by-filename-directory' to
`ibuffer-filter-by-directory' and changed the functionality so that
in a file buffer it matches against the file's path but in a
non-file buffer matches against default-directory. This is of
practical interest and '/ /' + '/ v'
[that is, (and (directory . "...") (visiting-file))] gives the original
functionality quite simply.
3. Keep the `ibuffer-filter-by-basename', making the name
change you suggested and keeping it on '/ F'. It does
no harm here and, I think, adds some value.
Let me know what you think.
> I like the new command `ibuffer-filter-chosen-by-completion', and
> i think your proposal of binding it to '/ TAB' is a good choice; the
> other command previously bound to '/ TAB' its also bound to '/ t', so
> this change seems for better.
>
> Similar thoughs applies to binding `ibuffer-filter-by-filename-directory'
> to '/ /'; this is consistent with `ibuffer-mark-dired-buffers' ('* /').
> Your alternative binding for `ibuffer-filter-disable' ('/ DEL')
> is easy to remember.
>
> That said, reassign key bindings is usually a matter of concern.
> It might be people get used to '/ TAB' and '/ /' standing for their
> current bindings. It must be a consensus before changing any long
> standing key bindings.
Understood.
I think the new bindings are highly mnemonic and will happily advocate
for them. But the need for consensus makes total sense.
(Note: '/ d' is already bound to ibuffer-decompose-filter or I would have
used it. I felt that the change I made keeps the mnemonic strong with
less overall impact -- what's a better match for decompose?, for instance.)
> You use a macro from subr-x.el in ibuf-ext.el, so you need to:
> (eval-when-compile (require 'subr-x))
Done. Good catch!
> There are several trailing white spaces in your patch.
Fixed.
> Your commit message don't follow the Emacs standards.
Thanks for spelling that out. I've fixed this on the new
commit rather than amend the old message and modify
the history. If you think more is required here, let
me know.
> You might want to write NEWS entry for the new features.
Done, and included in this commit/patch.
> I would change the wording in `ibuffer-included-in-filters-p' doc string.
Done.
> Once you add `ibuffer-and-filter' there is code duplication...I would
> extract the common code in a new auxiliar function....
Done. I removed some additional code duplication by using
ibuffer-decompose-filter as well and more with the push, while
eliminating unnecessary nesting in the result.
> In `ibuffer-filter-by-starred-name' you are matching a buffer name
> starting with "*". That covers all special buffers but it might
> add some garbage.
That makes sense. This means thinking of starred buffers as special
entities, in which case you don't want to match '*foo''s. If you want
those, you can filter by name explicitly. I've made the suggested
change.
> Could you create a receipt where the bug cause an actual failure?
> ... I don't object to the new format, though.
> I agree is more clear when writing filters by hand.
>
> I much prefer if this part of the patch go to a separated bug report.
OK, I'll do that. Just for the discussion here, the issue is
at the following point in the *original* `ibuffer-save-filters':
(ibuffer-aif (assoc name ibuffer-saved-filters)
(setcdr it filters)
(push (list name filters) ibuffer-saved-filters))
This treats existing filters (setcdr) and new filters (push)
inconsistently. Using the default value of ibuffer-saved-filters
(("gnus"
((or
(mode . message-mode)
(mode . mail-mode)
(mode . gnus-group-mode)
(mode . gnus-summary-mode)
(mode . gnus-article-mode))))
("programming"
((or
(mode . emacs-lisp-mode)
(mode . cperl-mode)
(mode . c-mode)
(mode . java-mode)
(mode . idl-mode)
(mode . lisp-mode)))))
and doing
(ibuffer-save-filters "foo" '((name . "foo") (derived-mode . text-mode)))
(ibuffer-save-filters "gnus" '((filename . ".")
(or (derived-mode . prog-mode)
(mode . "compilation-mode"))))
gives the following incorrect value for `ibuffer-saved-filters'
(("foo"
((name . "foo")
(derived-mode . text-mode)))
("gnus"
(filename . ".")
(or
(derived-mode . prog-mode)
(mode . "compilation-mode")))
("programming"
((or
(mode . emacs-lisp-mode)
(mode . cperl-mode)
(mode . c-mode)
(mode . java-mode)
(mode . idl-mode)
(mode . lisp-mode)))))
As you can see, the existing entry "gnus" breaks the expected format.
So to be more precise than I was earlier: In addition to the unnecessary
nesting level, this breaks anytime you save to an existing filter. My
change replaces the `list' with a `cons' and replaces various `cadr''s
with `cdr''s, making the two cases consistent and eliminating the extra
nesting.
Tomorrow, I will pull out the saved filter changes and submit a
formal bug report with patches for the two approaches, making
the other ibuffer changes independent. For the moment, to
facilitate discussion, I've included the commit with my previous
approach included and attached the patch. Sorry for the extra
delay on doing the splitting, but I'm on it.