What's the best Find in File mode for EMACS? - emacs

What's the best package for finding a string in multiple files in EMACS. I know about grep and such but I would like something that is a little smoother to operate.

There are three builtin functions for grepping in Emacs: grep, find-grep (or grep-find) and rgrep.
The first two work by letting the user edit the grep command line directly.
I usually use the third, rgrep, from "recursive grep". It's a little friendlier, as it prompts the user for the search parameters (search string, file types and directory) one by one, provides customizable defaults, and it automatically ignores some common files and directories you usually don't want to search, like for example .svn or .o files.
Then, there is ack, and its interface for Emacs: ack.el, whose default behavior is similar to rgrep, but can be customized to use the options that ack provides.

Just in case you haven't read it already - there's lots of relevant tips over at the EmacsWiki GrepMode page.

Dired mode also lets you do a search through marked files with the dired-do-search function.
And ibuffer lets you do emacs' generic isearch through a bunch of buffers using the awkward key sequence M-s a C-s.

As an alternative, I find dired-modehelpful, especially when used with either dired-mark-files-regexp (%m) or dired-mark-files-containing-regexp to select what should be searched and then dired-do-search (A).

Depends what you mean by find a string. As others have mentioned, grep is very good at what it does. I use it all the time, everyday.
But if your "string" is, say, a sequence of words within a sentence (which can be multi-line), then grep might not be what you want.
Another tool for searching across multiple files or buffers (or bookmarks) is Icicles search. The general idea is that it first parses the files into search contexts according to some definition (e.g. a regexp), and then it searches for matches to your current minibuffer input (changing the search hits dynamically as you edit your input).
Whereas grep always uses lines as search contexts, with Icicles search you are not limited in how you define the contexts to search. The contexts need not partition (exhaust) the file; they can cover as much or as little of the file text as you want.
Among other possibilities, you can use Emacs thing-at-point definitions for various kinds of THING as the search contexts. For example, you can use command icicles-search-thing with sentence as the THING type, to use sentences as the search contexts.
Or you can use character-property zones as search contexts: search all zones that are font-locked with a given set of faces, for instance. There are many possibilities.
http://www.emacswiki.org/emacs/Icicles_-_Search_Commands%2c_Overview

Related

Emacs: replace after rgrep?

I like rgrep a lot. The interface for finding and jumping between matches is great.
But I also want the ability to do interactive and non-interactive replacements
from the *grep* results window.
I mean the information for replacing is already laid out perfectly:
the thing to be replaced is nicely highlighted
some context is given (although it wouldn't hurt to bind
+ to increase the number of context lines)
the files and positions are here as well
But there's no interface for replacement (I checked with f1 m).
Did I miss it or it's not available? Or is it available is some package?
I think you are looking for wgrep. It uses wdired approach, and it is available in the usual package repositories.

How to efficiently search Info documentation?

I was looking for documentation on tr program. As you would imagine the combination of characters t and r happens fairly often in English language... Although I was sure about the name, I wasn't sure about the name of the section it belongs to, so I had to display all nodes and try searching for something like tr or tr( and so on.
Isn't there a better way to do it?
Hmm... I can only guess that the following isn't happening for you; however nodes for individual programs really ought to be listed in the top-level directory, and hence show up when you type M-x info RETd, from where you can simply use m tr RET.
However if you're searching for something which isn't in any of the directory files, the only convenient thing I know of is M-x info-apropos (which searches all of the indexes rather than the node titles).
And of course within a given manual you can use I to search its index, which is much faster than searching all of them.
Edit: This is tangential, but an excellent improvement in the upcoming Emacs 24.4 (currently undocumented in the NEWS file) is completion for Info node names in non-current manuals.
e.g. C-hig (elisp) TAB now provides completions for all the nodes in the elisp manual, even if you are not currently viewing that manual.
This is an extremely welcome change!
Icicles can help here. All Info commands that use completion let you take advantage of Icicles completion features. This includes apropos completion -- regexp matching, which means that you essentially get on-the-fly info-apropos behavior, among other things. And it includes progressive completion, which means you can add additional patterns to progressively narrow your search.
When completing you can sort the candidates in various ways, including sorting Info nodes in book order for g.
g (icicle-Info-goto-node) lets you search both node names and node contents at the same time: Your minibuffer input can contain a second search pattern that is matched against the node contents. The completion candidates are those whose names match the node-name pattern you type (if any) and the node-content pattern you type (if any). Each pattern is a regexp (which includes substring matching as a simple case).
See Icicles Info Enhancements for more information.

