Vim: Making Auto-Completion Smarter - vim

I use ctags, taglist, etc., to have auto completion in Vim. However, it is very limited compared to Visual Studio intellisense or Eclipse auto-completion. I am wondering whether it is possible to tune Vim to:
Show auto-completion whenever . or -> are typed. But only after some text that might be a variable (e.g. avoid showing auto completion after a number).
Show function parameters when ( is typed.
Stop removing the auto completion list when some delete all characters after . or ->: When I enter a variable name, then press . or -> to search for a certain member, I frequently have to delete all the characters I type after the . or ->, but this makes Vim hide the auto completion list. I would like to keep it visible unless I press Esc.
Showing related auto completion: When I type a variable and press ^X ^O, it usually shows me all the tags in the ctags file. I would like to have it showing only the tags related to the variable.
Thanks for the help.
EDIT: Some people are voting for this question, but no body seems to know the answer. So just wanted to mention that you don't have to provide a complete answer; partial answers to any of the mentioned points would be good also.

AutoComplPop is what you need.

For (1) when working with C++ or C clang complete is a really nice option

To make vim trigger a certain behavior when a key is pressed you need to map the key to a function.
For instance to map the key . to call some type of completion when in INSERT mode you would need to do:
:inoremap <expr> <buffer> . MyFunction()
and then the function would need to evaluate the context where it was called and present an appropriate answer to the user.
Edit: This is the basis of how clang complete mentioned by #honk works.
I'm not sure if you can customize the behavior of omnifunc to meet your needs but on my experience, I never went too far. As #Mikhail said, you would need to keep track of things which in practice means interpreting or even running the code to some extent.

I use vim every day, and I'm not aware of any existing script that may do this. This action would require understanding of classes and keeping track of variables. someObject-> means that VIM would know what class the variable someObject is, and then be able to search methods/variables within that class.
Writing scripts for vim is relatively easy, though like you've commented - no one has answered this yet. Up vote from me.

I would love to have that same functionality that you are looking for and just came across a promising plugin:
https://github.com/Shougo/neocomplcache looks like it could be the new autocomplpop, and seems to work quite well during my initial trials... now to configure the omni completion to work with scala~

I've recently discovered YouCompleteMe, it behaves similarly to the Visual Studio autocomplete tool. A demonstration can be seen here:
https://www.youtube.com/watch?v=YuMyHAHF0xs

In any case, I recommend YouCompleteMe (YCM). It provides (fuzzy) matching of identifiers of your current file, as well as path-completion, integration with external completion engines,...
ad 1)
If you like the semantic completion of eclipse, use eclim to integrate vim with eclipse. (alernatively use another semantic engine for YCM)
ad 2)
These 2 play nicely together btw.,: YCM can even provide the function definition (= parameter list) of the recently completed function!
ad 3)
that's what YCM does anyways
ad 4)
not quite sure, what you mean by that one. never used ctags!
P.S.: I strongly recommend using UltiSnips and Tagbar (and if you like UndoTree) additionally, what makes vim a perfect IDE for me.

Related

Run a shortcut event on key press in vim

