3

I switched to Org Mode and Emacs few weeks ago. I find it incredibly better than my previous (simple but effective) setup based on markdown files and VS Code editor.

I'm learning new features everyday but there's one thing from VS Code that I really miss and I can't think how to reproduce it in Emacs:

I'd like to open a specific directory (like /OrgMode) like a "workspace" and then be able to launch a command to find a file in the directory itself. Really simple. In VS Code I used to launch CMD+P (macOS) or CTRL+P (Win) to open a Spotlight-like file search. It was incredibly quick, useful and powerful.

It placed most opened files at the top of the list, updating the order dynamically. But it's OK if I can't reproduce it exactly in Emacs right now. All I want is an effective way to find a file based on my (partial and not necessarily using the beginning part of the filename) keyboard input.

Can you help me?

** Clarifying Edit ** I want to open a directory as the active workspace. Then, I need a command that will ask for my input so that I can quickly open a file within the directory itself.

Example:

  • Directories on my disk: /OrgMode/Projects.org /OrgMode/Todo.org /OrgMode/MonkeyIsland.org

  • Then: M-x command-im-looking-for

  • I type isl
  • A list containing MonkeyIsland.org appears
  • RET visits the file.
  • If you want to recursively search the contents of files in a directory (and subdirectories), M-x rgrep might do what you need – Tyler May 14 at 19:06
  • Thank you for introducing me to rgrep. Very powerful. But I need something quicker and restricted to opening files by filename. I don't need to search the file contents right now. – Marco Sgnaolin May 14 at 20:03
  • It's not clear what you're asking. Do you want to search for files, or just a quick way to select a file in a particular directory to open? – Tyler May 14 at 21:33
  • 1
    C-x C-f will prompt you for a file to open, provides tab-completion to select the file, and starts in your current directory. Is that what you want? – Tyler May 14 at 21:34
  • 2
    C-x C-f is very close to what I'm looking for. – Marco Sgnaolin May 15 at 7:10
6

It sounds like find-file, C-x C-f does what you want. There are more sophisticated options available for this kind of basic operation:

ido-find-file, which is built-in to Emacs. You can see the documentation via C-h f ido-find-file. If you like that, M-x ido-mode will switch C-x C-f from calling find-file to ido-find-file.

counsel-find-file, from the swiper package is similar in general approach, but with more sophisticated options and customizations. Again, you can replace the default behaviour via M-x ivy-mode. It's a bit involved, follow the link to see a detailed description.

helm-find-file, from the helm package is even more powerful, with more options and variations than I can describe here. Check the link.

A quick summary based on my own experience (which may be out of date for things other than counsel-find-file):

  • find-file : limited options but fairly intuitive
  • ido-find-file : like find-file+, intuitive with nicer presentation/selection of file targets
  • counsel-find-file : very powerful & customizable, lots of options, takes a little getting used to
  • helm-find-file : really powerful, lots of options and features, but also takes the most to get used to.

I started with find-file, and moved to ido-find-file. I don't think there's any reason to prefer find-file, ido-find-file is better in my opinion.

Next, I tried helm, which is amazing. However, I found it was a bit too much for my needs, and now prefer counsel-find-file, which I think of as helm-light.

The difference between ido, counsel and helm is a matter of personal preference, they're all very good at what they do.

4

The general answer is find-file(-other-window): C-x C-f (C-x 4 f).

But it helps to use Dired (C-x 4 d) in the directory you want. That sets the default-directory, so C-x C-f looks for files in that directory when you are in that Dired buffer.

You can customize option completion-category-overrides to get the kind(s) of file-name pattern matching you want. For example, you might set it to something like this, to allow for substring, not just prefix, completion when completing file names:

((buffer (styles basic substring partial-completion))
 (file (styles basic substring partial-completion)))

You can also customize option completion-styles for less fine-grained control.

2

See https://github.com/technomancy/find-file-in-project

M-x find-file-in-project-by-selected to find file in project root. Root directory is automatically detected but could also be customized by user.

M-x find-file-in-project-at-point. Try to detect relative/absolute path at point and open the file directly before searching file name in project root. Some user said this command makes ffip "perfect for his needs". https://github.com/technomancy/find-file-in-project/issues/97

C-u N M-x find-file-in-current-directory find file in current directory if N is zero or else find in Nth parent directory.

You can also interactively filter the candidates. For example, org !Monkey OrgMode/ lists *.org but exclude file whose name contains Money or file in OrgMode/ directory.

1

Use helm-find-files to dynamically narrow search results while typing.

Important: The helm package will need to be installed into emacs for this answer.
For Spacemacs use these instructions to install the helm layer.

After you have installed helm, please continue with answer.

  1. Type M-x helm-find-files RET.

    You should see the following:

    • The minibuffer will display Find files or url: prompt with the current directory path.

      E.g.

      Find files or url: /OrgMode/
      
    • In addition, helm will open new *helm find files* buffer containing a list of files in the current directory.

      /OrgMode/.
      /OrgMode/..
      MonkeyIsland.org
      Projects.org
      Todo.org
      
  2. Type isl and the *helm find files* should dynamically narrow search results to display

    [?] isl
    MonkeyIsland.org
    

    Note: MonkeyIsland.org should be highlighted in this example.

  3. Press RET key and the highlighted filename will open.

    Let's imagine that you wanted to filter the list of files to names containing the letter e instead.

    [?] e  
    MonkeyIsland.org
    Projects.org
    

    If your filtered results contain multiple lines use the up arrow or down arrow keys to highlight the filename you want.


Thanks for asking a great question! Thanks to @Tyler for inspiring this answer. ~ Melioratus


This answer was tested using:
emacs version: GNU Emacs 25.2.1

  • Thank you for the great answer :-) – Marco Sgnaolin Jun 18 at 17:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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