When I try to open a file in Vim (Linux) for editing, when I press TAB, Vim autocompletes filename only with filenames from the current directory. However, having searched on the Web, I suppose that from version 7 Vim should support bash-like filename autocompletion using filenames from all the directories in the search path.
Say, there is a file file1 in a directory dir1 (which directory is also in the environment variable PATH).
I type the following commands in Vim:
set path=/dir1
set wildmode=list:longest
And then, when I type:
:e fil<TAB>
The filename is not autocompleted. How to enable this feature in Vim?
Tab-completion works. You just expect it to do something it is not actually supposed to do.
:e[dit] and its siblings (:sp[lit], :vs[plit], :tabe[dit]) don't use the path option at all, no matter what version of Vim you have.
Use :fin[d] fil<Tab> instead (and :sf[ind], :vert sf[ind], :tabf[ind]).
Use set path=/dir1/** to make :find recursive.
See :help 'path' and :help :find.
edit
It is generally considered "good practice" to start Vim from the root of your project:
$ cd /path/to/project
$ vim somefile
The main advantage being that it sets Vim's "current directory" to a usable value that allows you to browse your project relatively easily or use external programs on your project in a clean and intuitive way.
Related
I'm using VIM as my primary code editor for Laravel projects. While I'm in VIM, I want to search for a file that I can open up as a tabnew or as a new vsplit pane. I was told there's a find command. So I tried something like this:
:find ~/development.project1.com/ -name *Controller.php
But that only gave me the error E345: Can't find file "/var/www/development.project1.com/ -name *Controller.php" in path
What did I do wrong? How can I quickly search for other files in VIM and open them up as a tabnew or as a new vsplit pane?
The vim find command is not the same as the unix find command. To find out what find does, use the online help!
:h find
This will give you an answer:
:fin[d][!] [++opt] [+cmd] {file}
Find {file} in 'path' and then :edit it.
In other words, :find is like :edit but looks in your path instead of just the current directory. Note that the vim path is not the same as the operating system shell variable PATH. You can find out what is in your path with
set path?
Most likely you don't have every subdirectory of your project in your path (or in your PATH). Neither should you.
If you want to edit a file with a name ending in Controller.php, a simple solution to search through every subdirectory is to specify ** before the filename to wildcard-match against every subdirectory:
:e **/*Controller.php
Note that doing the above will only open the first file matching the wildcards. If there are several matching files, and that wasn't the file you wanted, no luck.
If you want to choose a file among several matches, and don't want to use plugins, you can read a list using the unix file command
:r! find . -name \*Controller.php
You will end up with a buffer with a list of files. To open one of the files, move the cursor above the file name, and use the gf command to open it.
While not really an answer to your question, with vanilla vim, there's wildmode command line completion. If wildmode is enabled, vim will complete filenames when you open a new file with :e.
Finally, there are lots of different fuzzy finder plugins for vim. If you don't need windows, I recommend fzf.
vim find and find command are different as noted. Perhaps, you might like ctrlp.
But a easier vanilla vim replacement is to go to the folder which contains your files and in vim
:set path+=**
:find file_name
This will find and edit file_name. Nice thing of this is that it can auto-complete the file name but this will not be in split or tab.
Consider the following directory tree:
root/include/file.hpp
root/source/file.cpp
root/images/file.png
The command line is inside the directory root.
In the vimrc file, there is set wildignore=*.png.
If you open Vim in the folder root and run :next */file.*, it opens only file.hpp and file.cpp.
However, if you launch Vim from command line with vim */file.*, it opens all three files.
So, when feeding it a filename, it first loads the files, then vimrc? Is there a way to ignore extensions when opening files with Vim through the command line? Or to make Vim load vimrc first?
In the first scenario, the glob expansion is done by Vim and thus obeys the rules in your vimrc.
In the second scenario, the glob expansion is done by your shell and there's no reason to expect it to obey the rules in your vimrc.
You can do something like $ vim -c "next */file.*", which essentially opens Vim without a filename and executes next */file.*.
Or you can exclude the pattern directly in your shell. Assuming you have extglob set, this can be done in bash with $ vim !(file.png).
When doing :next */file.* from within Vim, vim expands the wildcard and filters by wildignore. When doing vim */file.* from your shell, the shell expands the wildcard, and passes all three files to Vim.
Depending on your shell, this will probably work instead:
vim +"args */file.*"
By default Vim is looking for plugins and other stuff in ~/.vim.
Is there any way to tell Vim to search for plugins, etc. in ~/.other_folder and force it to ignore ~/.vim entirely?
Vim uses the comma-separated paths from 'runtimepath' to determine where to look for :runtime'd files.
You can change that option either in ~/.vimrc (which is sourced as the very first script), or by passing the set rtp=... commands on Vim's command-line via --cmd (the commands passed with -c are only applied after startup).
I code in Vim, not an IDE.
My source code is often nested 2-3 directories deep.
~/foo$ find
xyz
bar/abc
bar/def
~/foo$ vim
// inside of vim
:e bar/abc
... some work ...
:e <-- is there a way I can have this :e start in ~/foo/bar instead of ~/foo ?
Basically, I want :e to start the directory in "pathname of last edited file"
Thanks!
There's a lot of reasons not to like autochdir as it messes up some plugins and if you end up doing :e ../../../foo.txt you are not gaining anything. Just as an idea try this cmap I knocked up
:cnoremap red edit <c-r>=expand("%:h")<cr>/
then you can type :red and get
:e /the/path/to/your/current/files/dir/
(edit: perhaps use z instead of red as there are commands that start with red)
To expand the topic, also check out the FuzzyFinder plugin and some custom mappings to rapidly jump to common files you are always editing. Eg
10 or so of your regular files should be no more than 2 keystrokes away. It helps if they are systematically named
Here's an idea I use for django.
http://code.djangoproject.com/wiki/UsingVimWithDjango#Mappings
Try the autochdir option. It will automatically change the current working directory to whatever file was most recently opened or selected. In .vimrc:
set autochdir
For more info, :help autochdir
To always change the working directory to the current file's directory I have this in my .vimrc:
if has("autocmd")
autocmd BufEnter * :lcd %:p:h
endif " has("autocmd")
Sorry, but vim's :edit command takes a path which is interpreted relative to the present working directory of the vim instance.
You do have a :cd command which you could use to :cd bar then work for a while, then :cd ...
Hope that help some.
Some time ago I asked questions related to this on the vim mailing list: http://www.mail-archive.com/vim_use#googlegroups.com/msg03266.html Maybe you will find useful tips in that thread.
I tested a lot of plugins, but since CLI based GUIs are not my taste, I simply ended up using standard vim with a few configuration settings.
As honk pointed out, this line sets the working directory to the same as the file your working on:
autocmd BufEnter * lcd %:p:h
My other tip is to use the wildmenu. It makes it easier to get an overview of the files in your current directory when you go :e and then TAB. I'm a python programmer so the last line shows how to hide auto generated files that the python interpreter spits out, but you could use it to hide java .class files or c .obj files or whatever.
set wildmode=list:longest
set wildignore=*.pyc,*pyo
:cd changes directory
:pwd prints the current one.
why not just :E? Explore directory of current file.
:help :E
This isn't exactly what you wanted, but check out NERDTree.
On vim/gVim I just have cd C:/blah/blah at the top of my vimrc. I imagine it works on all platforms.
I personally use vagrant for each project so one CD is enough, but I think you can get vim to use different config files too, -u flag I think.
Or map a key to each project you have so pressing Ctrl+F1 does cd path/to/project/1 and Ctrl+F2 does cd path/to/project/2 perhaps?
Note: I don't use any plugins
By making use of the remote feature in vim, is it possible to reuse an instance of vim to load up multiple files as needed.
It will be nice to have that facility from within the same terminal instance.
I am more keen to have a tab based interface, which available in vim 7+
The scenario should be
Open terminal
vim file1.cpp
Edit - Save - Ctrl+Z to get to prompt
open another file
vim file2.cpp
Now we have file1.cpp and file2.cpp open in the same editor
Is that possible?!
I'm not sure if this can be done in exactly the manner that you're specifying, but something very similar can probably be done using a vim server running on your local machine.
Look into the :help remote.txt in Vim.
If your version of vim was compiled with +clientserver you can use vim to create a vim server, and then execute commands on it, e.g. opening another file.
The --servername switch can create a new server, and the --remote switch can send additional commands or files to it.
e.g.
vim --servername test file1.txt
vim --servername test --remote file2.txt
I've had a look, and the vim I'm using as standard on xubuntu on one of my computers doesn't have it, but there are some instructions here that may help if yours has it compiled. If it isn't, installing gvim and symlinking is apparently an option (as gvim has it included by default), or compiling the binaries from source.
Edit:
I've had more of a play with gvim and this doesn't look possible to do this within the terminal. Control-Z suspends the job at the process level. I thought it might work with screen, but no communication seems to take place unless gvim has launched in a graphical window,
This is easy to do if you compiled VIM with +clientserver, as Andy suggested in a previous answer.
I did the following:
I started up VIM as a server:
vim --servername abc
I suspended it with CTRL+Z and did:
vim --servername abc --remote ~/.cshrc
fg
Now VIM had ~/.cshrc open.
Then I did:
vim --servername abc --remote ~/.aliases
fg
Now VIM had one buffer with ~/.cshrc and another with ~/.aliases.
Then I did:
vim --servername abc --remote-tab ~/foo_bar
fg
And now I VIM had one tab with the two previous buffers open and another tab with ~/foo_bar open.
In call cases VIM was running in the terminal, not as a GUI.
I have a couple suggestions for you, though neither is exactly what you're talking about. The first is NERD Tree, which gives you a nice tree-based file browser for opening other files. Very handy. I also set up a hot key (ctrl+o) to open NERD Tree for me. I keep an alias of whatever project I'm on in ~/curr/trunk, so this always works for me:
map <C-O> :NERDTreeToggle ~/curr/trunk/<CR>
The other thing that I would suggest is to do away with ctrl+z. It's somewhat clunky, and everyone I know who uses that method tends to get lost and end up with 3 or 4 vim's running in the background. Take a look at how to open a shell for yourself. I use a map for ;s to execute a shell script:
map ;s :!~/.vim/shell.sh<CR>
Which executes:
#!/bin/sh
/usr/local/bin/bash -l;
I also have a bit of magic in my .profile for making it obvious I'm in VIM:
if [ "$VIMRUNTIME" != "" ] ; then
export PS1="\u#\h \W \t$ vim> "
fi
</2 cents>
You can split the current screen and open two (or more) files in the following way:
For a horizontal split, do:
:sp 'filename'
and for a vertical split, do:
:vsp 'filename'
To tab between the two, hit ctrl+w, then use an arrow key to navigate to whichever file you want to edit.
Also, if you want to just switch files (and only have one open), you can do this:
:e 'filename'
G'day,
Or if you want to have multiple files but use the whole vim window for one file at a time you can just enter
:e 'filename'
to open the new file. You can do this multiple times. To see what you've currently got open, enter
:ls
To bounce between the files you've got open you can use cntl-^ (shift-cnt-6) and that will alternate between the main and secondary files (shown with a % and # in the file list)
Or you can enter
:n b
where n is the number at the beginning of the file you want in the list shown by the 'ls'command.
HTH
cheers,
You can set the hidden feature on vim, to allow it to have multiple files open:
:set hidden
Then you can open as many files as you want, without bothering to save them every time you want to switch a "buffer":
:e 'filename'
You have several commands to navigate the buffers:
:bnext
:bprev
:buffers
Of course, as mentioned by samoz, you can split your screen to see multiple buffers on the same window.
I'd suggest to read this for a good introduction about vim, it will save you a lot of time.
Good luck!