vim and c++11 lambda: auto indentation - vim

Using vim with c++11 lambda functions is actually poor. Indentation is not working and a lot of brackets are marked as erroneous.
As I know the indent and syntax highlighting for c and c++ is programmed internally and not via a c[...].vim file. Is there any chance to set up vim for c++11, especially for source code with lambda functions? Maybe someone can give a hint how and where to add lambda parsing in the internal vim syntax checking?
EDIT: (example code as requested from comments)
The code should look like the following example but is formatted to a single column.
MyLoop( [](int a, int b){
{
::i++;
for (;;)
{
SomeFunc();
}
cout << "Result: " << a*b<<endl;
}
});
Update for vim 7.4:
Now vim did not longer handle a lambda expression as an error, but it still did NOT do any indentation in the lambda expression and so it is still not usable for c++ anymore :-(
BTW: Has anyone a good auto formatting tool which can be added to vim environment, so that pressing a key externally do the formatting?

Vim 7.4 now has an jN cinoption for "Indent Java anonymous classes correctly." (:help java-cinoptions) This improves indenting behavior for C++11's lambdas.
With these options (put in your ~/.vim/after/ftplugin/cpp.vim):
setlocal cindent cino=j1,(0,ws,Ws
And if I move your for loop's opening brace to the same line (otherwise it's crazy) then vim indents your code like this:
MyLoop( [](int a, int b){
{
::i++;
for (;;) {
SomeFunc();
}
cout << "Result: " << a*b<<endl;
}
});
It doesn't give the hanging indent that you want either. If you move the initial opening brace it its own line, then you get your desired hanging indent.
For all the options, see :help cinoptions-values.
If you want at smarter indenting program, this user recommends set equalprg=clang-format to use ClangFormat so =ip will indent the current paragraph. This won't make vim correctly indent as you type (you need to setup indentexpr for that and that's quite complicated).
There's also a vim plugin that seems to do the same as setting equalprg, but with more code. Not sure if it's any better. It's supposed to be an alternative to clang-format.py (from Cyprian Guerra's answer).

Use
:let c_no_curly_error = 1
You can put that into your vimrc for example.
As for your assumption, it is wrong. There is a c.vim syntax file (in vim runtime). You can see a reference in :help c.vim and the implementation by looking it up in your vim runtime paths (:echo &rtp).

There is this project by Michael Small. I haven't tried it yet, but perhaps it's what you're looking for.

set smartindent autoindent
Then you type above code in vim,you will get the right indentation.
BUT,if you use gg=G or commands that contain "=" to re-indent above code,the indentation is still wrong.

I just struggled with this for a few days, looks like toggling on smartindent with cindent enabled helped me out with it lambda indentation in C++11.
In your ~/.vimrc
set cindent
set smartindent
Hope this helps peeps out.

What you seem to be looking for is clang-format.py from LLVM guys or vim-clang-format from Linda_pp a.k.a. rhysd (thanks idbrii for the latter) - both use clang therefore both support all of the C++11 new structures and you can run it as follows:
:pyf ~/src/llvm.git/tools/clang/tools/clang-format/clang-format.py
or
:ClangFormat
The latter seems better as it (among other features) allows to follow the "one config file for the same behaviour on every environment" rule, especially when you use a VIM add-on manager (e.g. VAM).

Related

Vim doesn't use tabstop distance in insert-mode

