dired-hacks
dired-hacks copied to clipboard
Filter groups break when reverting buffer with expanded subtrees
I've been running into the problem where filter groups do not get displayed after reverting the buffer and point is on a line that is contained within the region of a subtree.
It seems the culprit is that (ignore-errors (dired-next-subdir 0))
in dired-filter-group--apply
evaluates to nil
in the above scenario. I'm assuming because dired-next-subdir
is not aware of subtree's.
I made a fix for this that just folds the subtrees, applies the filter groups, and then re-expands the subtrees again:
(defun dired-filter-group-subtree-hack (orig-fun filter-group)
"Fold subtree's, apply filter groups, expand subtrees.
If `dired-subtree' is enabled, fold all of the expanded subtrees
before calling `dired-filter-group--apply' and re-expand them
after.
This avoids breaking the filter groups machinery when subtrees are
expanded and the buffer is reverted."
(let* ((subtrees (and (featurep 'dired-subtree)
(let ((dired-filter-keep-expanded-subtrees t))
(eval (dired-filter--mark-unmarked 't))
(reverse dired-filter--expanded-dirs))))
(prefix (car subtrees)))
;; fold all expanded subtrees
(when subtrees
(dired-utils-goto-line prefix)
(dired-subtree-toggle)
(--each-while (cdr subtrees)
(unless (string-prefix-p prefix it) (setq prefix it))
(save-excursion
(dired-utils-goto-line it)
(dired-subtree-toggle))))
(funcall orig-fun filter-group)
;; re-expand folded subtrees
(when subtrees
(--each subtrees
(save-excursion
(dired-utils-goto-line it)
(dired-subtree-insert))))))
(advice-add 'dired-filter-group--apply :around #'dired-filter-group-subtree-hack)
Another possible solution would be to remove and then re-apply the subtree overlays instead of having to re-insert the contents of all the subtrees.
It would be great to see if someone more familiar with the internals could see if there is a better option.