Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

counsel-jump-file: Don't ignore '.*' files if search pattern begins with \. #1820

Alexander-Shukaev opened this issue Nov 24, 2018 · 8 comments


Copy link

@Alexander-Shukaev Alexander-Shukaev commented Nov 24, 2018

Just wanted to see all my .gitignore files with counsel-jump-file but there were no results. Since I'm using "\\(?:\\`[#.]\\)\\|\\(?:[#~]\\'\\)" as counsel-find-file-ignore-regexp, I quickly found this


Line 1799 in 9414f7a

(string-match "\\`\\." ivy-text))

I believe this has to be extended for \. too as this is what you'd type for counsel-jump-file compared to counsel-find-file.

Furthermore, the following implicit filtering smells as well:


Line 2373 in 9414f7a

(concat find-program " * -type f -not -path '*\/.git*'"))

I guess this will also shut down .gitignore files for example which is sad. I'd let users decide what to filter.

Copy link

@CeleritasCelery CeleritasCelery commented Mar 27, 2019

can you just use counsel-git?

Copy link

@Alexander-Shukaev Alexander-Shukaev commented Mar 27, 2019

No, because the use case is to find many .gitignore files in many repositories which are in the tree on different nesting levels under the current directory. This definitely needs to be fixed within counsel-jump-file to fully serve its purpose.

@abo-abo abo-abo closed this in 3b677d4 Mar 28, 2019
Copy link

@abo-abo abo-abo commented Mar 28, 2019

Thanks, please test.

Copy link

@Alexander-Shukaev Alexander-Shukaev commented Mar 29, 2019

That change breaks the current display behavior, it leaves only basenames of files but not their relative paths from the current directory. Also the arguments for find are now suboptimal. Here is my take on all of this including some cleanups (tested):

(defcustom counsel-hidden-file-regexp "\\(?:\\`\\|[/\\]\\)\\."
  "Regexp of hidden files.")

(defcustom counsel-find-file-ignore-regexp nil
  "Regexp of files to ignore by `counsel--find-file-matcher'.
These files are not ignored if `ivy-text' matches them.
The common way to show all files is to begin `ivy-text' with a dot \".\".

Example value: \"\\(?:\\(?:\\`\\|[/\\]\\)[#.]\\|[#~]\\'\\)\".
Apart from hidden files, this will also ignore temporary and lock files.
Choosing the \"Hidden Files\" option (see `counsel-hidden-file-regexp'),
might be convenient, since one can still access hidden files if search input
(see `ivy-text') begins with a dot \".\" or contains slash and dot \"/.\",
depending on a preferred filtering criteria. The generic way to toggle
(show/hide) ignored files is \\[ivy-toggle-ignore], but the former method
should be more efficient."
  :type `(choice (const :tag "None" nil)
                 (const :tag "Hidden Files"
                 (const :tag "Ignored Extensions"
                        ,(regexp-opt completion-ignored-extensions))
                 (regexp :tag "Regexp")))

(defcustom counsel-file-jump-args "-name '.git' -prune -o -type f -print | cut -c 3-"
  "Arguments for the `find-command' when using `counsel-file-jump'."
  :type 'string)

(defcustom counsel-dired-jump-args "-name '.git' -prune -o -type d -print | cut -c 3-"
  "Arguments for the `find-command' when using `counsel-dired-jump'."
  :type 'string)

(defun counsel--find-file-matcher (regexp candidates)
  "Return REGEXP matching CANDIDATES.
Skip some dotfiles unless `ivy-text' requires them."
  (let ((res
          regexp candidates
          (lambda (re-str)
            (lambda (x)
              (string-match re-str (directory-file-name x)))))))
    (if (or (null ivy-use-ignore)
            (null counsel-find-file-ignore-regexp)
            (string-match-p counsel-hidden-file-regexp ivy-text))
      (or (cl-remove-if
           (lambda (x)
             (and (string-match-p counsel-find-file-ignore-regexp x)
                  (not (member x ivy-extra-directories))))

(defun counsel--file-name-filter (&optional use-ignore)
  "Return a command that filters a file list to match ivy candidates.
If USE-IGNORE is non-nil, try to generate a command that respects
  (let ((regex ivy--old-re)
        (ignore-re (list (counsel--elisp-to-pcre
        (filter-cmd (cl-find-if
                     (lambda (x)
                        (car (split-string (car x)))))
    (when (and use-ignore ivy-use-ignore
               (cdr filter-cmd)
               (not (string-match-p counsel-hidden-file-regexp ivy-text))
               (not (string-match-p counsel-find-file-ignore-regexp
                                    (or (car ivy--old-cands) ""))))
      (setq regex (if (stringp regex)
                      (list ignore-re (cons regex t))
                    (cons ignore-re regex))))
    (setq cmd (format (car filter-cmd)
                      (counsel--elisp-to-pcre regex (cdr filter-cmd))))
    (if (string-match-p "csh\\'" shell-file-name)
        (replace-regexp-in-string "\\?!" "?\\\\!" cmd)

(defun counsel-dired-jump (&optional initial-input initial-directory)
  "Jump to a directory (see `dired-jump') below the current directory.
List all subdirectories within the current directory.
INITIAL-INPUT can be given as the initial minibuffer input.
INITIAL-DIRECTORY, if non-nil, is used as the root directory for search."
   (list nil
         (when current-prefix-arg
           (read-directory-name "From directory: "))))
  (counsel-require-program find-program)
  (let ((default-directory (or initial-directory default-directory)))
    (ivy-read "Find directory: "
                (concat find-program " " counsel-dired-jump-args))
               "\n" t)
              :matcher #'counsel--find-file-matcher
              :initial-input initial-input
              :action (lambda (d) (dired-jump nil (expand-file-name d)))
              :history 'file-name-history
              :keymap counsel-find-file-map
              :caller 'counsel-dired-jump)))

Please, test and incorporate if looks good.

abo-abo added a commit that referenced this issue Mar 29, 2019
Copy link

@Alexander-Shukaev Alexander-Shukaev commented Mar 29, 2019


(defcustom counsel-hidden-file-regexp "\\(?:\\`\\|[/\\]\\)\\."

is actually important when counsel--find-file-matcher is applied for counsel-*-jump functions in particular because hidden files can be not just in the current directory but also in nested directories, in which case testing (string-match-p "\\`\\." ivy-text) is not sufficient.

abo-abo added a commit that referenced this issue Apr 3, 2019
Copy link

@abo-abo abo-abo commented Apr 3, 2019

Copy link

@Alexander-Shukaev Alexander-Shukaev commented Apr 3, 2019

Sorry to bump this again but was not what I meant. If you check the changes that I posted again, every function there was modified. In particular, counsel-hidden-file-regexp is used in counsel--find-file-matcher and counsel--file-name-filter instead of plain "\\`\\.". That is your last change will not do what I meant in the previous comment.

Copy link

@abo-abo abo-abo commented Apr 3, 2019

@Alexander-Shukaev The change I made solved the issues I could detect. If there's still something, please open a new issue with the whole reproduction scenario.

astoff added a commit to astoff/swiper that referenced this issue Jan 1, 2021
astoff added a commit to astoff/swiper that referenced this issue Jan 1, 2021
astoff added a commit to astoff/swiper that referenced this issue Jan 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

3 participants