vim path completion in command mode - vim

In vim, If you hit :e <tab><tab>, vim complete some path.
However, I want to open a/b/c/d.cpp, I stroke :e <tab><tab> and find AA.
I want to find subdirectory of AA. Alternatively, I hit / key.
example :e AA//BB//CC//DD.cpp
Are there another good way? In summary, I want to know complete path for subdirectory in command :e.

Command-line completion lets you use wildcards.
The basic * means "any character":
:e *<Tab> " similar to plain <Tab>
:e foo*<Tab> " completes only files starting with 'foo'
The fancier ** means "any subdirectory":
:e **/<Tab> " completes every file under every subdirectory
" of the current working directory
:e **/*foo<Tab> " completes every file ending with 'foo' under every subdirectory
" of the current working directory
See :help file-searching.
By the way, it's "command-line mode". "Command mode" is just another name for "normal mode".

This answer is based on the assumption you want the path for picking out the correct file for editing.
May I suggest to use :find after setting the path properly. This will save extra lot of typing.
You can start by setting :set path+=**(this will search sub-dirs as well). Now you can simply do
:find d.cpp
vim will do the rest for you. It will find out the path to d.cpp and open it.
What is nice about it is it allows to use wildcard, for example, as :find d.* or :find *.cpp.
If you don't want to use find and continue with edit, May be it will be useful to :set wildmenu. This will show all available options that you can iterate with tab

Related

In Vim, how to choose the nth suggested file while doing :edit?

This is a total newbie vim question. Apologies for the basic-ness involved.
I need to open a lot of files. The :edit <file-name> command seems to open a file and I also see a filename auto-complete feature, which searches for all similar file names in the path. But I don't know how to choose one of those suggestions quickly without writing the whole file name.
set wildmenu
enables the "wildmenu" where you navigate with <Tab> and <S-Tab>, enter a subdirectory with <Down> and select a file with <CR>.
See :help 'wildmenu' and :help 'wildmode'.
Note that :edit can only open one file. If you want to open multiple files at once, use :args models/*.php.
Another, more familiar, way to open files is to use the built-in netrw:
:Explore
See :help netrw for more info.
Sounds like you might enjoy the conveniences of the rather smashing CTRL-P plugin. https://github.com/kien/ctrlp.vim
It will allow you to type any substring of the filename to narrow the available files down. You can mark multiple files for opening.

Command line completion to enter into a folder in Vim

When I do :edit C:\ and keep tabbing, vim will cycle through all the files and folders. When I want to enter a folder, I think I can do Ctrl-E. But just by chance, I typed another backslash after the folder I want to enter, e.g, :edit C:\Documents\\. This also seems to work. Now if I hit tabs, vim start cycling through files/folders inside C:\Documents.
I wonder what is the reason behind this. Could Anyone point me to the reference manual where this behaviour is fully explained? And does there exist even better way to stop completion in the current directory and start command line completion inside another directory?
It is not documented, however, when you modify the text (for example, insert a backslash) during completion, vim will only auto-complete the rest of the string. This is because it starts a new completion cycle taking the current entry as the base.
I use this mapping, analog to concluding insert-mode completion:
" c_CTRL-Y Yes: Stop wildmode completion. Useful when completing
" directory names and wanting to use the currently
" completed directory and now complete its contents,
" instead of continuing to iterate the directory names.
cnoremap <C-Y> <Space><BS>
But Ctrl-E works as well when you're at the end of the command-line.

VIM 7: How to navigate the code source tree from the root of the code base, in an efficient manner?

I have a system of navigating the code across multiple files in a huge code base, and I want to improve/fix a drawback that it currently has :
My shell is pre-configured to open at the root of my code base - lets call it Dev/.
During syncing/code building, I have a script which automatically stores the relative path of all .h and .c files in a single file to be used by cscope (lets call it cscope.files).
Once I sync, this file is updated - and then I can open any file I want in vim using the following command from Dev/ :
vif "part of file name",
where
vif: aliased to vi `grep !:1 cscope.files`
Provided I give a part of the filename long enough to uniquely identify it, I can immediately open it in vim.
Now, the drawback to this approach is, when I've already opened one file, and jump to another file without exiting vim, the only way I can do so is
:!vif *file2*
This spawns a new shell and then opens the file in a vim launched there. As a result, I can't switch between the two files (using Ctrl-^). I'm unable to come up with a solution that :
a) Lets me open any file from Dev/ instantly
b) Lets me open any other file inside vim (once I've opened an existing file) in the same shell, so that the 2 vim sessions are aware of each other (I can hop between the 2 using Ctrl-^)
I know this is a long question (how does one google this :) ), but I'm betting the solution is simple and obvious to someone more proficient in vim !!
Let me know if any part of the question is fuzzy, and I'll clarify it...
UPDATE:
I ultimately went the cscope way, after customizing using a shortcut (as using 'gf' on cscope.files still prevented me from toggling between 2 source files). See VIM 7 and cscope: Using "cscope find f" inside a keyboard mapping for switching between files for the shortcut.
Use vim's grep in something like this:
:map <F1> :vim <pattern> cscope.files<CR>gf
For example, with this:
vnoremap <F1> "ry:exe ':1vim /'.#r.'/ cscope.files'<CR>gf
you select (visual mode) the pattern you'd like to search for and then press F1. The first file that matches the pattern will open, replacing the current buffer*.
* If this is possible. i.e if current buffer is saved or if hidden is set etc.
If you prefer to get a prompt, use input():
nnoremap <F1> :exe ':1vim /'.input("Enter pattern: ").'/ cscope.files'<CR>
[ but then you have to manually gf because input() consumes the remaining characters of the map. To avoid this, you can use inputsave() and inputrestore() ]
update
... for example like this:
function! GetPat()
call inputsave()
let mypat = input("Enter pattern: ")
call inputrestore()
return mypat
endfunction
nnoremap <F1> :exe ':1vim /'.GetPat().'/ cscope.files'<CR>gf
I think that the Vim Fuzzy Finder plugin is well adapted to your use case.
As the name implies, using the plugin, you can find files using a fuzzy text search.
Additionnaly, it also works for other Vim ressources like buffers, tags, etc.
I don't use cscope myself, but it seems that you can use it to find files, see :help cscope-find.
Otherwise, something like (not tested) this could help:
"Custom function
function! MyFunc(pat)
" Get files list
let filelist = readfile('path/to/cscope.files')
" Filter non matching item out and see if only one item is left
if len(filter(filelist, 'v:var =~? '.a:pat)) == 1
" edit file
exec 'edit '.filelist[0]
else
" Report back
echom 'More than one match:'
for file in filelist
echom file
endfor
endif
endfunction
" Custom command
command! -bar -nargs=1 MyCom call MyFunc(<args>)
Also try using the built-in cscope integration:
:cs find f stdio.h
Cscope tag: stdio.h
# line filename / context / line
1 1 /usr/include/stdio.h <<<unknown>>>
2 1 /usr/include/bits/stdio.h <<<unknown>>>
Type number and <Enter> (empty cancels):
See :help cscope-suggestions for some mappings that may make it easier to use cscope from within vim.

GVim - How to handle multiple files

Sorry to ask such a novice question but I am looking for a way to handle multiple files. I dont want to type huge file paths to open every file using :tabnew and :e commands
Fuzzy Finder is a handy plugin to quickly find and open files.
Basically you have to only type a few letters like test and you'll get a pop-up menu to open in your current path :
footest.c
bartest.h
footest.h
...
It is a bit slow when used on NFS but it is useful if you don't want to type long path and file names.
Alternatively if you don't want to use any plugin, by default gvim/vim includes a file browser called netrw.
To start it, just type :e . you'll get the content of your current directory, you can then navigate through the directory structure quite easily. (There is even commands to delete, rename, etc like a standard file explorer)
:help netrwfor more information.
A couple of tips that you might be interested in:
You can configure Vim so that the
current directory "follows" the
directory of the file you are
currently editing. That way you can
edit another file from the same
directory without having to type the
full path. This can be achieved by
putting either set autochdir or
autocmd BufEnter * lcd %:p:h in
your .vimrc
You can use wildcards with tab
completion. e.g. to edit
a_file_with_a_long_name.txt you could
do :e a*long and then press
Tab followed by
Return.
Usually, vim supports buffers for that. Use :badd to add buffer, :bdelete to remove it and :ls (or :buffers) to list all opened buffers. I believe, GVim supports these features too.
For example, if you wanna edit all .rb files in your app/controllers/pages dir (in the case of Rails project), you type vim app/controllers/pages/*.rb in your terminal and then edit the first file (buffer) in the vim window. When you've done with all changes, save changes as usual with :w (note: do not use q! option - this will close all your buffers you've opened) and then use :bn<tab> (or fully, :bnext) or :bprevious to switch to the next file (buffer). When you run :bnext on the last buffer, you'll be dropped to the first one.
You can open a directory in Vim, search for the file o directory you are looking for with '/' and type [enter] to open it.

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