How to insert boilerplate everytime a key is invoked in vim? - vim

When I'm coding in C/C++, when I type '{' I generally want the next couple characters to be a newline, tab, newline, ended by '}'. This is especially convenient with top-down programming so that you can make the format of your function and continue on, only to come back later and it has already been prototyped for you.
So, to clarify, I want '{' to be replaced by
{\n\t\n}
Is that possible in vim, and if so, how?

is this ok for you?
inoremap { {<cr>}<esc>O<tab>
with this mapping, if you type foo{ in INSERT mode, it will change to:
foo {
I
}
I is cursor position.

You may be interested to try out some of the many "auto closing" plugins available. I use DelimitMate but you could try AutoClose or AutoPair.

You have a bunch of yank registers. Perhaps the simplest solution would be to yank that to a designated register and then put from that register each time you need it.

For that kind of "top down" coding with "auto prototyping", snippet plugins are excellent.
With a snippet plugin you can do much more extensive "top down" coding than just expanding brackets.
Ultisnips is a great snippet plugin. If you don't have python support in your vim, then SnipMate, the predecessor of Ultisnips, is quite capable also, but not as advanced.
With Ultisnips, you could use any of the three snippets below:
1) Create the brackets and place cursor following them
snippet {
{
}
$1
endsnippet
2) Create the brackets and place the cursor within them
snippet {
{
$1
}
endsnippet
3) Create the brackets and place the cursor within them, then Ctrl-j to place the cursor following the brackets
snippet {
{
$1
}
$2
endsnippet
But in addition to simple snippets like these three, you could get much more sophisticated, defining whole function/class/etc templates in snippets that can be quickly expanded and jumped through.

Related

Vim: recognize character sequences as part of "whole word"

This has been bugging me for a while: I'm writing code that uses verilog-auto which means I'm editing in a verilog file with perl snippets injected into comment sections. One very useful thing that I like to do in Vim is to search for the whole word under the cursor with * and #. However, with perl syntax that contains variable names such as ${w} and $w, these shortcuts don't work.
I don't want to add $, { and } to my "keywords" list as there are many instances where I don't want these to count as part of a whole word. For instance, in verilog concatenation: {sig1,sig2[1:0]}, I wouldn't want {sig1 to be searched for as a whole word.
Is there a way to get "whole word" to recognize sequences via a regex or something? So only ${[a-z]+} or $[a-z]+ gets recognized as "keywords".
Either that or a separate keyboard shortcut that can let me search for the pattern under the cursor.
Here's a really ugly hack, but it works:
nnoremap * viW:s/\%V\$*{*\a*}*/\=setreg('a', submatch(0))/n<cr>/<C-r>a<cr>n
nnoremap # viW:s/\%V\$*{*\a*}*/\=setreg('a', submatch(0))/n<cr>/<C-r>a<cr>N
The only downside is that this will overwrite your last visual selection, so if you use gv a lot, this isn't the best solution. It also overwrites the a register, although you could pick a different one if you want.

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.

Vim function to test character after cursor

I'm trying to duplicate the functionality in vim of IDEs like IntelliJ that do the following, letting | be the cursor:
I type an open paren: (
It automatically closes it and puts my cursor in the middle: (|)
I type some text in the middle: (Some text here|)
I type a close paren, and rather than inserting a close paren, it simply moves my cursor over the already inserted one: (some text here)|
I have the following set of remappings that duplicate the functionality of 1-3 and when I just type ():
inoremap ( ()<Esc>i
inoremap () ()<Esc>i
It seems I need a way to detect if the character after my cursor is a ) in order to make a function to do what I want in 4. Does vim support this?
There are many pitfalls to implement this functionality properly; several plugins have attempted to do this. At least you should check them out to learn what they did; maybe one of them already fulfills all of your requirements! You'll find a complete discussion of implementation details, and a list of plugins at Automatically append closing characters.
I don't believe you can do this through a simple map since you would need to incorporate some conditional logic to decide when and when not to add the closing parenthesis. Instead, you would have to define a function to do the heavy lifting and then map the closing parenthesis to call the function. Vim's help has some information about functions, but I've found this page to be an invaluable resource: http://learnvimscriptthehardway.stevelosh.com/
That said, there are number of vim plugins out there that already perform this type of functionality. The one that I use is called "auto-pairs" and can be found here: https://github.com/jiangmiao/auto-pairs. As a bonus, you can see the code if you're actually interested in how it works as opposed to just being interested in having the functionality itself.
Try this code
inoremap <expr> ) getline('.')[col('.') -1] == ')' ? "\<Right>" : ')'
But I recommend to use plugin, because such settings make your vimrc in confusion.
I like vim-smartchr and vim-smartinput
https://github.com/kana/vim-smartchr
https://github.com/kana/vim-smartinput

How to delete enclosing braces in Vim?

I have the following text:
Monkeys eat {bananas}.
My cursor is in the middle of the word banana:
Monkeys eat {bana|nas}.
Here the | symbol denotes the cursor's position.
How can I delete the braces from there?
I can change bananas to apples with a simple ci}apples, so perhaps I could use a similar trick just to get rid of the { and } characters?
Also, can I do this even in this case, which is actually what I really need to do?
networks {
local
is|p
}
(The simplified example above was just to introduce the concept.)
Using Tim Pope's excellent surround.vim plugin (which I highly recommend), you would do ds{ for delete surrounding {
I understand that adding another plugin isn't always the ideal solution when you could find a native key sequence instead, but surround.vim is supremely useful, as it can also handle XML/HTML tags and perform enclosures on complex text objects. I regard it as one of those "stuck on a desert island, must have under any circumstance" plugins.
The task can be accomplished by means of Vim built-in text motions.
Delete the text inside the braces, select the braces, and paste the
previously deleted text over them:
di{v%p
What about this:
yiBvaBp
No plugin and simple.
Delete the braces and leave everything else?
mz[{x]}x`z
Expanded
:help m - set a mark. In this case marking the initial cursor position so I can go back there at the end. :help [{ - moves the cursor to the opening brace of the smallest block enclosing the cursor. :help x - delete the brace which is now under the cursor. ]} and x - doing the same to the closing brace. And finally
help `
returning to marked position, the one called z created at the start.
"Plugins" aren't my style...

Delete surrounding whitespace in vim

I'm using the awesome https://github.com/tpope/vim-surround plugin to surround words with parenthesis, for example I often use: viws<space><space> to surround a word with spaces.
What I'm missing is the opposite of this, that is, deleting surrounding spaces around a word.
The most common use for me is function arguments like
foo(bar) vs foo( bar ) depending on code style.
Does anyone know a nice way to do this?
Note: This solution requires the surround plugin referenced in the question.
For your specific situation you could do the following:
cs()
This changes foo( bar ) to foo(bar), however, it is not a general solution to your problem.
I often productively procrastinate in search of vim plugins too, when I could just define a mapping for this.
nnoremap <leader>dd F<space>xf<space>x
EDIT more information
<leader> common key for user defined mappings (, is a good one)
dd combination to use (any other mnemonic one will suffice)
F<space>x search backwards for a space, then remove it
f<space>x search forwards for a space, then remove it
Maybe just BXElx in normal mode.
In fact, perfect solution for me is the mapping provided by #puk, but using the keys #sarnold expected in the first place (what one would expect from surround plugin if it implemented this).
This is:
nnoremap ds<space> F<space>xf<space>x

Resources