How can I create a map combination using Tab in command mode? - vim

I want to create a key combination that would copy the text under the cursor, open the :find command, yank the word and then press Tab to autocomplete to the first filename in the list, so (in 99% of cases) I would have just to press enter to open the file.
map <Leader>o yw:find <C-R>"<Tab>
However, when I press <Leader>o, I get :find FileName^I in the command line instead. How can I make it react the same way as if I pressed the key myself?

You need the wildcharm options:
set wildcharm=<C-z>
map <Leader>o yw:find <C-R>"<C-z>
See :help 'wildcharm'.
Here is a more solid, non-recursive, alternative that doesn't clobber the unnamed register for no reason:
nnoremap <leader>o :find <C-r><C-w><C-z>

The gf (goto file) command should do the same thing as your mapping. This opens the file whose name is under or after the cursor.
If not getting the expected behaviour, it's worth checking the contents of the isfname option (use set isfname? to check). This specifies a list of characters that are treated as valid characters for file path names.
It’s also worth checking / setting the contents of Vim’s path option which lists the directories which are searched when using gf, :find and similar commands, e.g., the default setting on MS Windows is .,,:
. searches relative to the directory of the file currently being edited
,, (empty string) searches the current directory; use the cd command to check (or set) your current directory.
See
help gf
help isfname
help path

Related

Vim File Path Search Algorithm

TLDR. howto change vim path/file name search algorithm from cyclic autocompletion to incremental autocompletion. (like when autocompleting file paths in ubuntu terminal).
When opening a new file for editing in vim, for example using :vsp or :tabe the algorithm used when pressing the tab key to predict the next part of the path/file for the targeted file, has inconvenient behavior that I would like to change.
For example, i have a directory with three files:
/one.txt
/onetwo.txt
/onetwothree.txt
When attempting to open onetwothree.txt from a vim instance opened in the same directory, I would type :tabe o then press the tab key and vim will autocomplete the file name/path, to :tabe one.txt. I must then press tab again to change the autocomplete to :tabe onetwo.txt and then again a third time to get :tabe onetwothree.txt, before pressing enter to open the file. (algorithm 1) The tab algorithm has the behaviour of cycling through the complete path/file names one by one.
In the ubuntu terminal the search behaviour is much better and works that typing :tabe o the pressing tab will only partially autocomplete to give you :tabe one. Then typing t followed by tab again will autocomplete from :tabe onet to :tabe onetwo and then pressing t and tab again will autocomplete from :tabe onetwot to :tabe onetwothree.txt. (algorithm 2) The tab algorithm has the behaviour of partially completing the path/file name.
With the first algorithm the behaviour of pressing tab to cycle through the complete path/file names one by one can be inconvenient when working with lots of files. In the second algorithm shown used by the ubuntu terminal tab autocomplete has the behaviour of partially completing the path/file name and allows one to complete the path quickly and accurately.
I realise in this trivial example it takes two more key presses with the second algorithm, but in the non-trivial examples with many files cycling through every option is painful.
How can I change the filepath search algorithm? Is there a setting in the .vimrc that specifies it?
You will need to enable :help 'wildmenu':
set wildmenu
and adjust its behaviour with :help 'wildmode':
" just an example
set wildmode=longest,list
from :h cmdline-completion
If you like tcsh's autolist completion, you can use this mapping:
:cnoremap X (Where X is the command key to use, is
CTRL-L and is CTRL-D) This will find the longest match and then
list all matching files.
If you like tcsh's autolist completion, you can use the 'wildmode'
option to emulate it. For example, this mimics autolist=ambiguous:
:set wildmode=longest,list This will find the longest match with the
first 'wildchar', then list all matching files with the next.
so either map <c-l><c-d> in command mode, or adapt wildmode to longest,list

VIM: How to open another file from same location as an already open file