In Emacs how to operate (i.e. search) only in code regions?

I'd like to isearch/search-replace/occur only in code (that is not in comments or strings).
This must be a common problem, so what packages do this already?
If no existing packages do this, I'm thinking a minor-mode where strings and comments are hidden based on fontification would do the trick. Is there one?
Icicles search gives you several ways to do this. Here are two:
Search "things" (e.g. defuns, sexps, xml elements, etc.), ignoring comments (option icicle-ignore-comments-flag). That is, use selected code segments as search contexts, but ignore any comments within code or code inside comments.
Search the complement of the comments. E.g., define the search contexts as the complement of the zones of text that are font-locked with either face font-lock-comment-face or face font-lock-comment-delimiter-face (which means search all code outside of comments).
After defining the search contexts, just type text to incrementally filter the contexts. And you can replace any matches on demand.
Check out narrowing.
Yes, you are right. The HideShow minor mode allows you to hide/show block of text, in particular multiline comments.
The hide/show comments is not part of the standard package but on the wiki page you will find the code which does the trick.
Then isearch command does not take into account the hidden comments.
HOWEVER: replace operates on the whole buffer, including hidden blocks.
Isearch+ does what you ask (as does Icicles --- see other answer, above).
You can define the contexts that Isearch searches, using any of the following:
A regexp to be matched.
A given text or overlay property --- The search contexts are the text zones that have the property (e.g. a particular `face' value or combination of values)
A given Emacs THING (sexp, defun, list, string, comment, etc.) --- The search contexts are the text zones of the given THING type.
Having defined the search contexts, you can also search the complement: the non-contexts. You can toggle between searching contexts and non-contexts anytime in Isearch, using C-M-~.
When searching, by default the zones not being searched are dimmed slightly, to make the searchable areas stand out.
For context-searching with Isearch you need these two libraries:
isearch+.el
isearch-prop.el

Emacs recursive project search

I am switching to Emacs from TextMate. One feature of TextMate that I would really like to have in Emacs is the "Find in Project" search box that uses fuzzy matching. Emacs sort of has this with ido, but ido does not search recursively through child directories. It searches only within one directory.
Is there a way to give ido a root directory and to search everything under it?
Update:
The questions below pertain to find-file-in-project.el from MichaƂ Marczyk's answer.
If anything in this message sounds obvious it's because I have used Emacs for less than one week. :-)
As I understand it, project-local-variables lets me define things in a .emacs-project file that I keep in my project root.
How do I point find-file-in-project to my project root?
I am not familiar with regex syntax in Emacs Lisp. The default value for ffip-regexp is:
".*\\.\\(rb\\|js\\|css\\|yml\\|yaml\\|rhtml\\|erb\\|html\\|el\\)"
I presume that I can just switch the extensions to the ones appropriate for my project.
Could you explain the ffip-find-options? From the file:
(defvar ffip-find-options
""
"Extra options to pass to `find' when using find-file-in-project.
Use this to exclude portions of your project: \"-not -regex \\".vendor.\\"\"")
What does this mean exactly and how do I use it to exclude files/directories?
Could you share an example .emacs-project file?
I use M-x rgrep for this. It automatically skips a lot of things you don't want, like .svn directories.
(Updated primarily in order to include actual setup instructions for use with the below mentioned find-file-in-project.el from the RINARI distribution. Original answer left intact; the new bits come after the second horizontal rule.)
Have a look at the TextMate page of the EmacsWiki. The most promising thing they mention is probably this Emacs Lisp script, which provides recursive search under a "project directory" guided by some variables. That file begins with an extensive comments section describing how to use it.
What makes it particularly promising is the following bit:
;; If `ido-mode' is enabled, the menu will use `ido-completing-read'
;; instead of `completing-read'.
Note I haven't used it myself... Though I may very well give it a try now that I've found it! :-)
HTH.
(BTW, that script is part of -- to quote the description from GitHub -- "Rinari Is Not A Rails IDE (it is an Emacs minor mode for Rails)". If you're doing any Rails development, you might want to check out the whole thing.)
Before proceeding any further, configure ido.el. Seriously, it's a must-have on its own and it will improve your experience with find-file-in-project. See this screencast by Stuart Halloway (which I've already mentioned in a comment on this answer) to learn why you need to use it. Also, Stu demonstrates how flexible ido is by emulating TextMate's project-scoped file-finding facility in his own way; if his function suits your needs, read no further.
Ok, so here's how to set up RINARI's find-file-in-project.el:
Obtain find-file-in-project.el and project-local-variables.el from the RINARI distribution and put someplace where Emacs can find them (which means in one of the directories in the load-path variable; you can use (add-to-list 'load-path "/path/to/some/directory") to add new directories to it).
Add (require 'find-file-in-project) to your .emacs file. Also add the following to have the C-x C-M-f sequence bring up the find-file-in-project prompt: (global-set-key (kbd "C-x C-M-f") 'find-file-in-project).
Create a file called .emacs-project in your projects root directory. At a minimum it should contain something like this: (setl ffip-regexp ".*\\.\\(clj\\|py\\)$"). This will make it so that only files whose names and in clj or py will be searched for; please adjust the regex to match your needs. (Note that this regular expression will be passed to the Unix find utility and should use find's preferred regular expression syntax. You still have to double every backslash in regexes as is usual in Emacs; whether you also have to put backslashes before parens / pipes (|) if you want to use their 'magic' regex meaning depends on your find's expectations. The example given above works for me on an Ubuntu box. Look up additional info on regexes in case of doubt.) (Note: this paragraph has been revised in the last edit to fix some confusion w.r.t. regular expression syntax.)
C-x C-M-f away.
There's a number of possible customisations; in particular, you can use (setl ffip-find-options "...") to pass additional options to the Unix find command, which is what find-file-in-project.el calls out to under the hood.
If things appear not to work, please check and double check your spelling -- I did something like (setl ffip-regex ...) once (note the lack of the final 'p' in the variable name) and were initially quite puzzled to discover that no files were being found.
Surprised nobody mentioned https://github.com/defunkt/textmate.el (now gotta make it work on Windows...)
eproject has eproject-grep, which does exactly what you want.
With the right project definition, it will only search project files; it will ignore version control, build artifacts, generated files, whatever. The only downside is that it requires a grep command on your system; this dependency will be eliminated soon.
You can get the effect you want by using GNU Global or IDUtils. They are not Emacs specific, but they has Emacs scripts that integrate that effect. (I don't know too much about them myself.)
You could also opt to use CEDET and the EDE project system. EDE is probably a bit heavy weight, but it has a way to just mark the top of a project. If you also keep GNU Global or IDUtils index files with your project, EDE can use it to find a file by name anywhere, or you can use `semantic-symref' to find references to symbols in your source files. CEDET is at http://cedet.sf.net
For pure, unadulterated speed, I highly recommend a combination of the command-line tool The Silver Searcher (a.k.a. 'ag') with ag.el. The ag-project interactive function will make an educated guess of your project root if you are using git, hg or svn and search the entire project.
FileCache may also be an option. However you would need to add your project directory manually with file-cache-add-directory-recursively.
See these links for info about how Icicles can help here:
find files anywhere, matching any parts of their name (including directory parts)
projects: create, organize, manage, search them
Icicles completion matching can be substring, regexp, fuzzy (various kinds), or combinations of these. You can also combine simple patterns, intersecting the matches or complementing (subtracting) a subset of them

What is the best way to navigate duplicate tag definitions in Emacs?

Within emacs, what are the best options out there for navigating to a specific function whose name might show up across several different files? Within etags, you are only allowed to cycle through the tags one-at-a-time which could take a while if the function name you are looking for is popular.
C-u M-. cycles all locations of the same tag, but if you want to see a list of all tags that match your function name you can use the command tags-apropos.
Etags-select:
http://www.emacswiki.org/cgi-bin/wiki/EtagsSelect
If your programming language is C then cscope is much better than etags. It presents you with an interactive list of a symbol instances with its context. More info is in this answer
Icicles tag commands
In particular, use command icicle-find-tag, to do what all of these vanilla commands do:
find-tag (M-.) to find a tag
tags-loop-continue (M-,) to find another matching tag
tags-apropos to list all tags that match a regexp
list-tags to show all tags (definitions) in a given source file.
icicle-find-tag is a general tags browser: being a multicommand, you can visit any number of tags, in any order, in a single invocation.
Icicles imenu -- Imenu across files or buffers. Search within selected function definitions (as the search contexts).