5

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.
Drew
  • 75,699
  • 9
  • 109
  • 225
Marco Sgnaolin
  • 151
  • 1
  • 4
  • 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 '19 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 '19 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 '19 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 '19 at 21:34
  • Have you discovered `dired`? I use it all the time and it might help – mikado May 14 '19 at 21:37
  • The question is unclear. Please edit it to clear up the confusion. Apparently you are not searching files (their content); you are only interested in finding files whose names match some pattern (?). And are you interested only in the files in a directory or also the files in its subdirectories? If the latter, all subdirectories or just some whose names match some pattern? Lots of possible questions - it's impossible to know what your question is. – Drew May 14 '19 at 22:10
  • 2
    C-x C-f is very close to what I'm looking for. – Marco Sgnaolin May 15 '19 at 07:10
  • `counsel-find-file`, from this repo https://github.com/abo-abo/swiper `ido-find-file` (ships with emacs) will be probably even closer to what you are looking for – andrej May 15 '19 at 12:44
  • This sounds like the "global default directory" type problem I had. What I do is set the an Emacs-wide default directory which functions like a project. I then open all the files in the directory using `dired` (I actually use a custom function). Switching files then becomes a matter of switching buffers with `C-x C-b`. Let me know if this is what you want and I can post a more detailed answer. https://emacs.stackexchange.com/questions/44759/set-a-global-default-directory There is also `projectile` which may meet your needs. – Lorem Ipsum May 15 '19 at 16:21

4 Answers4

7

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.

Tyler
  • 21,719
  • 1
  • 52
  • 92
  • I was trying to use https://github.com/minad/consult but when I have its configuration along with (having `icy-mode`)`ido-find-file`, it does not work properly. Is it a normal behavior in emacs? – alper Aug 13 '21 at 12:23
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.

Drew
  • 75,699
  • 9
  • 109
  • 225
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.

chen bin
  • 4,781
  • 18
  • 36
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

Melioratus
  • 4,504
  • 1
  • 25
  • 43