I'm having problems with auto indentation in vim while programming in lisp.
My .vimrc had the following settings for tabs:
set noexpandtab
set autoindent
set softtabstop=0
set shiftwidth=8
set tabstop=8
When I type (if <enter> in insert-mode, a new line is created with an indentation of two spaces.
None of my settings say anything about two spaces, so why don't I get a tab?
What setting can I use to change the indentation while in insert-mode?
Thanks in advance!
Update:
Thanks for the answers, the settings are not overwritten.
It has to do with the "default lisp indenting".
In the :help lisp it says something about changing the p flag in
cpoptions. This is what it says in the help for the cpoptions flags:
p - Vi compatible Lisp indenting. When not present, a slightly better algorithm is used.
Setting it does change the indent to one space instead of two spaces.
Still not sure how to change this to something else though.
Looks like this is two-space indentation is a hard coded behavior of :set lisp mode which ignores shiftwidth.
We can trace this to the source code which contains a hard-coded amount += 2; increment statement.
It's that way for a good reason; it has come to be the predominant way of writing Lisp.
As I wrote this answer, I peeked at samples of source code the following projects (all Lisp or Lisp-like languages):
Steel Bank Common Lisp (SBCL);
Clozure Common Lisp (CCL);
GNU Emacs;
Clojure;
GNU Guile;
Racket;
and GNU CLISP.
I did not spot a single example of anything but two-space indentation! With two-space indentation, you are in good/large company. You might as well get used to that; even if you somehow get Vim to follow your way, if you upstream anything into anyone's Lisp project, you will likely have to reformat.
Now, I have seen Lisp code using four-space indentation, like in very old code bases and some books.
By the way, sometimes you see if indented like this:
(if (condition)
(then)
(else))
This may happen where indentation is four spaces, but I'm referring situations when this is alignment, and not four space indentation. This formatting is, of course, standard for function arguments, but controversial for operators such as if. Some people like it that way in their code bases. For instance, this institution's randomly found coding style guide recommends this way of writing if, while also recommending two-space indentation.
Vim will do the above if you remove if from lispwords.
The :set lispwords=... parameter contains a comma-separated list of identifiers which follow operator-like indentation, meaning two spaces rather than function-like alignment: second and third lines align with argument. By default, if is found in lispwords.
Lisp mode also applies two space indentation to a function (i.e. form not listed in lispwords, if there is no argument):
(gobbledygook 1 2
2 3)
(gobbledygook
1)
That's also "canonical". Sometimes this comes in handy if you're trying to conform to some maximum line length; a function call running past the limit can sometimes be made to fit by moving all its arguments down, and just giving them two space indentation.
Each filetype can have its own settings in vim. So your .vimrc values can be overwritten in filetype plugins. To learn the current values of the settings for lisp filetype open the lisp file and run the following commands in vim command line:
:set noexpandtab?
:set autoindent?
:set softtabstop?
:set shiftwidth?
:set tabstop?
If they are different from the ones in .vimrc, then your values are overwritten in some plugin.
In order to overwrite them again with your custom values, create the ~/.vim/after/ftplugin/lisp.vim file with the required values:
set noexpandtab
set autoindent
set softtabstop=0
set shiftwidth=8
set tabstop=8

Why does vim autoindent work inconsistently

Using vim 8.0.1365 on a Macintosh
I don't understand why autoindent fails some of the time.
Both of the code fragments below are indented as I want them to
be when I run the formatter, (both default and the pangloss
indenter). But when I'm in insert mode, the autoindent
doesn't work for the second code fragment.
So code like this gets autoindented as I'd like;
function SayHiToMom () {
message = "Hello, best mom in the world"; <- This line auto-indents, as expected.
send(message); <- and so does this one.
}
But not this code
var svg = d3.select("#chart-area").append("svg")
.attr("width", 400) <- Here, no auto-indent occurs, but that's not really a surprise. I indent by hand.
.attr("height", 400) <- When I start a new line here, no auto-indent occurs, surprising and annoying.
When you have filetype support on, Vim loads a filetype plugin when you load a file of a particular type (like JavaScript) and that file contains multiple settings. In the case of JavaScript, one of those settings is indentexpr, which is a function that's called to automatically provide the right indent.
It appears that in this case, it doesn't handle that case automatically, possibly because nobody ever considered that case in the code. Vim doesn't understand JavaScript natively, so the Vimscript has to do the best it can.
Also, it's possible that someone didn't do this behavior because your line wouldn't intrinsically be considered a continuation line if someone were using the JavaScript style where you don't write semicolons at the end, but instead put them at the beginning of the line if necessary to disambiguate. Vim has to support both styles of JavaScript, even if not everyone agrees that both are a good idea.
Regardless, the header of the file (on my system, /usr/share/vim/vim82/indent/javascript.vim) contains a GitHub URL where you could report this issue and either send a patch or see if someone else would be willing to write one. You could also turn off the indentexpr value by writing something like the following in your .vimrc:
au FileType javascript setl indentexpr=
In that case, you'd get the default autoindent behavior.

Can I fix Groovy indenting in Vim?

I am trying to use Vim for some Groovy code at work. It doesn't seem to handle autoindents well when semicolons are not used. I've found a few questions related to Ruby and JavaScript with the same issues, but none of the fixes I find work for me. I do have filetype plugin indent on in my .vimrc, and do not set cindent, autoindent, or smartindent. I've tried running setlocal nocindent nosmartindent in a Groovy buffer and reindenting the file with ggVG= just in case there's a plugin setting those behind the scenes, and it still always gets it wrong.
For example, I get this on a small sample (from a personal libGDX sandbox app I'm writing in Groovy)
#Override
void render () {
Gdx.gl.glClearColor(0.75f, 0.75f, 0.75f, 1)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
batch.begin()
batch.draw(img, 0, 0)
font.draw(batch, "Testing", 300, 400)
batch.end()
}
Notice the extra indents after the annotation, the opening brace, and the first line of the function. My .vimrc is fairly complex, but I can post a link to my dotfiles if anyone thinks that will help.
Vim doesn't come with a indent script for groovy. So it tries to use the standard indentation rules which are based on C. These rules use semicolons to determine if a line is ended which is why you get line continuation indents on the second line of the function.
Since vim doesn't include the indent script you can use the groovyindent plugin. Placed in ~/.vim/indent. You also need to run dos2unix on groovy.vim since it contains the wrong line endings.
Since groovy looks very much like simplified perl, for my little groovy (actually nextflow DSL) coding, setting filetype=perl followed by gg=G worked quite nicely.

Disable autoindent in vim

I use vim since almost 20 years and recently someone told me about the usage of = key for indenting a block of code. Sometimes I try a new vim key but stop using it because it isn't doing exactly what I want or I just don't need the feature. But in this case I find its a nice feature.
So I downloaded vim script 1120 (PHP-correct-Indenting) and installed it. My .vimrc contains:
filetype indent on
set smartindent
Now I can use = to indent a visually marked code block.
But I do NOT want vim to automatically indent code while I am typing. This is just irritating me as I am usually doing indentation myself and I am very much used to it ...
So how can I stop vim from automatically indenting my code while typing but can still continue to use = for indenting a visually marked block of text.
PS: Use hjkl for moving around in vim. It will make you about 1.5 times faster :)
My complete vimrc:
syntax on
set tabstop=3
set shiftwidth=3
execute pathogen#infect()
filetype indent on
set smartindent
Commenting the last two lines stops autoindenting but also using "=" does not use the mentioned vim script anymore
The plugin sets 'indentexpr', which controls both explicit reindenting via = as well as indenting-as-you-type. Fortunately, you can control the triggering of the latter via the 'indentkeys' option, so clearing that should work.
Put the following into ~/.vim/after/indent/php.vim; this way, it'll apply after the plugin:
setlocal indentkeys=
The effect I want can get achieved using:
:set paste
This is exactly(?) the mode I wanted to switch into. No autoindenting at all. But the "=" key works to indent a marked block of text.
Maybe I will add "set paste" to my .vimrc :)
Thanks for your support anyways.

