Is there a quick file open/find like IntelliJ's find file, or Sublime's? Something with fuzzy search. But in Emacs? - file

I'm looking for something that's a bit robust in how it finds files in Emacs. I have a project made up a number of different files, and a lot of them. So, I think maybe Emacs would need to cache a lookup or something like that to make a quick find/open facility to work. It would need to also be configured per project to consider only some directories and exclude others inside of this project, since a number of files and directories are generated and hold a massive amount of text and sometimes a concatenated representation of the rest of the code.
Is there a quick file open/find like IntelliJ's find file, or Sublime's? Something with fuzzy search. But in Emacs? That could help with this problem?

Projectile can probably do what you're after. It describes itself as a "project interaction library" with facilities for finding project files quickly.

Try projectile: https://github.com/bbatsov/projectile (see its fancy UI, helm-projectile). You'll have the command projectile-find-file. It is based on projects (they are defined by a .git/.gh/… or a .projectile).
permanent caching ? Yes
filter out directories ? Yes (with a command or a config into the .projectile)
fuzzy search ? Yes, a few: emacs'default, ido, ido-fuzzy, grizzl or helm.
you install it simply with M-x package-install RET projectile RET.

See this EmacsWiki page, which is is a jumping-off place for multiple answers to your question.
Emacs has a built-in file-name cache -- see (emacs) File Name Cache and this page.
See also Emacs bookmarks, and in particular, Bookmark+. You can bookmark any file or set of files. You can bookmark a Dired buffer, including its omit set, markings, and included subdirs. You can bookmark a set of such Dired buffers. You can aggregate bookmarks and use them to perform actions that set up environments etc. They can be triggered in various ways. You can bookmark Emacs desktops. You can tag bookmarks and files & dirs with free-form tags, which lets you organize them flexibly into overlapping sets.
See also this page about project support with Icicles.

Related

How can I configure Git to ignore trivial changes (e.g. timestamp) in auto-generated code?

I am working with a tool which auto-generates a large amount of C code. The tool generates code for a batch of .c and .h files at each run. For some reason, the tool isn't smart enough to recognize when the files have no substantial changes, so in many cases it simply updates a timestamp in the comments at the top of each file. Otherwise, the file remains unaltered.
When I run git status in that scenario, I sometimes see dozens or hundreds of files changed. But as I review the changes to the individual files, most of them have no real changes - just an update to the timestamp. I have to go through each file one-by-one to determine if there are any actual changes to be committed.
Is there a way to configure Git so that it can ignore inconsequential changes such as the timestamp in the header comments? Or how might I otherwise deal with this situation?
Thanks for your help.
Is there a way to configure Git so that it can ignore inconsequential changes such as the timestamp in the header comments? Or how might I otherwise deal with this situation?
Yes; this is the purpose of a filter.
You might be familiar with git's notion of "clean" and "smudge" filters already, that's how it handles line ending conversion. When you are on a Windows computer and have Windows-style line endings in your working directory, you might set a .gitattribute like * text=auto indicating that you want files checked into the repository with "normalized" Unix-style line endings. In this case, the files will have the "clean" filter applied to convert \r\n line endings to \n style line endings. Similarly, the files will be "smudged" on checkout to convert from \n to \r\n on-disk.
You can create your own clean and smudge filters to remove (or add) data when translating between the working directory and the repository. For these files you can add an attribute:
*.c filter=autogen
And then you can configure your autogen filter, with commands to run in the "clean" (into the repository) and "smudge" (into the working directory) directions.
git config --global filter.autogen.clean remove_metadata
git config --global filter.autogen.smudge cat
(Using cat is a "noop" as far as filters are concerned).
The Pro Git book has more detailed examples of creating your own filters.
I discovered a way to address the problem of trivial changes using Beyond Compare. I will describe the process as it pertains to ignoring timestamp updates in auto-generated C files, but it can be easily adapted to other situations and languages:
Configure Beyond Compare as the Git difftool. See here for specific details about how to do this.
(Optional but helpful) Add a Git alias for the git difftool --dir-diff --no-symlinks command (for example, dtd).
Make some changes (e.g. auto-generate your files), and run git dtd to do a directory diff. Beyond Compare will open and show you a before/after Folder Comparison of your changes.
Open a Text Compare session window for one of your changed files. Open the Tools menu and select File Formats.
Open the Grammar tab, delete the "Comments" grammar element.
Add a new grammar element and give it a meaningful name such as "Generation Time Comment".
For Category, select the "Delimited" grammar element. In the "Text from" box, enter the text you would like to ignore. For example, if the timestamp in your auto-generated code starts with the string * Generation Time:, enter it into the "Text from" box. Check the "Stop at end of line" checkbox.
Click the "Save" button and go back to your Text Compare session window.
Open the Session menu and select Session Settings. Open the Importance tab.
Look for your new grammar element (e.g. "Generation Time Comment") and uncheck it. This will tell Beyond Compare to treat it as an unimportant change.
Open the Comparison tab, select Rule-Based Comparison.
Change the dropdown at the bottom of the dialog to Update session defaults.
Close Beyond Compare, and then reopen it again by running the git dtd command.
All of the files in the Folder Compare session which contain nothing but an update to the timestamp will be shown with unimportant differences. If you want to completely hide files with unimportant differences, toggle off Ignore Unimportant Differences in the View menu.
Reference: https://www.scootersoftware.com/support.php?zz=kb_unimportantv3

