0

CentOS 7, Emacs 27.2, Ivy, Swiper, Counsel package.

In Temp folder I have different files. I want to find using counsel-locate all text files only in this folder and all subfolders.

I try this: enter image description here enter image description here enter image description here

As you can see I use command M-x counsel-locate .txt but counsel finds ALL text files in whole HDD. But I need to find all text files ONLY in the folder Temp.

Is this possible with the counsel package?

P.S.

(defun adl/counsel-locate-in-the-current-folder-and-subfolders ()
  (interactive)
  (counsel-locate (concat (file-truename default-directory) " ")))

Work only for current folder. But I need to find also in all subfolders. Here screenshots enter image description here enter image description here enter image description here enter image description here

6
  • Try M-x counsel-locate $PWD/*.txt. This command will probably find all txt files in the current folder and its subfolders.
    – adl
    Jun 8, 2021 at 5:36
  • Related: stackoverflow.com/questions/6196744/…
    – adl
    Jun 8, 2021 at 5:37
  • @adl $PWD/*.txt - not work this approach. Result is Nothing found Jun 8, 2021 at 6:23
  • An alternate option is counsel-fd-file-jump from counsel-fd which lists all files under the current directory. You can select .txt files easily using ivy. Jun 8, 2021 at 6:59
  • 1
    @a_subscriber The reason the subfolders are not being found is most likely because locate hasn't indexed them, so I don't think it's counsel-locate's fault. See my updated answer, as well as man locate and man updatedb.
    – Basil
    Jun 9, 2021 at 12:21

3 Answers 3

2

counsel-locate essentially just calls the system locate command (see man 1 locate).

You can control which executable is called by customising the user option locate-command from the built-in package locate.el.

You can further control the exact command that counsel-locate issues by customising the user option counsel-locate-cmd.

On GNU/Linux, the default command issued by counsel-locate is:

locate -i --regex REGEXP

where REGEXP is the user input interpreted as a regular expression.

So, to find any .txt files under any directory called Temp, you need an input like Temp \.txt\' or Temp.*\.txt\' (note that the literal full stop . has to be escaped, that \' anchors the file extension at the end of the file name, and that Ivy translates the first pattern into something equivalent to the second pattern by default).

To find any .txt files under a specific directory called Temp, you need an input like

\`/home/alexeij/Temp \.txt\'

or

\`/home/alexeij/Temp.*\.txt\'

Where the

\`

anchors the search at the start of the file name.

Finally, to start every counsel-locate search in the current directory, you can write a custom command like the following based on adl's answer:

(defun my-counsel-locate-here ()
  "Start `counsel-locate' anchored at `default-directory'."
  (interactive)
  (counsel-locate (rx bos (literal (file-truename default-directory)) ?\s)))

Then you can issue e.g. M-x my-counsel-locate-here RET \.txt\' to find all .txt files under the current directory.

A more direct (but sometimes slower) way of achieving the same thing is M-x counsel-file-jump RET \.txt\'.

For a fuzzy search analogue, there's also e.g. M-x counsel-fzf RET .txt.


Update

P.S. [adl/counsel-locate-in-the-current-folder-and-subfolders] work only for current folder. But I need to find also in all subfolders.

The locate command usually depends on indexing your filesystem in order to answer queries efficiently. Are you sure the subfolders in question have been indexed already? Usually locate updates its database daily in the background, but you can force it via updatedb.

In any case I think adl/counsel-locate-in-the-current-folder-and-subfolders is working fine (except for the fact that it doesn't quote and anchor regular expressions properly, see the my-counsel-locate-here example), so the problem is most likely a pilot error/misunderstanding.

0

You can use the following function to start counsel-locate already with the current directory in it and an space. Then you could type whatever you want to search there.

(defun adl/counsel-locate-in-the-current-folder-and-subfolders ()
  (interactive)
  (counsel-locate (concat (file-truename default-directory) " ")))
4
  • Try your custom function. Locate: /home/alexeij/Temp/*.txt, but result is "Nothing found" Jun 8, 2021 at 8:42
  • You have to use an space instead of the * /home/alexeij/Temp/ .txt . The function already adds the space after the current directory name.
    – adl
    Jun 9, 2021 at 10:03
  • Not work. I was updated my post Jun 9, 2021 at 12:04
  • 1
    @a_subscriber I've confirmed that it works, so it must be a case of pilot error.
    – Basil
    Jun 11, 2021 at 7:42
0

I prefer this approach:

(defun my-insert-default-directory ()
  "Insert `default-directory' at point."
  (interactive)
  (insert (file-truename default-directory)))

(global-set-key (kbd "C-c C-d") #'my-insert-default-directory) ;; custom function

enter image description here

During M-x counsel-locate, if I press C-c C-d I get the following result:

enter image description here

I do not need the current directory every time. So when I need it I use C-c C-d.

1
  • 1
    Since the input to counsel-locate is interpreted as a regexp by default, I recommend passing the result of file-truename through regexp-quote before inserting it.
    – Basil
    Jun 11, 2021 at 7:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.