Vim Code Folding for Scilab

I've just recently started to use the folding functionality of vim and it's very helpful for the languages that it works really well for.
My issue lies in the way vim comments out the fold markers in scilab code. It defaults to
/*{{{*/ and /*}}}*/
which works great in languages like C, but is not actually a comment in scilab. I get a multiplication error when i try to run the code.
I've tried adding
autocmd FileType scilab set fmr=//{{{,//}}}
to my .vimrc file which doesn't quite do what I'd like. It results in
/*//{{{*/ and /*//}}}*/
which are still not comments. The code "folds" fine but becomes unusable. I could set up a macro to replace every instance of "/*" with "//", but that could have unintended consequences when applied globally to a file.
So the question is: how can i setup vim fold markers comments for scilab files such that it will not render the file unusable?
You do not add the comments to 'foldmarker' itself, there's the 'commentstring' option that influences how Vim surrounds the fold markers (when creating folds with zf). Try setting
:setlocal commentstring=//%s
for your scilab filetype. (Put the command in ~/.vim/after/ftplugin/scilab.vim to make it permanent.)
It sounds to me like vim doesn't understand how SciLab comments work. I'm not sure if vim comes with SciLab syntax logic these days, is syntax highlighted correctly in your SciLab files? If not, you can get the syntax file from here.
Is there a particular reason you want to use marks? They aren't actually needed. If you don't want vim to auto-fold by syntax or indentation level, you can still manually define folds with
:set foldmethod=manual
That lets you select a chunk of text in visual mode and make it into a fold with 'zf'. No marks required.
More info on various vim folding techniques here.

Resources