Vim File Path Search Algorithm - vim

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

Related

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

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

Editable vimgrep string in command line

I use vimgrep a lot to navigate in files and usually use the last search from the history to modify the search pattern and run it again.
Is there a way to display in the command line an editable string like the one below, with the cursor already positioned between the two search pattern slashes (and the pattern being empty)?
:vimgrep // **/*[ch]|copen
I don't want to use a constant mapping (like the one at this vim tip) since I want to be able to add/change options (\c etc.).
I'd recommend using the command-line window for this (q: opens it from normal mode), since you
can edit the command with the regular normal mode keystrokes (and you get syntax highlighting too).
You can also move around in your history just like in a normal buffer. So ?vimgrep<Enter>nnn... will search for and move you to all your old vimgrep commands.
Just hit <Enter> as normal when you are done editing, or :q<Enter> to abort the command and quit the window like you would any other.
Finally, here's a mapping to quickly bring up your empty vimgrep template in the command-line window.
:nnoremap \v q:ivimgrep<Space>//<Space>**/*[ch]<Bar>copen<Esc>F/;i
Reference: :help cmdline-window

How to go to any buffer directly by searching the contents of all buffers in Vim, like pressing Ctrl+P in Sublime Text?

In Sublime Text 2, when I have a bunch of files opening, I can go to any opened file by 3 following steps:
Hit <Ctrl>+P.
Enter the pattern to search for. The editor immediately display the file which match the pattern while I am typing (without hitting <Enter>).
After the right file is shown, I hit <Enter> to select the file.
How can I have similar functionality in Vim to search through all buffers/tabs? I know there are plenty of plugins which allow me to search all buffers, but they are just not as simple as the above 3 steps to go to a file. I think this feature is particularly useful in navigation.
You can either use the vim CtrlP Plugin to search through all files in your current working directory (:pwd, changed with :cd dir) or you can use the Lusty Explorer plugin to search through all open buffers in vim
With CtrlP, it you would type ctrl+p, then the file pattern, then enter (or ctrl-t to open in a new tab)
With Lusty, you would type Leader lb (leader is \ by default), type the name of the buffer you have open, and hit enter or ctrl-t

How do I make Vim do normal (Bash-like) tab completion for file names?

When I'm opening a new file in Vim and I use tab completion, it completes the whole file name instead of doing the partial match like Bash does. Is there an option to make this file name tab completion work more like Bash?
I personally use
set wildmode=longest,list,full
set wildmenu
When you type the first tab hit, it will complete as much as possible. The second tab hit will provide a list. The third and subsequent tabs will cycle through completion options so you can complete the file without further keys.
Bash-like would be just
set wildmode=longest,list
but the full is very handy.
The closest behavior to Bash's completion should be
set wildmode=longest:full,full
With a few character typed, pressing tab once will give all the matches available in wildmenu. This is different to the answer by Michael which opens a quickfix-like window beneath the command-line.
Then you can keep typing the rest of the characters or press tab again to auto-complete with first match and circle around it.
Apart from the suggested wildmode/wildmenu, Vim also offers the option to show all possible completions by using Ctrl + D. This might be helpful for some users that stumble across this question when searching for different autocompletion options in Vim like I did.
If you don't want to set the wildmenu, you can always press Ctrl + L when you want to open a file. Ctrl + L will complete the filename like Bash completion.
I'm assuming that you are using autocomplete in Vim via Ctrl + N to search through the current buffer. When you use this command, you get a list of solutions; simply repeat the command to go to the next item in the list. The same is true for all autocomplete commands. While they fill in the entire word, you can continue to move through the list until you arrive at the one you wish to use.
This may be a more useful command: Ctrl + P. The only difference is that Ctrl + P searches backwards in the buffer while Ctrl + N searches forwards... Realistically, they will both provide a list with the same elements, and they may just appear in a different order.
set wildmode=longest:full gives you a Bash-like completion with:
suggestions in a single line
Tab completing only what is certain
Right/Ctrl-n | Left/Ctrl-p to select suggestions.
From the help:
If you prefer the <Left> and <Right> keys to move the cursor instead
of selecting a different match, use this:
:cnoremap <Left> <Space><BS><Left>
:cnoremap <Right> <Space><BS><Right>
Try using :set wildmenu. Apart from that, I'm not sure what exactly you're trying.
Oh, yeah, and maybe try this link: link

Filename completion in reverse order

To open a file in vim, I usually type ":e " and then hit tab until the file I want appears.
However, I always get in a rhythm and inadvertently go ONE past the desired file. Without knowing how to move backwards, I end up tabbing all the way to the end and repeating the whole process.
Is there a way to perform the filename completion in reverse order?
Shift-Tab goes backwards.
You can also use set wildmenu to get a list of matching file names above the status bar when you do file name completition with Tab. Then you can select the file name with the arrow keys from this list.
Shift+Tab and Ctrl+P both go backward.
However Shift+Tab only works with the GUI [1]. Since I am using vim and not gvim, Shift+Tab would not work. Ctrl+P works perfectly.
[1] And on the Amiga and MS-DOS. See ":help cmdline-completion" for more info.
If you got here because your vim autocompletion starts with the last item when you use "Tab", cycles backward from there AND you're using the Supertab plugin, here is your solution: https://stackoverflow.com/a/17105393/332451
let g:SuperTabDefaultCompletionType = "<c-n>"

Resources