I am using clang_complete with vim which supports autocomplete for variables using short cut <Ctrl-x Ctrl-u>. But I want autocomplete to happen with every keypress i.e. whenever I press a character, autocomplete list shown be shown.
I found that CursorMovedI is an autocmd-event in vim but I could not find any help on autocmd-event.
Please help me find out the way to make autocomplete possible on every keypress.
You may be used to that feature from IDEs, but I would recommend against this in Vim. The popup will interfere with editing, if only by slowing down Vim.
Nonetheless, if you would like to give this a try, there are plugins that can achieve that. AutoComplPop is an old (and I think by now unmaintained) plugin that provides this functionality; by default for built-in completions, but you can also configure user completions.
There may be other plugins (YCM?, neocomplcache?) that provide similar functionality, so do some research. If you still would like to implement such yourself, you probably find useful information in those, too. (But be warned that such implementation isn't trivial.)

How do I customize three letter sequences in Vim Latex-Suite?

I installed Latex-Suite for Vim, and I like it very much, but I'd like to be able to customize the environment mappings that came by default, and add new ones. For example I want to edit the equation environment that appears typing EEQ and move around some elements, like the \label{} command. How can I do this? I've been scanning everything inside my /usr/share/vim/vimfiles/ftplugin but I can't find a way to do it (or I just don't understand what those files are).
You want to check out the documentation on Macro Customisation, specifically the Tex_Env_{name} bit.
In short, if you want your theorem snippet to look like
\begin{theorem}
<++>
\end{theorem}<++>
then you want a line like
let g:Tex_Env_theorem = "\\begin{theorem}\<CR><++>\<CR>\\end{theorem}"
in your vimrc.
Note the backslashes to escape carriage-return, and double-backslash for normal backslashes.
The <F5> functionality (press F5 after typing an environment name, i.e. figure<F5>) should work out of the box, but you may need to refresh the three-letter code. This is more hassle than it needs to be, but something like
autocmd BufNewFile,BufRead *.tex call IMAP('EFI', g:Tex_Env_figure,'tex')
will do the job.
The answer to the question you asked comes with a caveat, which is that Latex-Suite is an enormous amount of code that is very hard and annoying to modify, and which does not play nicely with other plugins. This falls into Latex-Suite's philosophy that it's the only plugin you need for editing latex within vim.
That said, you want to look in /path/to/ftplugin/latex-suite/envmacros.vim. Searching for EEQ will lead you on the path to understanding the set of calls that latex-suite performs. I would like to reiterate that many functions are deeply intertwined.
On the other hand, there is a very easy way to have very easily customizable environments, which are snippets. See the UltiSnips page for a good example of how this works. These are designed for customization and extremely easy to write.

How to understand code with vim?

