navigating filesystem in vim -> :find vs. :edit - vim

When opening files in Vim I almost always do something like this:
:e subDir/**/file<ctrl-d>
But in the docs and basically every StackOverflow/blog post I have read it seems that people use "find" the way I use "edit".
What am I missing by using the edit command instead of the find command?

:edit is restricted by default to the working directory: if you need to edit a file that is not under your working directory you will have to provide its absolute path or a path relative to the working directory. Also, you need to provide the necessary globs.
:find is superficially very similar to :edit but the (big) difference is that it finds files in the directories specified in the path option. path is what makes :find a lot more interesting than :edit.
With set path=,, you essentially get the same behavior as :e foo.
With set path=** you essentially get the same behavior as :e **/foo except you don't have to use any glob.
With set path=.,** you also get access to files in the same directory as the current file.
With set path=.,**,/path/to/some/central/vendor/directory you also get access to files from that directory… and so on.

Related

How to get Vim to use a local spell-file in the current directory?

I undestand Vim can do spell-check, and it can modify a spell-file inside ~/.vim to keep words flagged as good.
I'd like to keep a "local" spell-file in the same directory as a file I'm editing, so that if I'm in different directories editing different files, different spell-files would be used.
How would I set up Vim to do this?
Vim's own help is usefull here:
:help spellfile
Name of the word list file where words are added for the
zg and zw commands. It must end in ".{encoding}.add".
You need to include the path, otherwise the file is placed
in the current directory.
More detailed information:
http://thejakeharding.com/tutorial/2012/06/13/using-spell-check-in-vim.html
Separate Vim spellfile for custom words
So:
:set spellfile=./en.utf-8.add
hth

Vim insert mode file path completion

I want to change where vim looks for file completion, but only in insert mode. For example:
I open gvim inside of the CG-Website directory.
This is my directory structure:
Then i go in to the css folder and open style.css
using :e src/static/css/style.css
Now i am inside of style.css and i want to complete a file name that is down one directory.
I want to be able to type ../ in INSERT mode and have all the files/folders that are inside of the static folder show up, instead of the www folder which is what it does right now.
However I don't want to change the actual directory, because I still want :e to work normally.
Insert mode filename completion is always done from the "current directory" or "working directory" which may or may not be the directory of the current file. Since you don't want to change directories, filename completion can't work like you want it to work.
Actually, the last sentence of :h compl-filename should give you a hint:
Search for the first file name that starts with the
same characters as before the cursor. The matching
file name is inserted in front of the cursor.
Alphabetic characters and characters in 'isfname'
are used to decide which characters are included in
the file name. Note: the 'path' option is not used
here (yet).
One solution to this problem is to set autochdir so that Vim always changes the working directory to the directory of the current file and use a plugin like CtrlP (there are others) for navigation. When configured properly, CtrlP lets you navigate your files from your project's home as defined by the presence of a .git or similar directory. This is really handy.
However, you can get around that limitation relatively easily with set autochdir (again, you need it for filename completion to work like you -- and I -- want it to work) and a bit of creativity:
nnoremap <F9> :e ~/path/to/project/
Consider this mapping as a quick shortcut to your project.
I think you are approaching this the wrong way. You want to filter results relative to your last opened dir without changing your current dir and that doesn't quite make sense.
My recommendation is to use a tool what will allow you to quickly filter through all of your files from the root folder of your project.
Take a look at Command-T: Fast file navigation for VIM
PS: you need vim with ruby support for that.

Include a directory recursively for vim autocompletion

