branch: externals/filechooser commit aab481d354d5126cf7d488963c530c13f03f1709 Author: Rahguzar <rahgu...@zohomail.eu> Commit: Rahguzar <rahgu...@zohomail.eu>
Rework handling of filters --- filechooser.el | 96 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/filechooser.el b/filechooser.el index 2aa8fcc9b6..af04d9d02a 100644 --- a/filechooser.el +++ b/filechooser.el @@ -126,6 +126,7 @@ UI of choice: usually RET." ;;;; Internal Variables (defvar filechooser--filters nil) +(defvar filechooser--active-filters nil) (defvar filechooser--selection nil) (defvar filechooser--multiple-selection nil) (defvar filechooser--dired-buffers nil) @@ -146,6 +147,16 @@ See Info node `(elisp) Programmed Completion' for CAND and TRANSFORM." (expand-file-name name (dired-current-directory)) name))) +(defun filechooser--filters (filters) + "Return FILTERS added to `filechooser-filters'." + (cl-delete-duplicates (append filechooser-filters filters) + :test #'equal :key #'car)) + +(defun filechooser--active-filters () + "Return active filters." + (delq nil (mapcar (lambda (flt) (if (cddr flt) (cadr flt))) + filechooser--filters))) + (defun filechooser-toggle-filter (arg) "Toggle a filter. With prefix ARG toggle multiple filters using `completing-read-multiple'." @@ -163,6 +174,7 @@ With prefix ARG toggle multiple filters using `completing-read-multiple'." #'table nil t))))) (dolist (name names) (cl-callf not (cdr (alist-get name filechooser--filters nil nil #'equal)))) + (setq filechooser--active-filters (filechooser--active-filters)) (if (minibufferp) (throw 'continue t) (dolist (buf filechooser--dired-buffers) @@ -185,18 +197,17 @@ With prefix ARG toggle multiple filters using `completing-read-multiple'." (cl-callf not (cdr (alist-get (car current) regex-filters nil nil #'equal)))) (nreverse regex-filters))) -(defun filechooser--filters-predicate (filters) - "Make a predicate out of FILTERS." - (lambda (name) - (catch 'match - (dolist (filter filters) - (when (cond - ((stringp filter) - (string-match filter name)) - ((functionp filter) - (funcall filter name)) - ((error "Unknown filter %S" filter))) - (throw 'match t)))))) +(defun filechooser--filters-predicate (name) + "Return non-nil if NAME matches an active filter." + (catch 'match + (dolist (filter filechooser--active-filters) + (when (cond + ((stringp filter) + (string-match filter name)) + ((functionp filter) + (funcall filter name)) + ((error "Unknown filter %S" filter))) + (throw 'match t))))) ;;; Utility definitions (defmacro filechooser--maybe-with-new-frame (minibuffer &rest body) @@ -259,8 +270,8 @@ See Info node `(elisp) Programmed Completion' for STR, PRED and ACTION." (group-function . filechooser--multiple-group-function))) (_ (completion-file-name-table str pred action)))) -(defun filechooser--read-file-name-1 (prompt &optional mustmatch filters dir default) - "Read a filename with PROMPT and predicate made from FILTERS. +(defun filechooser--read-file-name-1 (prompt &optional mustmatch dir default) + "Read a filename with PROMPT and predicate made from active filters. MUSTMATCH and DIR are as in `read-file-name'. DEFAULT is the default filename. If MULTIPLE is non-nil `completing-read-multiple' is used." (catch 'continue @@ -269,8 +280,7 @@ If MULTIPLE is non-nil `completing-read-multiple' is used." (current-local-map))) (when dir (setq default-directory dir))) (read-file-name - prompt dir default mustmatch nil - (when filters (filechooser--filters-predicate filters)))))) + prompt dir default mustmatch nil #'filechooser--filters-predicate)))) (defun filechooser--handle-exisiting-file (filename &optional dir filters) "Handle an existing FILENAME according to `filechooser-save-existing-files'. @@ -297,18 +307,13 @@ are the filters to use in that case." "Read a filename with PROMPT and predicate made from FILTERS. MUSTMATCH and DIR are as in `read-file-name'. DEFAULT is the default filename. If MULTIPLE is non-nil `completing-read-multiple' is used." - (let ((result t) - (filechooser--filters (cl-delete-duplicates - (append filechooser-filters filters) - :test #'equal :key #'car))) + (let* ((result t) + (filechooser--filters (filechooser--filters filters)) + (filechooser--active-filters (filechooser--active-filters))) (while (eq t result) (when (minibufferp nil t) (abort-minibuffers)) - (setq result (filechooser--read-file-name-1 - prompt mustmatch - (delq nil (mapcar (lambda (flt) (if (cddr flt) (cadr flt))) - filechooser--filters)) - dir default))) + (setq result (filechooser--read-file-name-1 prompt mustmatch dir default))) (when (equal result default) (setq result (expand-file-name default dir))) (when (and default (file-directory-p result)) @@ -360,14 +365,10 @@ files which satisfy one of the active filters from FILTERS or (defun filechooser--multiple-read-file-name (prompt &optional dir) "Read a filename with PROMPT and starting from DIR. MAP contains additional key bindigs." - (let ((result t) - filters) + (let ((result t)) (while (eq t result) (when (minibufferp nil t) (abort-minibuffers)) - (setq filters (delq nil (mapcar - (lambda (flt) (if (cddr flt) (cadr flt))) - filechooser--filters))) (setq result (catch 'continue (minibuffer-with-setup-hook @@ -375,7 +376,7 @@ MAP contains additional key bindigs." filechooser-multiple-selection-map (current-local-map)))) (completing-read prompt #'filechooser--multiple-loop-table - (filechooser--filters-predicate filters) t + #'filechooser--filters-predicate t (abbreviate-file-name dir) 'file-name-history))))) result)) @@ -390,10 +391,9 @@ files which satisfy one of the active filters from FILTERS or `filechooser-filters' are presented for completions." (setq dir (file-name-as-directory (expand-file-name (or dir default-directory)))) - (let ((filechooser--filters (cl-delete-duplicates - (append filechooser-filters filters) - :test #'equal :key #'car)) - selected filechooser--multiple-selection) + (let* ((filechooser--filters (filechooser--filters filters)) + (filechooser--active-filters (filechooser--active-filters)) + selected filechooser--multiple-selection) (filechooser--maybe-with-new-frame only (while (setq dir (catch 'done @@ -518,9 +518,10 @@ editing session. FILTERS are in the format of `filechooser-filters'." (unless (and filechooser--selection (file-directory-p (car filechooser--selection))) (setq filechooser--selection (list (make-temp-file "filechooser-selection-" t)))) - (let ((overriding-map `((t . ,filechooser-dired-overriding-map))) - (filechooser--filters (append filechooser-filters filters)) - filechooser--dired-buffers) + (let* ((overriding-map `((t . ,filechooser-dired-overriding-map))) + (filechooser--filters (filechooser--filters filters)) + (filechooser--active-filters (filechooser--active-filters)) + filechooser--dired-buffers) (save-window-excursion (unwind-protect (progn @@ -571,16 +572,15 @@ editing session. FILTERS are in the format of `filechooser-filters'." (progn (setq end (progn (goto-char end) (forward-line 1) (pos-eol))) (setq beg (progn (goto-char beg) (forward-line -1) (goto-char (pos-bol)))) - (let ((pred (filechooser--filters-predicate active))) - (while (< (point) end) - (when-let ((name (dired-get-filename 'no-dir t))) - (alter-text-property (1- (point)) (pos-eol) 'invisible - (lambda (val) - (setq val (ensure-list val)) - (if (funcall pred name) - (cl-callf2 delq 'filechooser-filter val) - (cl-pushnew 'filechooser-filter val))))) - (forward-line)))) + (while (< (point) end) + (when-let ((name (dired-get-filename 'no-dir t))) + (alter-text-property (1- (point)) (pos-eol) 'invisible + (lambda (val) + (setq val (ensure-list val)) + (if (filechooser--filters-predicate name) + (cl-callf2 delq 'filechooser-filter val) + (cl-pushnew 'filechooser-filter val))))) + (forward-line))) (remove-from-invisibility-spec 'filechooser-filter)) `(jit-lock-bounds ,beg . ,end))