How to omit certain folders on ido-switch-buffers and ido-dired? - emacs

I would like to ignore certain folders turning up via ido-dired when changing buffers in Emacs. These folders are system folders on a Mac and should not be removed otherwise, so at least I would like to hide them (especially annoying is, for example, ~/Documents which is suggested when one wants to change to ~/Downloads and thus starts to type Do...).
To this end, I found ido-ignore-directories and I used the following line in .emacs to omit these folders:
(setq ido-ignore-directories (quote ("~/Applications" "~/Documents" "~/Library" "~/Movies" "~/Music" "~/Pictures" "~/Public")))
The problem is, that they are still suggested when I use ido-dired.
How can the folders be hidden on ido-dired?
Update
When setting ido-ignore-directories as suggested by npostavs, the folder still appear:

To this end, I found ido-ignore-directories and I used the following line in .emacs to omit these folders:
(setq ido-ignore-directories (quote ("~/Applications" "~/Documents" "~/Library" "~/Movies" "~/Music" "~/Pictures" "~/Public")))
ido-ignore-directories is the correct variable, but it matches just the directory name itself, not the full path.
(setq ido-ignore-directories
'("Applications/" "Documents/" "Library/" "Movies/" "Music/" "Pictures/" "Public/"))

Related

Does .emacs.d belong to load-path?

My .emacs.d/ contains the file load-directory.el, which, as its name suggests, provides the function load-directory (and, yes, it contains the statement (provide 'load-directory) too). I'd like load it at startup time, but the statement (require 'load-directory) returns this error:
File error: Cannot open load file, load-directory
What's wrong?
Thanks in advance.
Use a sub-directory for your custom Lisp extensions, e.g. ~/.emacs.d/lisp/, and add this directory to load-path:
(add-to-list 'load-path (locate-user-emacs-file "lisp/"))
Do not add ~/.emacs.d/ to your load-path. For details, see Disable warning about emacs.d in load path
No, .emacs.d does not belong into the load-path.
From the docstring:
Directory beneath which additional per-user Emacs-specific files are
placed. Various programs in Emacs store information in this directory.
So this is a directory to which files are automatically written. It should therefore not contain your own files. Which means, if you add it to your load-path, you are probably doing something wrong.
The warning is a bit misleading. AFAICT, the problem is not the load-path per se, but that you do not want your own lisp files in that directory, because they could be overwritten.
It looks like load-directory.el is not in your load path. If it's it your .emacs.d, add it via:
(add-to-list 'load-path "path/to/.emacs.d") ; note: no trailing /
If load-directory.el itself holds all your load-path customizations, you can use the second, optional parameter of require to tell it which file name to use:
(require 'load-directory "path/to/directory/load-directory") ; note: no file extension needed
(And just in case: it should be (provide 'load-directory) and not (provides ...) in that file.)

How do I find-file recursively in directories

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.")))

Permanently add to emacs load path

I am trying to add "~/" to the emacs load path, because for whatever reason it is not there. I managed to find the command for adding to the emacs load path:
(add-to-list 'load-path "~/")
When I execute this command the load-path variable contains all the stuff it did before, and "~/" is added to the list. The problem is when I quit emacs, the next time it starts the "~/" had been removed from the list, the change is not persistent. How do I add something to the emacs load-path variable permanently?
Adding to the .emacs file won't work here, because the problem is that the .emacs file, which is in the ~/ directory, is not being loaded, so modifying the .emacs file won't fix this problem.
I guess there is a typo in phils' comment. The right way should be C-h v user-init-file RET. Maybe you customized this variable in some other places and you forgot. Try changing the value of this variable back to the default.

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.

What's the best way to handle multiple like-named files in emacs?

One problem that I have with emacs is that it doesn't seem to handle like-named files in different directories very well. For example, if I'm not careful, I'll end up with 20 __init__.py buffers open. What I've been doing is using M-x rename-buffer and renaming it to indicate what package it's within. However, doing this manually is somewhat tedious.
Does anyone have any strategies for attacking this problem?
I like uniquify, which comes with Emacs:
(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 (or Gnus mail buffers)
With those settings, the directory gets added to the buffer name, giving you an indication of where the file is. For example, loading the files /some/path/to/Makefile and /some/path/to/different/Makefile would result in the following buffer names:
Makefile/to (which is /some/path/to/Makefile)
and
Makefile/different (which is /some/path/to/different/Makefile)
uniquify also handles updating the buffer names when buffers are deleted, so when one of the two Makefile buffers is deleted, the other gets renamed to simply Makefile.
If you want full control you can redefine create-file-buffer.
If you want the full filename it could be as simple as
(defun create-file-buffer (filename)
"Create a suitably named buffer for visiting FILENAME, and return it."
(generate-new-buffer filename))
See files.el for reference.