Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C/C++ incorrect syntax region #55

Open
idnsunset opened this issue May 21, 2020 · 3 comments
Open

C/C++ incorrect syntax region #55

idnsunset opened this issue May 21, 2020 · 3 comments

Comments

@idnsunset
Copy link

idnsunset commented May 21, 2020

Hi,
I attempted to add 'c': ['c'] to the g:rst_syntax_code_list to enable C syntax highlighting but run into the issue with c and cpp code blocks as described below.

Given the following rst text:

.. code:: cpp
   using namespace std;

   int main() {}

using

Both 'using' are highlighted as C++ statement. It seems that 'c' and 'cpp' cannot be specified simultaneously in g:rst_syntax_code_list.

@marshallward
Copy link
Owner

Yes, this is something that I had noticed as well, but looks like I never logged the issue. Thanks for submitting it.

When I tried to sort this out, it seemed to be a problem with one of those syntax files, but I could not make any more progress at the time.

Your example is a bit odd in that there should be a blank line between the directive and the code block. That may be affecting things as well here.

@madjxatw
Copy link
Contributor

madjxatw commented May 22, 2020

I've figured out what exactly happens there.

If you take a look into the C++ syntax file (syntax/cpp.vim), you will find that it loads syntax/c.vim by exectuing runtime! syntax/c.vim. When you put both 'c' and 'cpp' in g:rst_syntax_code_list, the c.vim syntax file will be sourced twice, resulting in all C syntax groups having duplicate patterns.

Taking the example you posted, place the cursor at the opening { and run the following command:

:echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')

and you will get:

['rstDirectivecpp', 'cBlock', 'cBlock']

This means that the cBlock syntax group is matched twice at {.

Now lets check the definition of cBlock group by running:

:syn list cBlock

and you will get:

--- Syntax items ---
cBlock         xxx start=/{/ end=/}/  contained transparent fold 
                   start=/{/ end=/}/  contained transparent fold

You can see the duplicate patterns defined for cBlock.

When reaching the closing }, the inner cBlock group ends but the remaining texts are still in the outer cBlock group until reaching another }, this is why the second using is highlighted.

I've thought about why 'c' is not added to g:rst_syntax_code_list by default and this might be the reason? However, we don't want to get some C++ keywords such as using highlighted in a C code block, hence we will have to define a separate @rstc syntax cluster containting all C syntax groups, meanwhile avoid source syntax/c.vim twice.

I attempted to fix this by introducing extra code to define the @rstc cluster during processing C++ sutff. See: https://github.com/madjxatw/vim-restructuredtext/blob/a52a1782eb6480554c5641db24fbba2b8309cb3e/syntax/rst.vim#L254-L273
This might not be the best approach, welcome better solution.

@marshallward
Copy link
Owner

Thank you @madjxatw for solving this mystery, your explanation makes a lot of sense. This looks like an interesting solution to a very difficult problem.

It would be nice if there were a way to catch the more general issue of recursive highlighting, since quite a few syntax languages do this. For example, I think php inherits html!

In the meantime, I'll try to find some time to work through your solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants