How do I find-file recursively in directories - emacs

Often, I know the file name but don't remember or find it cumbersome to specify the exactly directory. I'd like to be able to do:
find-file x/y/*/some_file.txt
where * would allow searching in recursive directories instead of just the current one.

As described here:
M-x find-name-dired
After you provide the directory and the pattern the matching files will be displayed in a Dired buffer. You can navigate the file list (C-n, C-p, etc.) and open files as you wish (Ret).

I've long looked for that feature and I'm now satisfied with what I found: I'm using helm-projectile.
Projectile is a project interaction library. Projects are VCS directories or directories containing a .projectile file. It is based on GNU find (but offers a pure emacs lisp implementation too)
https://github.com/bbatsov/projectile
(you can install it with packages.el). You can use it alone: call projectile-find-file (or projectile-mode and C-c p f). It uses ido for the completion by default, but in that case I prefer the interface of helm-projectile.
My colleagues kept telling me to use Sublime Text because of that feature. Fortunately, I found projectile :)

ido-find-file does this: when the filename that you enter doesn't match
anything in the current directory, it uses something like locate to match
what you wrote against all files on your system.
The setup is just one line:
(ido-mode)
After this, C-x C-f will call ido-find-file.
Also, I usually add:
(setq ido-enable-flex-matching t)
because I like it, but with it you will locate more results,
i.e. foo will also match froo.

In case of files in a project directory, I have used Fiplr that uses a fuzzy search library by the same author.
https://github.com/d11wtq/fiplr
This is available from MELPA.
Other solution that I haven't tried is https://github.com/technomancy/find-file-in-project

edit: I found much better with projectile, see my other answer.
There is find-recursive.el : http://www.webweavertech.com/ovidiu/emacs/find-recursive.txt
Download it, put it in your load path and require it in your .emacs: (it isn't available through ELPA or el-get)
(require 'find-recursive)
now when you call M-x find-recursive, it will ask for a file name to search for recursively, a base directory, then you have to select one file among a result list. It isn't integrated into ido unfortunately, but I like it, it is useful sometimes.

Here is a solution that gives you selectivity over the files and subdirectories searched. To use it you need both Dired+ and Icicles.
The command, used only in Dired, is icicle-visit-marked-file-of-content-recursive (or the -other-window version of it). It is bound to M-+ C-F (for other window, use M-+ C-O -- and yes, those are uppercase F and O).
What it does:
It provides, as candidates for completion, all of the files marked in the current Dired directory, pslus all of those in any marked subdirectories that have Dired buffers, and so on recursively.
You can visit any number of such candidates that match your minibuffer input, including all of them. You can visit some that match a minibuffer input pattern, then change the pattern to match and visit others --- all in the same command invocation.
"Matching" your input can mean either or both:
Matching the file name
Matching the file content
That is, your input can be two-part (separated by hitting C-M-j: a file-name part and a file-content part. Narrow the choices by matching file names, and narrow further by matching text in those files. This search is fast -- it succeeds as soon as it finds a single match in the file.
You can omit either part: match only file names (fast) or only file contents (slower, naturally).
You can combine input patterns -- progressive completion. It is much easier to add additional patterns to match, incrementally and interactively, than it is to try to come up with a single regexp that does just what you want.
Each input pattern (each part of a two-part pattern) can be a regexp. Fuzzy matching is also available.
You can alternatively just insert subdirectories in your Dired buffer, instead of having them as separate Dired buffers. Any files and subdirs marked in a Dired buffer are handled the same way.
If you do not want to descend into subdirs that are marked, you can use the non-recursive version of the command, icicle-visit-marked-file-of-content, bound to C-F (C-O for other-window).
If you also use Bookmark+ then you can bookmark a Dired buffer or a set of Dired buffers. The bookmark records which files and subdirectories are marked, which subdirectories are inserted, and which files and subdirectories are omitted. Jumping to such a bookmark restores all of these things. This gives you a way to snapshot a project, which you can then search using M-+ C-F etc.

A lot of options listed, I'm using next command:
find-file-in-current-directory
You can put it in your .emacs like this:
;; Find file in current directory:
(global-set-key (kbd "C-M-,") 'find-file-in-current-directory)
Interface looks very familiar to those who use fsf tools (https://github.com/junegunn/fzf)

If you have helm, you can use this:
(defun my/helm-find-file-recursively ()
"Recursively find files in glob manner, in the specified directory."
(interactive)
(helm-find 'ask-for-dir))
(global-set-key (kbd "C-c o f") 'my/helm-find-file-recursively)

Icicles command icicle-locate (or icicle-locate-file, if you do not have a locate program for your OS) is made for that. Locate a file anywhere under a given directory (including ~HOME or the root directory).
You can match against any parts of the absolute file name (i.e., the path and the file name). You can use several kinds of matching, including regexp, substring, and fuzzy matching.

For a more programmatic approach (using the built-in files library):
(directory-files-recursively "~/assignments/" "[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.org")
;; ("~/assignments/a/b/2022-05-18.org"
;; "~/assignments/c/d/2022-07-15.org"
;; "~/assignments/e/f/2022-08-08.org")
Here's a thin wrapper around that function which reads a filename from the minibuffer and returns a list of matching directories (starting from the current directory), from which you select an entry which will then be visited:
(defun my/find-directory ()
"Find the directory containing FILE."
(interactive)
(let ((matches (directory-files-recursively default-directory (read-from-minibuffer "Filename: "))))
(if matches
(find-file
(completing-read
"Pick a directory: "
(mapcar 'file-name-directory matches))))
(message "No matching directories.")))

Related

How do I find org-mode files with completion in Emacs?

I have a growing set of org files stored in org-directory. How can I navigate between them, preferably with interactive filtering and completion?
I thought there was a way to get org-mode to produce a list of known org files for quick navigation, but I can't seem to find it. If org-mode does not have this feature, how can I make a simple command that launches something like helm or icicles to find them?
The question is not very clear to me. But if your Org-mode files all have a certain file-name pattern (e.g. *.org) and all are in the same directory (org-directory) then you can use several methods Emacs method to access them:
C-x C-f *.org RETURN in org-directory opens them all (the buffers are visiting them but only the last one is shown).
C-x C-f *.org TAB in org-directory, to show them using completion, then pick whichever one you want (or pick more than one, using a glob pattern, as in #1).
The same as #2, using Icicles or Helm. In Icicles, at least, you can also match using regexps and in other ways.
Open Dired for just those files: C-x d *.org.
There are really any number of ways to do what you've described. But I'm guessing that you have not really described your request/problem/question well enough, and when you do you will get a narrower set of answers.
UPDATE after your comments:
Here's one way: Open Dired on all of your Org files in and under org-directory.
(defun foo ()
"Open Dired for (only) the Org files in and under `org-directory`."
(interactive)
(cd org-directory)
(dired "*.org" "-lRF"))
Test it with M-x foo. Put this in your init file:
(foo)
And here's another way: M-x bar or bind bar to a key.
(defun bar ()
"Open an Org file in or under `org-directory`."
(interactive)
(let ((default-directory org-directory)
(icicle-file-match-regexp ".*\\.org"))
(icicle-locate-file-of-content)))
I have a package that does just that: plain-org-wiki.
It's nothing too elaborate: I just dump all of my 45 org files into a single directory and get completion for them.
How about org-iswitchb, which is provided by org already?
Switch between Org buffers.
With one prefix argument, restrict available buffers to files.
With two prefix arguments, restrict available buffers to agenda files.
Add this to your startup file after org is loaded:
(global-set-key "\C-cb" 'org-iswitchb)
My favorite solution to this is helm-mode which is activated with the helm package from MELPA. Here's a demo:
It really makes for a great environment for searching ones files quickly. In addition, one can enable fuzzy completion! Here's a minimal configuration (after installing the helm package):
(require 'helm-config)
(helm-mode 1)
(global-set-key (kbd "C-x C-f") 'helm-find-files)
You can also run grep on the files if you'd like to search their content. Take a look at this amazing guide if you'd like to learn more.

How to go to a file quickly in Emacs Dired?

If a directory contains many files and I want to go to files(or subdirectories) with name starting with a letter (or a string), is there any good way to do it? I know in Far File Manager people can press Alt and start typing the name and the cursor will move as you type, I am wondering if Emacs has something similar.
The fastest way to answer this question is copying a section from the emacs info files.
To get to this text type C-h i d m emacs ret and then isearch for an appropriate substring ignoring the first Failing I-search or just go to info with C-h i and then directly go to the info node mentioned below with g and then typing the node name followed by ret.
The first from the info-node (emacs) Dired and Find works whether one is in a dired buffer or not:
To search for files with names matching a wildcard pattern use `M-x
find-name-dired'. It reads arguments DIRECTORY and PATTERN, and
chooses all the files in DIRECTORY or its subdirectories whose
individual names match PATTERN.
The second from the info-node (emacs) Dired Navigation works in dired buffers but only applies to the currently listed files. But, note that you can list subdirectories with i before.
`M-s f C-s' (`dired-isearch-filenames') performs a forward
incremental search in the Dired buffer, looking for matches only
amongst the file names and ignoring the rest of the text in the buffer.
`M-s f M-C-s' (`dired-isearch-filenames-regexp') does the same, using a
regular expression search. If you change the variable
`dired-isearch-filenames' to `t', then the usual search commands also
limit themselves to the file names; for instance, `C-s' behaves like
`M-s f C-s'. If the value is `dwim', then search commands match the
file names only when point was on a file name initially. *Note
Search::, for information about incremental search.
EDIT:
To isearch a directory recursively you may first list it recursively.
You can list sub-directories recursively by calling dired with prefix-arg and adding R to the list of switches.
The following snippet for the emacs initialization file would even simplify this task:
(defun dired-noselect-maybe-recursive (dir-or-list &optional switches)
"Like `dired-noselect' but lists sub-directories when last character is ?/."
(if (and (null switches)
(= (aref dir-or-list (1- (length dir-or-list))) ?/))
(dired-noselect dir-or-list "-alR")
(dired-noselect dir-or-list switches)
))
(setq find-directory-functions (subst 'dired-noselect-maybe-recursive 'dired-noselect find-directory-functions))
With this snippet you get a normal listing of directories if you call find-file (C-x C-f) for a directory without a slash at the end and you get a recursive listing if you call it with a slash at the end.
But be careful. Recursive directory listing can take its time. If you get nervous you can always quit with C-g.
isearch will do that. control-s, then start typing.
Since it's emacs' general-purpose search function, it could start out matching other things in the buffer until you get enough of the name in.
I just want to add a trick that I like to use that's
somewhat related to your question:
(add-hook
'dired-mode-hook
(lambda()
(define-key dired-mode-map "j" 'ido-find-file)))
Obviously it works for just one file, and it opens it, instead
of offering a multitude of things that dired can do to a file,
but at least it's fast.
#Tobias and #jl8e have both answered your question directly: use C-s (incremental search). Nothing to add to that.
But if you are going to be using a subset of the listed files multiple times, or you are going to perform the same operation on a subset of the files, and if that subset can be identified by a file-name pattern (e.g. same prefix), then you can use %m to mark all files matching a regexp. Once marked, you can do all kinds of things on the set of files marked (or on the set of those unmarked).
(One of the things you can do is just omit the marked or unmarked file names from the listing, and hence from operations.)
Dired is really mostly about examining and operating on sets of files. The singleton set is a special case, and all operations (keys) that operate on the marked files also operate on the current line's file only, if none are marked.

recursively remove subdir from emacs dired

I often look at dired structures, showing the entire directory recursively, via: (dired dir "-lR"). This works great most of the time.
However, some times, there are huge sub-directory structures that Idon't want to look at. Is there a way to recursively kill a subdirectory in a dired buffer with a complete tree in it?
I use find-dired for the same purpose. To exclude a subdirectory, I enter something like this at the Run find (with args): prompt: -path ./exclude_me -prune -o true, which will give me a recursive listing of the directory excluding the one directory exclude_me. This only works if you're using a Unix-like with a function version of find though.
Edit: Another way to remove the tree is to simply toggle the dired buffer to readable (C-x C-q) and edit the buffer.
Ok, I just wrote the following elisp:
(defun bp-kill-directory-rec()
(interactive )
(let (
(i (point))
(cur-dir (dired-current-directory)))
(beginning-of-buffer)
(while (search-forward cur-dir nil t)
(dired-kill-subdir))
(goto-char i)))
Start with the cursor in the directory that you want to kill, and it will kill all subdirs of that directory. The trick is that (dired-current-directory) gives the entire path, so searching for that should only give the directories you want to kill. If you have a directory structure, where you have something like /home/a/b and also /home/c/d/home/a/b then bad things could happen. But you'd have to be kind of crazy to do that, no?
Use Dired+, command diredp-kill-this-tree.
Just put the cursor in a subdir that you want to remove from the listing, and invoke the command. That inserted subdir and all its descendents that are also inserted (listed) are removed.
You can invoke this command also in either of these ways, after putting point within a subdir listing:
Click mouse-3 and choose item Remove This Inserted Subdir and Lower.
Choose menu-bar menu Single (called Immediate in vanilla Emacs), item Remove This Inserted Subdir and Lower.

Emacs navigation between files with same names

I've long been a fan of GNU Emacs' file navigation model. I've been switching buffers with C-x C-f ..., C-x b; C-mouse-1 occasionally.
However, recently I've been finding myself programming on projects that have sets of several files with the same names, but in different directories, along these lines:
package/message.py
package/message.zcml
package/ui/message.py
package/ui/message.zcml
package/ui2/message.py
package/ui2/message.zcml
In these circumstances my usual buffer switching tools are not very efficient. It's hard to remember whether the file I want is in the buffer message.py<2> or message.py<3>, and it's pretty fussy to switch between them with C-x b. What I would like, perhaps, is something like tab bar or a menu where I could arrange the files I'm working on and have them maintain their spatial arrangement, so that I could quickly switch beetween them. I briefly looked at speedbar and tabbar-mode, but didn't find much help. Any suggestions?
I found this solution from Borbus:
https://stackoverflow.com/a/845311/552421
;; uniquify changes conflicting buffer names from file<2> etc
(require 'uniquify)
(setq uniquify-buffer-name-style 'reverse)
(setq uniquify-separator "/")
(setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified
(setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers
From your example, your buffers would be named "message.py|ui", "message.py|ui2", etc...
Along with using uniquify to obtain more helpful buffer names, you might want to look into using ibuffer groups for your "spatial arrangement" needs. You can create named groups based on sets of filters, and you can filter on file path(*), so you could easily have separate groups for each of those directories.
I highly recommend binding C-xC-b to ibuffer as a replacement for the default.
Aside from that, if you use ido-mode in conjunction with the uniquify config, then when you type C-xb to switch buffers, you can type and match against any part of the (uniquified) buffer name. If you enable ido-enable-flex-matching (or alternatively, use something like LustyExplorer instead) then you can type unconnected parts of that buffer name, and the fuzzy matching will narrow the list intelligently (e.g. typing "mez2" might be enough to isolate "message.zcml|ui2").
(*) Personally I prefer ibuffer to match dired buffers as well as file buffers when I make a filename filter, so I redefine that filter accordingly:
;; Enable ibuffer-filter-by-filename to filter on directory names too.
(eval-after-load "ibuf-ext"
'(define-ibuffer-filter filename
"Toggle current view to buffers with file or directory name matching QUALIFIER."
(:description "filename"
:reader (read-from-minibuffer "Filter by file/directory name (regexp): "))
(ibuffer-awhen (or (buffer-local-value 'buffer-file-name buf)
(buffer-local-value 'dired-directory buf))
(string-match qualifier it))))
You can rename the buffer without changing the file it is attached to. M-x rename-buffer <ret> new-buffer-name <ret>. After that, you can bounce back and forth using the more convenient buffer names, but when you save any changes they go to the actual files associated with each buffer.
In your case, you might rename your message.py<n> files to ui-message, ui2-message and base-message. Those will be easier to navigate to (and remember which files they belong to) with C-x b.

Don't show uninteresting files in Emacs completion window

How do I prevent Emacs from showing me all the files I'm not interested in (such as ~ backup files, .pyc files, or .orig files) when I: C-x C-f TAB ?
It is working in one respect: if I know the file I want to open begins with foo and I type foo TAB then the mini-buffer correctly autocompletes all the way to foo.py. It correctly ignored foo~ and foo.pyc, because both ~ and .pyc are in completion-ignored-extensions. It also correctly lets me open either ignored file if I really want to by typing in all the letters my self.
However, if I just hit TAB to to bring up the completion list buffer then that list includes files with extensions in completion-ignored-extensions, which makes it very difficult to find what I'm looking for.
Clearly the code to ignore uninteresting files is there and working. How do I get the completion list buffer to respect completion-ignored-extensions?
(by-the-by, can I make dired behave similarly?)
This piece of advice filters out files with extensions listed in 'completion-ignored-extensions:
(defadvice completion--file-name-table (after
ignoring-backups-f-n-completion
activate)
"Filter out results when they match `completion-ignored-extensions'."
(let ((res ad-return-value))
(if (and (listp res)
(stringp (car res))
(cdr res)) ; length > 1, don't ignore sole match
(setq ad-return-value
(completion-pcm--filename-try-filter res)))))
Note: This doesn't affect dired.
For the dired issue, add this to your .emacs
(eval-after-load "dired"
'(require 'dired-x))
(add-hook 'dired-mode-hook
(lambda ()
(dired-omit-mode 1)))
Read the documentation for dired-x to get an idea of what's available there.
I would recommend using ido-mode to ignore files; it comes with Emacs by default and adds many other useful enhancements that you'll quickly learn to love. The Ignorance is Bliss section from this Mastering Emacs blog post covers how to ignore files, directories, and buffers:
ido-ignore-buffers Takes a list of buffers to ignore in C-x b
ido-ignore-directories Takes a list of directories to ignore in C-x d and C-x C-f
ido-ignore-files Takes a list of files to ignore in C-x C-f
Icicles does what you expect by default. It always respects completion-ignored-extensions for file-name completion, including for buffer *Completions*. And you can toggle this ignoring on/off at anytime, by hitting C-. in the minibuffer.
In addition, if you use library completion-ignored-build.el by Kevin Ryde, then Icicles automatically takes advantage of that library's dynamic adjustment of ignored file extensions. (Just load completion-ignored-build.el -- do not enable its minor mode or advice.)
I don't know of an answer for completion, I'm afraid. I think this is by design - when you know the name you're looking for, you probably don't want e.g. the backup file. But when you don't know, it's probably better to have a list of all of the files.
However, for dired, you can load the 'dired-x' package on startup (in your .emacs), and this provides dired-omit-mode:
(load "dired-x")
You can use 'M-x customize-variable<RET>dired-omit-files' to set the actual patterns to ignore. Then when you are in dired mode you can use M-O (the letter, not the number) to toggle 'omission' on and off.