Find files in vim: how to do a partial filename match with Explore **/*

I've recently discovered the following to find files in Vim.
:Explore **/[pattern]
Finding files is pretty important to me, and I can't believe I've done without it for 8 years. I can relate to what this gentleman has said: http://vim.wikia.com/wiki/Find_files_in_subdirectories
I see people searching for files in TextMate and have to hang my head in shame :(
So using the above I'm able to search for files, "in theory", but the output baffles me and often has files that do not match. I'll use a Rails example.
For example doing this:
Explore **/envir*
Yields this, which a bunch of extra weird files:
../
deploy/
environments/
initializers/
locales/
.DS_Store
application.rb
authorization_rules.rb
boot.rb
config.yml
database.yml
deploy.rb
development.sphinx.conf
environment.rb
production.sphinx.conf
routes.rb
sphinx.yml
staging.sphinx.conf
test.sphinx.conf
That is at least usable, I can scroll down to environment.rb and open it.
But say I want to find a list of all helpers. I would think that this:
Explore **/*help*
Would work, but no files are found.
Can someone illuminate me?
Have you look at the Ctrl-P.vim plugin? https://github.com/kien/ctrlp.vim
This plugins finds files in a similar way to what you show.
No, :Ex[plore] **/foo* sucks.
The above mentioned CtrlP is a beauty (that I use extensively despite a few limitations) that allows you to find files in your project and other niceties. FuzzyFinder and Command-T are worthy alternatives, LustyExplorer as well and there are obviously many others.
But Vim is quite capable by himself. The wildmenu option is key, here. Just add these two lines to your ~/.vimrc:
set wildmenu " see :h 'wildmenu'
set wildmode=list:full " see :h 'wildmode' for all the possible values
With the setting above, the following command shows you an accurate list of matches that you can navigate easily and relatively intuitively.
:e **/foo*<Tab> " see :h starstar
If the "working directory" is set to your project directory, that command is sure to give you good results. It's not very sexy (I like it, though) but it's very effective and dependable. Of course, this method can be used with :sp, :vs or :tabe.
The :find command is even better and probably more suited to yor needs: it looks into the directories defined in the path option. :set path=/path/to/project at the beginning of your session and you can open any file in your project with:
:find foo<tab> " see :h :find
Neat.
Another possibility is to use "args". You add all the files matching some pattern to your "argument list" and use buffer navigation commands:
:argadd ./**/*.js " see :h arglist
:sb foo<tab>
But it can be a little messy.
Overall, there are many elegant ways to deal with file navigation in Vim (and I didn't even mention tags-based navigation!). Plugins may provide a nice unified UI to a number of navigation needs but they are not required for finding files efficiently. At all.
It is interesting to note that both TextMate's and Sublime Text's implementations of fuzzy search are actually limited to the current "project" which is not the case for those Vim plugins or for Vim's buit-in file handling.
If all you want is simple :find type functionality but with partial file name matching with tab auto-completion, the find-complete plugin is good.

How to achieve symbol referencing across directories in vim?

Can ctags tag symbols from a directory up in the hierarchy also or is it limited to create tags for current and sub-directories only?
Basically I'm looking for Visual Studio like symbol cross referencing it is very helpful in understanding alien source code flow.
If not Vim, then which other editor should I use?
thanks
Ctags only recurses to subdirectories. But all you have to do is run ctags -R . in your project home directory, and it will create a tags file for your whole project.
You aren't limited to specifying one tags file in Vim. This is an alternative to the other answers; you can just do something like:
set tags=tags,~/wintags,c:/path/to/moretags/etc
So you don't need to take the time regenerating a monolithic tags file when you just want to update your local tags.
Regarding the OP's comment in another answer,
yes thats correct but when i open a file say proj/dir1/def.c and press ctrl+] on a function name which is defined say in proj/dir2/abc.c, I get tag not found :(
You could also create one tags file for all of your projects at the 'proj' root:
set tags=tags;c:/path/to/proj
This will use the first file named tags that it finds as it walks up the directory hierarchy from where you are.
You can combine these two techniques to have a project-local tags file and then a "global" tags file that isn't updated as often.
Whilst it's got similar user interface for asking it to do it's thing, so you need to actually specify "go down directories", I find that cscope is a very nice tool, whcih does everything that ctags does and a bit more.
ctags (well, exctags at least) can create tags for as many directory trees you want. Simply run
exctags -R dir1 dir2 ...
Then vim knows about all the symbols you need. For example, one of the directories could be /usr/include in addition to your own source directory.
Make sure to run vim path/to/file.c from the same directory you created the tags file in.

How can git be configured to ignore files?

There are some files we want ignored, not tracked, by git, and we are having trouble figuring out how to do that.
We have some third-party C library which is unpacked and we have it in Git. But when you configure && make it, it produces many new files. How to write .gitignore to track source files and not the new stuff. (it's not like forbidding *.o)
Edit: There are at least 12 file-types. So we would like NOT to enumerate, which type we want and which not.
Use ! to include all the types of files you need. Something like in the following example"
*
!*.c
!*.h
Explicitly specifying which files should be tracked and ignoring all others might be a solution. * says ignore everything and subsequent lines specify files and directories which should not be ignored. Wildcards are allowed.
*
!filename
!*.extension
!directory/
!/file_in_root_directory
!/directory_in_root_directory
Remember that the order matters. Putting * at the end makes all previous lines ineffective.
Take a look at man gitignore(5) and search for !. It says
Patterns have the following format:
(...)
An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again. If a negated pattern matches, this will override lower precedence patterns sources.
I'm not sure why you say "it's not like forbidding *.o", but I think you mean that there aren't any good patterns you can identify that apply to the generated files but not to the source files? If it's just a few things that appear (like individual built executables that often don't have any extension on Linux), you can name them explicitly in .gitignore, so they aren't a problem.
If there really are lots and lots of files that get generated by the build process that share extensions and other patterns with the source files, then just use patterns that do include your source files. You can even put * in .gitignore if it's really that bad. This will mean that no new files show up when you type git status, or get added when you use git add ., but it doesn't harm any files that are already added to the repository; git will still tell you about changes to them fine, and pick them up when you use git add .. It just puts a bit more burden on you to explicitly start tracking files that you do care about.
I would make sure the repo is clean (no changes, no untracked files), run configure && make and then put the newly untracked filed into the ignore file. Something like git status --porcelain | fgrep '??' | cut -c4- will pull them out automatically, but it would be worth some eyeball time to make sure that is correct...

Is there any way to tell IntelliJ IDEA not to look at files during a search/replace or during refactorings?

Basically my question is the topic ^
I have 4 files that are massive. I need to put them in resources under my maven project structure. Whenever I do a string-based refactoring or search/replace... I basically want the IDE to ignore these files altogether.
Yes, I know I can exclude them and do the replacements manually... but like I said, I want to remove any possibility that they can be modified through the IDE (without having to write-protect them I guess, or revert them all the time if the version control says they've been modified).
Is there any way I can exclude these files?
There are two questions there:
1) How to exclude these files in string based refactoring such as search and replace
You can set up a custom scope when you do a find and replace. This custom scope is saved so you don't have to set it up every time you do a find and replace.
Open the find-and-replace window or the find-in-path window and you will see the scope section in the window with "Custom" as the last option. You can select the files that you want to include/exclude here.
2) How to prevent files from being modified in the IDE without write protecting them
This I'm not sure about. You can add them to a separate change list so that they will always be grouped away from your main set of changes or add them to the vc ignore list. But this doesn't stop the IDE from modifying them. Perhaps you should find out what is editing those files and stop that process?
You can mark the directory as Excluded in "Project Structure->Modules"
You can mark this directory as for "Generated Sources Root"

Resources