I use vim from the base directory of my source code. I would like to have autocomplete consider every word of every file in this directory (and subdirectories) when editing a single file.
Completion is controlled by the 'complete' option. With the k flag, you can have Vim scan files. The ** wildcard stands for a recursive descent into subdirectories. Voila:
:set complete=k**/*
When you want to keep the other default locations (other buffers, included files, etc.), use :set complete+= to add to it.
Alternatively, as this can be too slow for a default, you can use the 'dictionary' option and use Ctrl-X Ctrl-K completion:
:set dictionary=**/*
:argadd **/*
This will recursively load all files into buffers, and the completion will consider them. Beware that this will load all files, including files you might not want to add, such as binary files or files in CVS directories. A more fine-grained glob such as the one below might be a good idea.
:argadd **/*.cpp
I think a much better approach is to generate a tags file in your directory system using Exuberant CTags.
For starters, build your tags file in the root of your source with:
ctags -R .
This may find more than you like, but you can tune it with further command line options.
Set your tags option to refer to this file ("tags" is the default name), or use set tags=./tags;/ to search up your directory tree to the first tags file found. See :help file-searching to understand the ;/ syntax for upward search.
Finally, make sure that 't' is in your complete option. It's there by default, but check with set complete?. If it's not there, set complete+=t will put it there.
I personally remove 'i' and 'd' from my 'complete' option, because the disk access is annoying, even though typing CTRL_Y (yes, accept completion) or CTRL_N (no, reject completion) or continuing normal typing will stop the search. If all the included files are in your tags file, you'll find the completion instantly.

Recursive Tab Complete Filenames on :edit in VIM

I had found a .vimrc configuration that allowed me to simply type
:e <<characters_in_filename>>
and then tab and the path would expand out to :e full_path or show me a list of options if there are similarly named files in my current path.
Anyone know how to make this happen?
note: I'm aware of FuzzyFileFinder, Peepopen, and CommandT, this has just really been bothering me.
It's very similar to the functionality described in this google groups thread
As ZyX said, it sounds like you want find.
set wildmenu
set wildmode=longest:full
set path+=./**
If you type :find so<Tab>, it will complete with all files that start with so searching recursively from the current file's directory (not pwd). (<Tab> can be changed with wildchar.)
You may prefer this kind of completion:
set wildmode=list:longest
And you could add your often used roots to path if you don't want recursive from the current file's directory.
set path+=~/code/**
If you just want to recurse from the current directory, try the above wild settings and use:
:edit **/so<Tab>
For more on specifying filenames see :help {file} and for more on **, see :help starstar-wildcard.
Be sure that wildmenu is on and try :find command.

Shortcut to open file in Vim