Vim is a nice editor and I use it for many tasks.
However, when it comes to start working on a new (possibly huge) codebase, I don't feel comfortable using it to go around the code with the objective of understanding how things work.
For example, if I want to see where a C++ function is used, I can :vimgrep for that function in every **/*.cpp files and :copen the quickfix window to jump on every occurrence... of that string.
If I do the same with e.g. Eclipse (call hierarchy of a C++ method), that will not be just a string, but a C++ method defined in an object, so I will get a precise indication of the usages of that function (and not also a function with the same name defined in another class).
So the question is, how to make vim a powerful tool to analyze code?
Subquestions:
Are there any vim plugins designed for this?
Does it make sense to use vim to only analyze code? Probably external tools (e.g.: OpenGrok) can do the job?
Vim is a text editor. What you want is almost completely orthogonal to editing text and completely outside of Vim's own abilities.
However, Vim is quite good at using external tools like ctags and cscope for navigating within a project. Supposing you have created a tags file and/or a cscope.out database, Vim has a bunch of commands you can use to "jump to definition", "jump to usage", etc.: :ts[elect] foo, <C-]> over a function name and so on… You can find all the info you need in :h ctags and :h cscope.
If you are curious, GNU GLOBAL is another alternative. Another pro of cscope is that it comes with its own TUI that you can use in your shell.
The only plugin offering a cscope (+ ctags) interface I know of is CCTree which seems to be limited to C.
There are a bunch of ctags oriented plugins like TagBar or TagList you could try but note that, while ctags is limited to definitions, cscope can also do usage and callers.
You should keep in mind that these tools are code indexers: you shouldn't expect them to "understand" your code or be even remotely as precise as IDE tools. However I love Vim, I'd suggest you use a tool better suited to that task than a text editor.
When I switched from Netbeans to Vim, I felt the same as you. I missed Netbeans feature to see any function definition upon a right click. Disclaimer: I use Ruby, Javascript mainly and sometimes PHP
I tried ctags, but found it is not so accurate and not so clean. I also tried plugins Tagbar and Taglist using together with ctags. Tagbar is a bit heavy in my opinion, takes lot of CPU and memory when handling tags. Taglist is better, but the best use case is to browse long files instead of tags.
Finally I gave up using ctags.
Later I found there are better solutions specific to language. For example, for Ruby there is a plugin to show ri doc of any function within installed gems(libs), with only one key.
But I still don't use that often as my habit already changed. I like things to be lean, to be in there right places, and to be fast.
Now I feel comfortable by:
Using tmux together with Vim. Check doc and verify code in console when needed.
Use snippet plugin(Neosnippet) to store frequently used codes, methods. The snippets management in Vim is far better and flexible than any IDE I've seen.
Use brain to store more, with less touching of mouse.
Hope these help.
There is a plugin called fly.vim that is super awesome to browse source code. It makes use of a cscope database and provides simple navigation mechanism. Combine it with autotags plugin that generates and maintains cscope and ctags for a project in a central location, and you can switch between different code bases with ease.
I was using Source Insight to browse the Linux Kernel source code and when I switched over to this combination, I had nothing to complain. It may take some time and/or effort to get in speed with this setup, though. If you know how ctags and cscope work, then, probably you'll pick it up in less than an hour. But the advantages: cscope indexes code fast, vim uses cscope fast, fly.vim queries through cscope and displays it fast, and in a usable format. Plus, it maintains jump history.

TextMate's Jump to Function in VIM?

Recently I've been trying my hand at using vim instead of TextMate and one of the features that I've missed most in VIM is TextMate's jump to method function (CMD + Shift + T for those who don't know). From looking around I havn't seen any particular way to emulate this functionality and was wondering if anyone here has had experience with this sort of functionality in VIM.
Thanks in advance for any answers
Patrick
You're looking for vim's 'tags' functionality ... I answered a similar question about tags here: How to implement own tag jump in VIM with CTRL-]?
This functionality has been implemented in fuzzyfinder using :FufBufferTag. See the ticket
I'd love to hear good suggestions as I use Vim all the time but haven't used TextMate. I do the following things which slightly overlap.
Search for d-e-f-space-<first few letters of function name>. So to go to function foo (in Python or Ruby, and within the same file of course), I type /def fo and I'm there. I also have incremental search enabled in Vim.
Use marks for functions which I visit often. So I'll ma at the function definition and then 'a back to it later. I know it's not function definitions but it is a crutch.
you can create a tags file with ctags http://ctags.sourceforge.net/
basically $ctags -R
Then once you're in vim :set tags=/path/to/tagsfile
this will also be any tag so not just class names, methods, etc. In normal mode ctrl-] on the method/class/ and it will jump to that position.
You can also use the taglist plugin which will display current tags in a side window. ctags
I had pretty much the same problem and I found a quick and dirty solution (paste this in your .vimrc and call by typing :LS)
function! s:ListFunctions()
vimgrep /function/j %
copen
endfunction
command! -bar -narg=0 LS call s:ListFunctions()
If you require more functionality then Exuberant Ctags will do better for you
I'm using CommandT for file searching, then / to search for a particular function. However, the real issue is with CSS. Cmd Shift T in Textmate enable quick jumps to a particular CSS class, and that is a huge time-saver.
CTags doesn't support CSS parsing, unless you re-compile with a patch (found via google), but I'm not even sure if we can do fuzzy searching for CSS classes like in Textmate. I really miss the Cmd Shift T feature.
I've written a TextMate Bundle command (you can easily assign it to Ctrl+] for example) that lookup for the definition of the class or method under the caret and displays it in a tooltip, along with the file name and the line where it was find.
Check it out: Add a shortcut to TextMate to lookup a class or method definition in a tooltip
Hope you'll find it useful!
The feature described in this question has many different names depending on the IDE/Editor:
In Resharper it's called "Goto File member"
In Sublime Text 2 it's called "Goto Symbol"
In PyCharm it's called "Goto Symbol"
The feature is essentially the same though in all of the above implementations (and I assume it's very similar in TextMate as well). The feature brings up an interactive list of methods/functions (and potentially also includes member variables/properties).
The list allows interactive filtering by typing the name of a methods/functions/etc. The list also usually allows the use of arrow keys to select a method/function/etc. Hitting the enter key with a method/function/etc selected navigates to the line in the current file where the selected method/function/etc is defined.
Of all the existing answers in this question the only one that I see which seems to provide a reasonably similar implementation of this feature is to use the command:
:FufBufferTag
in vim's FuzzyFinder plugin.
The answer which suggests using the taglist plugin is not a good solution, because the functionality offered by the taglist plugin is quite different from the feature. The taglist plugin offers similar functionality - the ability to view an outline of methods in the currently file, but it does not offer an interactive way to filter that list in realtime. The taglist plugin does allow you to search the tag buffer, but that's not nearly as convenient as the "Goto symbol" functionality offered in other editors.
I wanted to provide an alternative suggestion here, which is to use the command:
:CtrlPBufTag
in the excellent Ctrlp vim plugin. In my opinion this by far the best implementation of the "Goto Symbol" feature currently available in vim.

How to create short snippets in Vim?

I have recently started using Vim as my text editor and am currently working on my own customizations.
I suppose keyboard mappings can do pretty much anything, but for the time being I'm using them as a sort of snippets facility almost exclusively.
So, for example, if I type def{TAB} (:imap def{TAB} def ():<ESC>3ha), it expands to:
def |(): # '|' represents the caret
This works as expected, but I find it annoying when Vim waits for a full command while I'm typing a word containing "def" and am not interested in expanding it.
Is there a way to avoid this or use this function more effectively to this end?
Is any other Vim feature better suited for this?
After taking a quick look at SnippetsEmu, it looks like it's the best option and much easier to customize than I first thought.
To continue with the previous example:
:Snippet def <{}>():
Once defined, you can expand your snippet by typing def{TAB}.
Snipmate - like texmate :)
http://www.vim.org/scripts/script.php?script_id=2540
video:
http://vimeo.com/3535418
snippet def
""" ${1:docstring} """
def ${2:name}:
return ${3:value}
As another suggestion (although slightly different) using vim's built in functionality:
:iabbrev def def(): #<LEFT><LEFT><LEFT><LEFT><LEFT>
Now whenever you type def followed by a space or other non-word character, it will expand to the same as what you've given as the output of SnippetsEmu (the space comes from the space you entered to trigger the completion).
This approach doesn't suffer the "lag" issue you encountered using :inoremap, and is built-into vim. For more information on this feature, look at :help abbrev.
You may be concerned that being triggered by space not tab it will trigger unnecessarily, but in general vim is pretty smart about when to trigger it. The issue can be additionally mitigated by enabling the abbreviation only for certain file-types (eg, python):
au filetype python :iabbrev ... etc
Snip[ets] (Manager|Emu|Mate|.vim) is of course also a perfect solution, but it's nice to be aware of the alternatives (especially when they are built in).
If SnippetsEmu is too heavy or ambitious for what you need (it was for me), I wrote a plugin that manages snippets based on filetype. It even has tab completion when picking the snippet! :)
Get it here: snippets.vim
I just installed UltiSnips. There’s a good article that explains why you might choose UltiSnips: Why UltiSnips?
I haven’t used any of the other snippet plugins; I decided to take the plunge with one that seemed full-featured and would be able to accommodate me as I gain more Vim skills and want to do more sophisticated things.
SnippetsEmu is a useful snippets plugin.
As noted by MDCore, SnippetsEmu is a popular Vim script that does just that and more. If you need only expanding (without moving back the caret), you can use the standard :ab[breviate] command.
:ab[breviate] [<expr>] {lhs} {rhs}
add abbreviation for {lhs} to {rhs}. If {lhs} already
existed it is replaced with the new {rhs}. {rhs} may
contain spaces.
See |:map-<expr>| for the optional <expr> argument.

Resources