Emacs: what are good tactics for navigating directories and opening files?
Asked Answered
A

6

30

Last week, infuriated (again) by having to cope with different IDEs for R and Perl, neither of which I like or use enough to get really comfortable in, I decided to try Emacs. This decision was not made without a certain trepidation on my part. My main use is for Perl with cperl and for R with ESS. My environment is Windows 7 Ultimate 64-bit and I am running v23.4.1, which I think is what the ESS package installed on my behalf.

Nearly a week in and so far it has been surprisingly painless, no more involved than any other significant piece of software. I have remapped my ctrl key to caps-lock, changed default folders, messed around with .emacs and made some additions such as auto-install, yasnippet, color-theme, icicles and a few others. Clearly there is some very sophisticated stuff out there. In addition of course certain features of base Emacs are immediately very powerful and useful, such as isearching up and down. On the whole I have been pleasantly surprised and reassured.

One thing that is cruder than I was expecting is the process of finding and opening files. After a cursory read of various tutorials I had this image of quasi-magical file location and filename auto-completion. The main directories in my setup have paths like g:/roaming/code/perl or g:/roaming/code/R/ but I often need to branch into completely different paths like g:/pricedata/support files/sector/project01/ and so on.

Currently I laboriously delete the file path when I need to take a different fork, then use auto-complete to move deeper into that branch of the filesystem. It kinda takes me back to running a bash shell on the Amiga twenty years ago.

What had I expected? Something like (using the above example) typing 'project01' to skip immediately into the folder at the bottom of the path. For some reason I had got the idea in my head that Emacs would preload directories. So maybe this wasn't realistic.

My guess is that my difficulties probably stem from my own lack of familiarity rather than a structural shortcoming in Emacs and leads on to my questions. I can't complain that there is not enough documentation; rather there is abundant information that it is scattered around rather haphazardly. Icicles has a similar problem - if anything there's too much.

1) What is the best tactic for moving around different branches of the file tree when trying to open files in the minibuffer or using some other method? Are there aliases that can be used to shortcut from one place to another or can one specify directories to be preloaded? Do people just cd around a lot? Or am I coming at this from completely the wrong angle and need to adopt a different strategy?

2) With additional setup, can auto-complete be used to find files in (say) the project01 directly above by prefixing with wildcards etc? What should I focus on to become more efficient here? Am I not tapping the power of add-ons like icicles, anything etc?

I realise these questions veer dangerously close the deprecated category of not having clear answers. My defence is that some tips/guidance at this stage before I commit myself to bad habits or a poor long-term solution would be welcome and I suspect the answers will benefit others who might be considering the switch. I am happy to withdraw or rephrase if there are problems.

Alanaalanah answered 22/2, 2012 at 14:44 Comment(0)
K
8

There are various approaches. File name cache is a built in solution. Opening files from recent files is also very effective, especially if you set the stored files to a high number (e.g. 1000). There are also packages for opening files from anywhere on the file system. And there are meta solutions like anything.el which can show you file completions from multiple sources (history, project files, etc.) in a common interface.

You should investigate the different options to find out which is the most suitable for you.

Kornegay answered 22/2, 2012 at 15:18 Comment(1)
Nice concise summary putting base Emacs functionality first, complete with links - thank you. I have looked into and enabled file name cache and recent files.Alanaalanah
C
13

helm (formerly known as anything) might suit you. You can install it manually, or using a auto-install extension.

For the auto-install way: download it, put in Your load-path, then add to .emacs:

