How to autocomplete c or c++ keywords in vim - vim

For example, when I type 'inclu', is there a method which can complete it to 'include'?
Thank you.

Most of vim's (complex) auto-completion is done via the ^X key mapping. ^X^] will autocomplete based on tags generated by ctags(1). ^X^P looks for previous keywords in the file that can be used for completion. ^X^K looks into a configurable dictionary for completion words. ^X^I looks into included files and pops up a menu for completing keywords from within those files. ^X^D completes from #define.
Perhaps the simplest way to get what you're after is to fully type #include <...> once in your file. The second file to be included could then be handled via #incl^X^P and then keep going.
If you want to put slightly more effort into it, create a ~/.vim/dict file with the keywords you want to autocomplete, add the file to the dictionary variable (:help dictionary), and use ^X^K to insert it.

Maybe, any plugin like Snipmate or UltiSnips will be helpful for you.

You may want to try the Vim plugin Supertab. If you do, I suggest installing it using Pathogen.

Snipmate does this by default. type 'inc' and press Tab, it will convert into
#include <stdio.h>

You could set up some Vim abbreviations to do this for you.
iab inc #include ""
iab Inc #include <>
Then by typing inc<SPACE> Vim will automatically expand this to #include "". You could add all kinds of abbreviations to reduce the number of keystrokes required.
If you want to push this further, I'll share a little ongoing experiment of mine to create a C++ 'shorthand'. Though it certainly reduces the number of keystrokes required to input code, I haven't used this long enough to determine if the added mental complexity of remembering the shorthand is worth it. (Probably not!)
You will need to install UltiSnips for this to work. You could probably do most of this using Vim's abbreviation feature, but I've found it works best with a dedicated snippet completer.
Once UltiSnips is installed you will already have some C and C++ snippets ready to use, including the #include "" example mentioned above.
I've added the following (plus many, many more!) to my cpp.snippets file.
snippet sptr "std::shared_ptr< type >"
std::shared_ptr< ${1:type} >
endsnippet
When I want a shared_ptr I type sptr and press the snippet completion key. UltiSnips completes this as std::shared_ptr< type > with the word type selected so I can continue entering the template type without pausing.
This contrived example shows some more of the shorthand. This is what I could type:
// <C> is where I would press the UltiSnip complete/next key.
fun<C>sptr<C><C>load_widget<C>cu32<C>offset<C>, cc<C>name<C>ret<C>msptr<C>widget<C>offset<C>name<C>;
Which expands to:
std::shared_ptr< widget > load_widget( const std::uint32_t offset, const char* name )
{
return std::make_shared< widget >( offset, name );
}
A rough count shows this reduces approximately 136 keystrokes down to 100. With Omnicomplete or YouCompleteMe plugins, this is reduced further as variable and function names can often be completed after the first 2 or 3 characters have been entered.
I try to stick with this pattern when creating a shorthand for types: [c]type[r|p]. [c] is optional const, [r] or [p] for optional reference or pointer. (r and p and easier for my to type than & and *). For example, std::string has the following shorthand:
str = std::string
strp = std::string*
strr = std::string&
cstr = const std::string
cstrp = const std::string*
cstrr = const std::string&
So cstrr, the most common of these in my code, reduces 19 keystrokes (there's a trailing space) down to just 6.

you should install omni plugin: omni autocompletion

Related

Faster way to type control flow statements (in C and php etc)?

I am new to Vim and I need to speed up my typing for this kind of statements.
if (a == 'e') {
foo();
}
In other text editors, I usually type if() {} first and then insert the text in to the parenthesis and curly braces. If I do this in Vim, I need to switch back to normal, move cursor to middle of () then middle of {}... switch between i and esc ...
What is your suggestion on typing this kind of syntax for Vim beginner? I would be grateful if you can show me the commands for that example step by step.
This is a job for snippet expansion. Take a look at SnipMate or UltiSnips.
snippets are like the built-in :abbreviate on steroids, usually with parameter insertions, mirroring, and multiple stops inside them. One of the first, very famous (and still widely used) Vim plugins is snipMate (inspired by the TextMate editor); unfortunately, it's not maintained any more; though there is a fork. A modern alternative (that requires Python though) is UltiSnips. There are more, see this list on the Vim Tips Wiki.
There are three things to evaluate: First, the features of the snippet engine itself, second, the quality and breadth of snippets provided by the author or others; third, how easy it is to add new snippets.
There are two approaches that solves your goal:
abbreviations
and snippets engines
Abbreviations and the old way of doing things. You just type if and space, and tada! You'll find plenty examples around the web. Only a few will be context-sensitive (i.e. they won't expand within comment or string contexts), or able to take the current project spacing style into consideration. In lh-cpp, you'll find the usual control-statement abbreviations for C and C++, they'll need to be duplicated for similar languages (a runtime ftplugin/c/c_snippets.vim from a php ftplugin should do it in your case)-- in lh-misc I support a couple of others languages (for VimL and shell)
Snippet engines are the trendy way of doing the same thing. This time, you will be able to type i or if and then <tab> (or CTRL+SPACE, or ...). Control-statement snippets won't need to be aware of the current context as we need to explicitly require the expansion. Others have already given links to the trendy snippets engines. Snippets from lh-cpp (which relies on mu-template) take the project style into account when expanding control-statement snippets (i.e. some projects want ) and { on a same line, other want a newline in between, ...)
Here's my answer in case you want to go with vanilla Vim.
In the majority of the cases I guess there is no point in entering the parentheses first and filling in the condition later, just type it all in right away:
if (a == 'e')
Then you can either continue
by typing {}<ESC>:
if (a == 'e') {}
^ cursor is here
The cursor is already placed so you can continue with i<CR> and type the body (if properly configured, Vim should indent for you).
or by typing {<CR>}<ESC>:
if (a == 'e') {
}
^ cursor is here
Then you can enter the body by pressing O (open new line above cursor). Possibly Vim also automatically indents here (it doesn't in my configuration).
If you really want to fill in the condition after you have entered this:
if () {
}
^ cursor
you can do so by typing kf(a.
If anybody knows better ways to do this without plugins, suggestions are welcome.

How do I configure VIM to use different syntaxes in different parts of a file?

I have a file that works like this:
:: JavaScript
function whatIsThis(){
return "an example";
}
:: Haskell
main = putStrLn "is this is an example?"
:: C
#include <stdio.h>
int main(){
printf("yes, it is");
};
In other words, a line starting with :: determines the syntax of the next lines until another :: is found. Is there any way to configure vim to highlight the syntax of those blocks correctly?
Have a look at my SyntaxRange plugin; it offers both a :[range]SyntaxInclude command, and functions to define regions (based on start and end patterns) to highlight with a particular syntax. For your example:
call SyntaxRange#IncludeEx('start="^:: Haskell" end="^::"me=e-3', 'haskell')
call SyntaxRange#IncludeEx('start="^:: C" end="^::"me=e-3', 'c')
call SyntaxRange#IncludeEx('start="^:: JavaScript" end="^::"me=e-3', 'javascript')
If you want to have full editing capabilities for each separate part (i.e. filetype-specific settings, customizations, mappings, commands), not just specific syntax highlighting, you won't get around having a separate buffer for each fragment (as these things are all tied to the buffer's filetype).
With the NrrwRgn - A Narrow Region Plugin similar to Emacs, you can cut up the original file into separate buffers (shown e.g. in split windows), and the plugin syncs any changes back to the original automatically.

How to script in Vim to yank only lines from a visual selection (or fold) that match a certain pattern?

I'd like to add a command to my .vimrc that allows to, within a visual selection or the range of the current fold level to
yank all, but only those lines that match a certain pattern.
and as a bonus to
reverse their order
and
perform a small pattern substitution.
Specifically the idea is to reduce the legwork in writing the common C idiom fail-goto-rollback, i.e. (can be found in lot of C projects most prominently the Linux kernel) if the body of a function (or a block) is this
someErrorType errorcode;
if(fail1) {
errorcode = someError1;
goto error_1;
}
prepare_a();
if(fail2) {
errorcode = someError2;
goto error_2;
}
then the result of the desired transformation shall be this.
error_2:
/* <insert cleanup code operation that did not fail1 here> */
error_1:
for the "yanking all", you can do:
normal mode: qaq to clear reg a
do visual selection
press :, vim will auto add '<,'>, then g/pattern/y A<Enter>
all your needed lines are in reg a, you can "ap to paste. for the reversing order requirement, I don't understand. What output do you expect. A concrete before/after example may help.
For adding boilerplate code, the usual solution is via a snippets plugin, which solves this (at least partially) in a generic way, instead of building a (possibly brittle) special solution with Vim built-ins.
snippets are like the built-in :abbreviate on steroids, usually with parameter insertions, mirroring, and multiple stops inside them. One of the first, very famous (and still widely used) Vim plugins is snipMate (inspired by the TextMate editor); unfortunately, it's not maintained any more; though there is a fork. A modern alternative (that requires Python though) is UltiSnips. There are more, see this list on the Vim Tips Wiki.
There are three things to evaluate: First, the features of the snippet engine itself, second, the quality and breadth of snippets provided by the author or others; third, how easy it is to add new snippets.

Vim macro: log/variableize selected object

Is there some sort of Vim plugin that would allow me to do something like this, given the code:
function something (arbitraryObject) {
arbitraryObject.something = doesNotMatter;
}
Then let's say I just select the word arbitraryObject in the function body, I'd like an easy way to write a macro that, given a short key combination or command-mode command, could give me something like:
function something (arbitraryObject) {
arbitraryObject.something = doesNotMatter;
console.log(arbitraryObject);
}
or...
function something (arbitraryObject) {
arbitraryObject.something = doesNotMatter;
window.arbitraryObject = arbitraryObject;
}
Note that I'm not asking what this macro would actually look like, I'm curious if there are built-in tools or plugins that make the creation of things like this particularly easy.
I know that you aren't asking for the specific macro, but it's easiest to learn these types of things by example. The first one (console.log) can be achieved through this mapping:
:vmap <leader>il y<esc>oconsole.log(<c-r>");<esc>
Likewise, the second one could look like this:
:vmap <leader>iw y<esc>owindow.<c-r>" = <c-r>";<esc>
Can you spot the similarities? <leader>il means that the command binds to the leader key (usually ,) followed by i followed by l. You can check what the following commands mean by using :help [key] in vim, but the mappings basically yank (copy) the selected text, enters a new line (Esc, o) and then appends some text followed by Ctrl+r and ", which inserts the yanked text.
One option would be to use something like snipMate.vim and have snippets for your various tasks. For example, you could create these snippets:
snippet cons
console.log(${1:variable});${2}
snippet wind
window.${1:attribute} = $1${2}
Then you could do something like yocons<Tab><C-r>"<Tab>, or likewise yowind<Tab><C-r>"<Tab>. You could also use yiw instead of visually selecting too. I like an option like this because then you can easily make it applicable to only a particular type of filetype (e.g. javascript) and continue to extend your already existing snippets.
nmap <Leader>l o<esc>pv^"xygv[ygvdiconsole.log(<esc>a"<esc>pa",<esc>"xpa);<esc>
This is better alternative, since it quotes strings with help of vim-unimpared. Just yank text, you need to log and use this key binging. It converts
this.$el.find("input,select,textarea")
to
console.log("this.$el.find(\"input,select,textarea\")",this.$el.find("input,select,textarea"));

Is there a "verbatim" mode for the vim map command?

I am trying to set up some useful coding templates in vim, for example I have mapped
map `cl iclass <+CLASSNAME+><CR>{<CR><Esc>Iprotected:<CR><+PROTECTED MEMBERS+><CR><Esc>Ipublic:<CR><+PUBLIC INTERFACE+><CR>};<CR><++><CR><Esc>3kv<0v3k<2k
so that when I type `cl in vim I get
class <+CLASSNAME+>
{
protected:
<+PROTECTED MEMBERS+>
public:
<+PUBLIC INTERFACE+>
};
<++>
(so that I can jump between the <+ +> tags with C-j). This works fine, but I find the above remap pretty obscure. Is there a way to enter what I want vim to type in "verbatim mode"? So I would want to write something like
map `cl i{VERBATIMSTART}class <+CLASSNAME+>
{
protected:
<+PROTECTED MEMBERS+>
public:
<+PUBLIC INTERFACE+>
};
<++>{VERBATIMEND}
?
Thank you
Paul
I don't know if there is such a "verbatim"-mode for mappings.
I, personally, would use one of the snippet-plugins to do this.
See www.vim.org and search
for "snippet". I have not tried all of them (just SnippetsMgr ;-) ),
but I suppose that they are handier to define multi-line-snippets.
Some of the available snippet-plugins on vim.org: snippets.vim ,
snippetsEmu, snipMate, SnippetsMgr, etc.
As Habi has mentioned, one way to go about this is with a snippet plugin.
Another way is to copy that snippet of code into its own file and set up your mapping to insert that file below the cursor:
map `cl :r /path/to/code_snippet<CR>
Kind of obvious (and probably not what you want) is:
map `cl iclass <+CLASSNAME+>
\<CR>{
\<CR>protected:
\<CR> <+PROTECTED MEMBERS+>
\<CR>public:
\<CR> <+PUBLIC INTERFACE+>
\<CR>};
\<CR><++>
\<CR>
\ in beginning of line tells that the line is the continuation of the previous one. But this is rather literal continuation: it doesn't add new lines so one has to add them manually. Since it uses the insert mode, the operation would be also affected by the current indentation mode. (Though one can try to work that around with :set paste/:set nopaste.)
I would have tried to put the text into a temp variable or register then Pput (or :put) it into the buffer. E.g. setreg() allows one to tell that the content of a register are lines and thus Putting it would work regardless of indentation.
Otherwise, looking in :help line-continuation or :help variables I see no way how one can specify a multi-line string or text.

Resources