I want to open a file in Vim like in Eclipse using Ctrl + Shift + R, or via the Ctrl + N option of autofill. Invoke a keyboard shortcut, type the file name/pattern, and choose from all the matching files names.
I know opening it normally like:
:tabe <filepath>
:new <filepath>
:edit <filepath>
The problem here is that I have to specify the whole file path in these cases.
What I normally do is e . (e-space-dot) which gives me a browsable current directory - then I can / - search for name fragments, just like finding a word in a text file. I find that generally good enough, simple and quick.
I recently fell in love with fuzzyfinder.vim
... :-)
:FuzzyFinderFile will let you open files by typing partial names or patterns.
:find is another option.
I open vim from the root of my project and have the path set to there.
Then, I can open files located anywhere in the tree using:
:find **/filena< tab >
Tab will autocomplete through various matches. (** tells it to search recursively through the path).
You can search for a file in the current path by using **:
:tabe **/header.h
Hit tab to see various completions if there is more than one match.
Consider using CtrlP plug-in.
It is included in Janus Distributive.
Allows you to find files in the current directory, open buffers or most recently used files using "fuzzy matching" or regular expression.
unless I'm missing something, :e filename is the fastest way I've found.
You can use tab to autocomplete the filename as well.
I like the :FuzzyFinderTextMate (or Ctrl + F) on my setup.
See http://weblog.jamisbuck.org/2008/10/10/coming-home-to-vim
I use a couple of shortcuts in my .vimrc file (exact syntax below).
They are based on the fact that in 90% of the cases, I want to open another file in the same directory as the file that I am currently editing, or in a directory that is very close in the hierarchy to that edited file.
Here's what the commands do do:
,cd : Change the current working directory to the directory that the current file you are editing is in.
,e : Opens a file with the current working directory already filled in so you have to specify only the filename.
Put these into your .vimrc:
map ,e :e <C-R>=expand("%:p:h") . "/" <CR>
map ,cd :cd %:p:h <CR>
Here's a sequence of events:
You are editing a file called test.java in "/home/prog"
,cd -> Current working directory now
becomes "/home/prog"
,e -> Expands to ":e /home/prog" so
that you can just fill in the file
name, say test.h.
,e -> Expands to ":e /home"
tab -> Cycle through subdirectories of /home
enter -> cd to the directory you
want say /home/prog
,e -> Expands to ":e /home/prog"
There's also command-t which I find to be the best of the bunch (and I've tried them all). It's a minor hassle to install it but, once it's installed, it's a dream to use.
https://wincent.com/products/command-t/
Use tabs, they work when inputting file paths in vim escape mode!
If you've got tags (and you should), you can open a file from the command line just by the name of the class or method or c function, with "vim -t DBPlaylist", and within vim with ":tag ShowList".
If you're editing files in a common directory, you can :cd to that directory, then use :e on just the filename.
For example, rather than:
:e /big/long/path/that/takes/a/while/to/type/or/tab/complete/thingy.rb
:sp /big/long/path/that/takes/a/while/to/type/or/tab/complete/other_thingy.c
:vs /big/long/path/that/takes/a/while/to/type/or/tab/complete/one_more_thingy.java
You can do:
:cd /big/long/path/that/takes/a/while/to/type/or/tab/complete/
:e thingy.rb
:sp other_thingy.c
:vs one_more_thingy.java
Or, if you already have a file in the desired directory open, you can use the % shorthand for the current filename, and trim it to the current directory with the :h modifier (:help :_%:) :
:e /big/long/path/that/takes/a/while/to/type/or/tab/complete/thingy.rb
:cd %:h
:sp other_thingy.c
:vs one_more_thingy.java
And, like others have said, you can tab-complete file names on the ex-line (see :help cmdline-completion for more).
This isn't exactly what you're looking for, but it's good in many cases (though not all).
If you VIM open and there's a name of a file in the buffer, you can put the cursor on that filename and type gf. This opens the file whose name is under the cursor in the same buffer. It's the same as
:e CTRL+r CTRL+w
I know three plugins that permit to open files, support auto-completion, and don't require to enter the full path name of the file(s) to open (as long as the files are under one of the directories from &path vim option):
searchInRuntime that I'm maintaining (the completion is not on :e/:find, but on split actions)
fuzzy finder as it has been already pointed out,
lookupfile.
Lately, I've seen another plugin with a similar feature, but I don't remember the name.
Soon, :find is likely support auto-completion -- patches on this topic are circulating on vim_dev mailing-list these days.
you can use (set wildmenu)
you can use tab to autocomplete filenames
you can also use matching, for example :e p*.dat or something like that (like in old' dos)
you could also :browse confirm e (for a graphical window)
but you should also probably specify what vim version you're using, and how that thing in emacs works. Maybe we could find you an exact vim alternative.
FuzzyFinder has been mentioned, however I love the textmate like behaviour of the FuzzyFinderTextmate plugin which extends the behaviour to include all subdirs.
Make sure you are using version 2.16 of fuzzyfinder.vim - The higher versions break the plugin.
With Exuberant ctags, you can create tag files with file information:
ctags --extra=+f -R *
Then, open file from VIM with
:tag filename
You can also use <tab> to autocomplete file name.
In GVIM, The file can be browsed using open / read / write dialog;
:browse {command}
{command} - open / read / write
open - Opens the file
read - Appends the file
write - SaveAs dialog
I installed FuzzyFinder. However, the limitation is that it only finds files in the current dir. One workaround to that is to add FuzzyFinderTextmate. However, based on the docs and commentary, that doesn't work reliably. You need the right version of FuzzyFinder and you need your copy of Vim to be compiled with Ruby support.
A different workaround I'm trying out now is to open all the files I'm likely to need at the beginning of the editing session. E.g., open all the files in key directories...
:args app/**
:args config/**
:args test/**
etc...
(This means I would have possibly scores of files open, however so far it still seems to work OK.)
After that, I can use FuzzyFinder in buffer mode and it will act somewhat like TextMate's command-o shortcut...
:FuzzyFinderBuffer

Resources