(add-to-list 'load-path "~/.emacs.d/site-lisp/auto-install")
(require 'auto-install)
(setq auto-install-directory "~/.emacs.d/site-lisp/auto-install/")

Then do M-x auto-install-batch anything. After that is done, put in .emacs:

(require 'anything)
(require 'anything-match-plugin)
(require 'anything-config)
(require 'anything-show-completion)

Then do M-x anything for anything.

Also give a try to ECB (stands for Emacs Code Browser). If you're on Linux, you probably have it available in a standard repository.

Cabinetwork answered 22/2, 2012 at 15:19 Comment(5)
auto-install seems interesting, but not actually a requirement here (i.e. there are other ways to obtain and install anything).Gerbil
@phils: Quite right, I've just reproduced the way I set it up. I'll put the auto-install part at the end of my answer.Cabinetwork
Anything is amazing. Not sure how easy it is for an end-user to get going in it, but as a coder, using it is pure bliss. ;) It's far superior to ido or my uses. Also, the maintainer is very friendly and responsive in the Google groups "emacs-anything". I highly recommend you give it a shot.Avery
+1. Appreciate the step-by-step and also for the mention of ECB, which I shall look into as soon as I get a moment. I tend to agree with the developers that base Emacs isn't so great at browsing files.Alanaalanah
@Alanaalanah check out projectile and helm-projectile, described in this excellent guide.Blouse
F
9

You could benefit from using ido-mode, which greatly enhances autocompletion nearly everywhere in emacs (especially when finding files or buffers)

(setq ido-enable-flex-matching t
      ido-auto-merge-work-directories-length -1
      ido-create-new-buffer 'always
      ido-use-filename-at-point 'guess
      ido-everywhere t
      ido-default-buffer-method 'selected-window)
(ido-mode 1)
(put 'ido-exit-minibuffer 'disabled nil)
(when (require 'ido-ubiquitous nil t)
  (ido-ubiquitous-mode 1))

While this might help you quickly finding files "not far away", it probably won't help you much finding files in entirely different locations.

If find that one way to begin tackling this problem is using recentf-mode to quickly jump to recent locations (if you have only a small number of usual project directories, this might do the trick). recentf can be coupled with ido using something like this (I'm not sure where I got this snippet from):

(recentf-mode 1)
(setq recentf-max-saved-items 50)
(defun ido-recentf-open ()
  "Use `ido-completing-read' to \\[find-file] a recent file"
  (interactive)
  (if (find-file (ido-completing-read "Find recent file: " recentf-list))
      (message "Opening file...")
    (message "Aborting")))
(global-set-key (kbd "C-x C-r") 'ido-recentf-open)

With this, you can use C-x C-f (ido-find-file) to look for files near you current location, and C-x C-r (ido-recentf-open) to look for recently opened files (hoping one of them is not too far away from where you want to go).

Faludi answered 22/2, 2012 at 15:11 Comment(3)
+1. Very useful. I have switched on ido and am now using it - seems neat. I'm grateful for the elisp above though I was temporarily stalled by require-or-install and install-elisp on which it depends. At this point I still don't know enough to distinguish core Emacs from add-ons, but I got there in the end.Alanaalanah
@Alanaalanah Sorry, require-or-install is a custom function I wrote to install the modes I need when I first start emacs on a new computer. I removed all mentions to it and the above snippets should now be standard core emacs.Madge
Would be nice to mention ido virtual buffers in this answer.Epicedium
K
8

There are various approaches. File name cache is a built in solution. Opening files from recent files is also very effective, especially if you set the stored files to a high number (e.g. 1000). There are also packages for opening files from anywhere on the file system. And there are meta solutions like anything.el which can show you file completions from multiple sources (history, project files, etc.) in a common interface.

You should investigate the different options to find out which is the most suitable for you.

Kornegay answered 22/2, 2012 at 15:18 Comment(1)
Nice concise summary putting base Emacs functionality first, complete with links - thank you. I have looked into and enabled file name cache and recent files.Alanaalanah
D
7

In addition to IDO and recetf you can use the following methods:

  1. Open the directory recursively.

    (defun op-i:dired (rec)
      "customized dired: will display directory recursively when called with an argument"
      (interactive "P")
      (let ((dir (car (find-file-read-args "Dired: " nil))) 
            (opts (if rec (read-string "options: " "-lhAR") "-lhA")))
        (if (file-directory-p dir) (dired dir opts))))
    
    (define-key (current-global-map) (kbd "C-x C-d") 'op-i:dired)
    

    Then you can navigate in the directory buffer as in any other buffer using a (wildcard) search.

  2. Use Emacs registers to point to often used directories. You can initialize them in your .emacs

    (set-register ?0 (cons 'file "c:/path/to/my-project0"))
    (set-register ?1 (cons 'file "c:/path/to/my-project1"))
    

    Then jump to register using C-x r j

Debauchee answered 22/2, 2012 at 15:12 Comment(0)
A
6

Other people have already mentioned anything, suffice it to say, I believe it solves all your problems. :)

Calling out one specific feature of anything is anything-locate. On *nix systems, this uses the DB created by the locate command to quickly find files. On Windows, I believe it works with "Everything", which should give you near instantaneous search results across all your files. I mean all.

Tom has mentioned file-cache. Anything works with that.

Just as a side note, Dired is an absolute monster once you get used to it. You should read the emacswiki pages related to it. In particular dired-x, which comes with Emacs binds C-x C-j, jumps to current buffer in Dired was a revelation for me. Also dired-find, wdired.

Edit: some details on why C-x C-j is awesome.

When you pop the current buffer in a Dired buffer, you can modify it, i.e. rename, delete, etc. And Emacs is aware of what you've done, and adjusts accordingly.

Avery answered 22/2, 2012 at 16:49 Comment(1)
anything was renamed to helm, I believeEpicedium
D
5

Other possibilities:

  1. Bookmarks. If you use Bookmark+ then you can also:

    • Bookmark Dired buffers, which remembers their inserted subdirs, their markings, and their file omissions. You can have a bookmark that opens Dired to a specific set of files that need not be in the same directory or even the same directory tree.

    • From Dired you can hit a key to create a separate bookmark to each marked file or subdir.

    • Bookmark files automatically (autofiles).

    • Tag bookmarks and files (autofile bookmarks) with arbitrary-text tags. (Tags can even be non-text Lisp objects). Use tags to organize, search, etc. different categories of bookmarks.

    • Bookmark sets of bookmarks or bookmark files or Emacs desktops. Jump to such a bookmark to restore a given project state/context.

  2. Icicles.

    • Define temporary or persistent sets of files on the fly, even from different directories. Operate on the files in a set in various ways. (Use Emacs filesets, less powerful, the same way.) Complete against file names from such saved sets during any completion command, not just file-finding.

    • Act in different ways on candidate files during completion.

    • Search bookmarked objects or saved sets of files or buffers.

  3. Dired+.

    • Additional navigation, including i bouncing between a subdirectory listing and the subdirectory's line in the parent listing.

Refs:

Declinate answered 11/8, 2013 at 23:36 Comment(2)
More than two years after I asked this question I find that I use bookmarks and bookmarks+ every time I use Emacs, so ultimately this has proven to be the right solution for me.Alanaalanah
If it is really the right solution for you, and if that also means it is the best answer for your question here (that doesn't necessarily follow), you can, if you want, change the accepted answer.Declinate

© 2022 - 2024 — McMap. All rights reserved.