Let's say I am in my home directory. I open a file that is present in some deep nested directory structure:
vim /some/really/long/path/file.txt
Now, within vim, I want to start a vertical split with another file from that same long location (but I don't want to change the current directory to that path, I still want to be in the home directory).
A layman (like me) will do something like:
:vsp /some/really/long/path/file2.txt
But I want to find out from all you VIM geniuses out there, is there an easier way to do this?
On the same note, if I had multiple files already open residing in different paths, can VIM automatically assign some sort of internal variables to all the locations? And then when I want to start a new VSP or SP with one of the files from one of those locations, I simply use those internal variables?
Try this:
:vs %:p:h/otherfile
as %:p:h gives you the path of the current file.
See :help %:p for more info.
Edit another file in the same directory:
:vs %<Tab><C-w><C-w><C-w>file2<Tab>
With a mapping:
nnoremap <key> :vs <C-R>=expand('%:p:h')<CR>
If you like more navigation than typing the commands, a convenient option could be the use of the embedded Explore command, which opens a window with the list files in the directory of the file in current buffer. Then you can navigate with the cursors and press v when over the file you want to open in a vertical split.
A convenient way is to map the Explore command, like:
" open embedded file system navigator
map <leader>\ :Explore<cr>
Press <leader>\ and navigate to the file, then press v.
With some versions of vim, the Explore window stays open after pressing v -- in that case, if you want to avoid extra burden to close the Explore window, you can do first the vertical split with :vsp, invoke :Expore and open the desired file by pressing Enter.

When in Vim insert mode, is there a way to add filepath autocompletion?

I write a lot of shell scripts and I am constantly having to enter in filepaths. I am wondering if anyone knows of a way to get Vim to autocomplete filepaths while in insert mode, just like when you are in your favorite shell you tab to complete the path of the directory or file.
Extra credit if you can get CTRLD functionality of the shell into Vim insert mode (i.e. to see what files/directories are in the current path).
For file name omni completion, you can use:
Ctrl-XCtrl-F
There's ctrl-x ctrl-f
:he compl-filename
To build on #CMS and #michael excellent answers
When using ctrl+X ctrl+f command sequence it will display a list of files in the current directory. I spend a minute looking for the right key to move up and down between the different filenames. The correct keys are Ctrl-n and Ctrl-p. You can use almost any other key (like Space) to select and continue typing.
In addition, if you are not already at the file/directory you would like to insert, you can go down a file tree structure as follows:
Optionally enter some part of the directory. You can even use ../../ for example!
Press ctrl+X ctrl+f and select the first item in the tree from the list.
Next press ctrl+f again while the correct item is highlighted to display a list of the next level down the directory tree structure.
You can keep doing this until you find the directory/file you would like to insert in the document.
I experienced similar problem. I found solution like:
sudo apt-get install realpath
And in VIM naviagte to file with in normal mode type:
:r !realpath /path/to/file
When you are navigating in non-insert mode after !realpatch you are able to use our key button.
VOILA! TAB is working again!
edit: excuse me, I landed here from a google result for "vim insert file absolute path"
(first leave insert mode with esc or ctrl+c) ;)
from normal mode, on a blank line
!!readlink -f #
this will run a command, and substitute # with the current file name, readlink will resolve a canonical name, and !! will write the output where the cursor was
note, this needs to be done on a blank line, as the content of the line will be fed as stdin to the subcommand.

Easily open include filenames in vim?

Basically, I'm editing files that have include file names and I want a quick way of opening the file without having to type the path/filename:
include('inc/doctype.inc.php');
Is there an easy way to do this? (Ideally, I'd like to use :tabnew to open the file in a new tab.)
Thanks.
Use the gf shortcut. Move your cursor on a path string, the exact cursor position is not important and then press gf in normal mode. gf stands for "goto file".
See vims help page with :h gf:
Uses the 'isfname' option to find out which characters
are supposed to be in a file name. Trailing
punctuation characters ".,:;!" are ignored.
Uses the 'path' option as a list of directory names
to look for the file. Also looks for the file
relative to the current file.
Uses the 'suffixesadd' option to check for file names
with a suffix added.
If the file can't be found, 'includeexpr' is used to
modify the name and another attempt is done.
To get back, use Ctrl-o in normal mode.
Note: This command brings the cursor position to older positions in the jump list. The opposite command is Ctrl-i which brings the cursor to newer positions in the jump list.
Put the cursor on the filename, then Ctrl+wgf
:h ctrl-w_gf

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