vim syntax highlighting error on missing closing parenthesis - vim

I'm using gvim 9.0 (2022 Jun 28).
If I launch vim with the --clean flag and attempt to write a small C function such as this:
void blah()
{
blah();
}
Then when I set the filetype to c using: :set ft=c, I can see void highlighted.
Now, if I remove the closing parenthesis in the start, i.e. resulting in this:
void blah(
{
blah();
}
I can see the subsequent curly brackets are highlighted in red, indicating an error, which is good.
However, if I now set the filetype to cpp using: set ft=cpp, the highlighted curly brackets revert to black. If I then set the filetype back to c as before, they remain black.
Is this a bug?
Additionally, how can I get erroneous unmatched parentheses as part of function invocations to be highlighted? In my example, a missing opening parenthesis results in the closing parenthesis to be highlighted, but the converse isn't true. For example:
void blah()
{
blah(;
}
Doesn't indicate any errors. This kind of typo catches me all the time and it would be great if I could be visually alerted to these.

Related

Vim: delete inside matching delimiter as in Neovim

As a Neovim user, I am able to type di( (also di", di{ and so on) in order to delete the content delimited by matching brackets/quotes. For example, in a situation like the following
(cursor here)
/
void foo(int bar)
-
By running di( I would get
(cursor here)
/
void foo()
-
And by running da( I would get
(cursor here)
/
void foo
-
However, in vim this behaviour can be accomplished only by placing the cursor on the starting bracket/quote first. So di( works only if the cursor is positioned as follows
(cursor here)
/
void foo(int bar)
-
Because of that, in vim I have to run f(di( or F(di( according to where my cursor is on the line in order to move the cursor to the starting delimiter and, then, deleting the content. In neovim I can, instead, directly run di( obtaining the same result.
Is there any remap I can set in order to make vim behave like neovim does?
Vim used to treat nesting pairs (where the beginning and end are different) and non-nesting pairs (where the beginning and end are identical) differently but it all changed late in 8.2's lifecycle.
Your Neovim build includes the patch but your Vim build doesn't.
Update Vim to a version > 8.2.3255 and you will have the desired behavior.

VIM: how do I get close parenthesis aligned with block like close brace does?

in vim
when you close the brace, it automatically aligned with the block head of the opening brace. like this:
f() {
...
}
how do I get closing parenthesis automatically moved and aligned the same way:
f (
int i,
...
) {
At the moment, I can only get it aligned by use alignment command. e.g ==, without the command, it looks like this:
f (
int i,
...
) {
i.e. an extra indent from where it is supposed to be aligned.
how do I fix this problem and make it work just like a closing brace?
The answer depends on the value of 'indentexpr'.
If it's set (e.g. to GetJavaIndent()), you should look into fixing the corresponding function. No generic advice can be given here.
If 'indentexpr' is not set, you're using 'cindent', the behaviour of which can be affected with 'cinoptions'. The option you're looking for is m1. So just add this to your vimrc, and you should be set: set cinoptions=m1 (maybe wrap it into autocmd or something so that it will only affect specific filetypes.)

Wrapping a code block around code in VIM

Is it possible to wrap a code block around a piece of code in VIM? For example, if I want to wrap a while loop around the following, how can I do it without having to scroll to the bottom of the code to add the closing brace:
if(z > y)
{
switch(x)
{
case 1:
addPoint();
break;
case 2:
addValue();
break;
}
}
This is what the code will look like afterwards:
while (a > 10)
{
if(z > y)
{
switch(x)
{
case 1:
addPoint();
break;
case 2:
addValue();
break;
}
}
}
Vim does not have a built in surrounding system. I suggust you look at Tim Pope's excellent surround plugin. Then assuming you are positioned on the if you can do this:
Vj%SBIwhile (a > 10)
The Vj% selects the block + the conditional.
SB surrounds the selected text with a {,} (read surround with block)
Insert your loop text at the beginning of the newly inserted block.
You don't need surround to do this. You can do it with plain vanilla vim.
Vj%>`]o}<esc>g;g;Owhile (a > 10)<cr>{<esc>
However I prefer to use surround as it is a very handy plugin to have.
For more help see:
:h %
:h g;
:h `]
You can use the vim plugin surround.vim. It lets you wrap lines or fragments in blocks (and change the wrapping pairs).
Check something like Snipmate, it's possible they have an ability of surrounding Visually selected code with a snippit.
http://www.vim.org/scripts/script.php?script_id=2540
snipMate-visual-selection-support There is a special placeholder called {VISUAL}. If you visually select text, then press Vim
switches to insert mode. The next snippet you'll expand will replace
{VISUAL} by the text which was selected previously
You can make a mapping to do this in vanilla Vim e.g.:
:imap <S-F2> <Esc>j>>j>%%o<C-D>}
Use the mapped key after typing the opening brace for the surrounding code. Goes without saying that you should change <S-F2> to a keymap you like.
Breakdown of the key sequence:
Esc: go to Normal mode
j>>: move cursor to next line (in your example the if line) and indent it.
j>%: move cursor to the line with opening brace of if, indent from there to matching brace (the cursor will jump back to the opening brace)
% goes to the closing brace of if
o add a new line after the closing brace, and enter Insert mode.
CTRL+D: unindent (to undo the effect of smartindent)
} add the closing brace for the surround code (in your example, while)
Of course the plugins recommended by others have many more features so you should look at those as well.

Highlighting a code block using viEMU

May I know how do I highlight a code region say for example
public void foo()
{
blah();
blah1();
blah2();
}
where my cursor is at 'b' of first blah(), how can I highlight the whole code region using viEmu or VIM per se?
In Vim, that's va{ (or va}, or vaB as synonyms). The v enters visual mode, and a{ is a text object that selects a Block. If you don't want the curly braces included, use i{ (inner Block) instead. And if you want to operate (e.g. delete) on the block, you can skip visual mode and just use a command that takes a motion, e.g. da{.

Strange folding in Vim when there's a { and a } on the same line.&*

I am currently editing a C++ file with twp function similar to
int func_name_1(int param) {
do_stuff();
and_more();
}
int func_name_2(int param) {
do_different_stuff();
STRUCT_TYPE s = {5, 8, 10, 12};
do_something_with(s);
}
If I do a zc on the word func_name_1, vim folds the function, as expected, so that it now looks like
int func_name_1(int param) {--------------------
On func_name_2 however, the function is folded like so:
int func_name_2(int param) {---------------------
do_something_with(s);
}
which is not exactly what I want. For some reason the opening and closing {} on one line seem to disturb the folding algortithm.
If someone knows how I can get a "better" folding, I'd appreciate any hinter into the right direction.
Edit the options that I believe are relevant for this problem are set in my buffer like so
set foldmarker={,}
set foldmethod=marker
set foldtext=getline(v:foldstart)
Edit II: If I change the line with the opening and closing {...} to STRUCT_TYPE s = { 5, 8, 10, 12}; (Note the space after the {), then the folding works as expected.
Oh.... I see....
:help fold-marker tells me: Markers can have a level included [..] The following number specifies the fold
level
So, the 5 immediatly after the { specified the fold level, which messed things up.
The zc command closes the current fold. You may have a folder created to be able to close it, so your problem was on creating the fold and not closing it.
To create the fold use zf or zF. zf Works on visual mode, and also on a motion like zf2j to create a fold on 2 lines down. zF already works in a "line-wise" way.
The most practical way, in your case, would be to position the cursor on the bracket (using f{ for example) and run zf% to create and close a fold that goes to the matching bracket. Anyway, it would be even more practical if that bracket was on another line (so you could use ]] to go to it) but that's a convention out of the scope of this answer :-)

Resources