Re: [vim/vim] Decouple C and C++ syntax files (Issue #18224)
Amelia Clarke (Vim Github Repository) <[email protected]> Tue, 28 Jul 2026 11:09:51 -0700
| Newsgroups | gmane.editors.vim.devel |
|---|---|
| Message-ID | <vim/vim/issues/18224/[email protected]> |
selenebun left a comment (vim/vim#18224) Sorry about that, I guess I never ended up seeing this message. Anyways, I've been experimenting off-and-on with different ways to fully refactor the C syntax file into something a bit more sustainable to update, and I've come up with some prototypes I'm quite happy with. It's only recently that I've started tinkering with the C++ syntax, but I've changed my mind since the initial post, and am increasingly of the opinion that it doesn't make sense to have them wholly separate. I think a shared `syntax/c89.vim`[^1] could definitely be the way forward. There are some places where I think it's a bit neater to have regex patterns that are mutually exclusive, especially for things that have changed a lot across versions: <details open> <summary>For example, here's how I handle integer constants:</summary> ```vim if s:c23 syn match cNumber '\v<[1-9]%(\'?\d)*%([Uu]%(LL?|ll?|WB|wb)?|%(LL?|ll?|WB|wb)[Uu]?)?>' syn match cNumber '\v<0%(\'?\o)*%([Uu]%(LL?|ll?|WB|wb)?|%(LL?|ll?|WB|wb)[Uu]?)?>' syn match cNumber '\v<0[Bb][01]%(\'?[01])*%([Uu]%(LL?|ll?|WB|wb)?|%(LL?|ll?|WB|wb)[Uu]?)?>' syn match cNumber '\v<0[Xx]\x%(\'?\x)*%([Uu]%(LL?|ll?|WB|wb)?|%(LL?|ll?|WB|wb)[Uu]?)?>' elseif s:c99 syn match cNumber '\v<[1-9]\d*%([Uu]%(LL?|ll?)?|%(LL?|ll?)[Uu]?)?>' syn match cNumber '\v<0\o*%([Uu]%(LL?|ll?)?|%(LL?|ll?)[Uu]?)?>' syn match cNumber '\v<0[Xx]\x+%([Uu]%(LL?|ll?)?|%(LL?|ll?)[Uu]?)?>' else syn match cNumber '\v<[1-9]\d*%([Uu][Ll]?|[Ll][Uu]?)?>' syn match cNumber '\v<0\o*%([Uu][Ll]?|[Ll][Uu]?)?>' syn match cNumber '\v<0[Xx]\x+%([Uu][Ll]?|[Ll][Uu]?)?>' endif ``` </details> But for a lot of these, at least if the syntax is backwards compatible, you can just have the C89 version in the common file and rely on the new syntax groups that are defined later taking precedence. Really, I think the biggest issue with the existing system right now is how it handles versioning. At present, it's all controlled with a bunch of variables like `g:c_no_c99`, `g:c_no_c11`, etc.[^2] Aside from this many independent variables adding a lot more complexity to the syntax file, it also makes it much more tedious to use a specific version, since you have to set the variables to disable everything after that point. It also makes it possible to enter a "broken" state where you can disable stuff from a prior version, but still have syntax from a newer version active, which possibly relies on the existence of the earlier version to behave correctly. Instead, I propose having a single variable, e.g. `g:c_standard` (or `b:c_standard`), which controls the version the user is targeting. Each part of the syntax file *knows* when it was introduced, and when it was deprecated or removed, and then can just test if the selected standard falls within that range. I've had a lot of success with this method, and it definitely lets you simplify a lot of things. It probably wouldn't be too hard to create a small "shim" layer that guesses which version the user wants based on the old variables if `g:`/`b:c_standard` doesn't exist. You'd also do a similar thing for C++. Really, I think the tricky part is just figuring out which functionality to move out into the shared syntax file. While C and C++ *have* diverged a lot, some of the recent standards have borrowed from each other, and there are certain places like the recent `#elifdef`/`#elifndef` and other preprocessing directives that are basically identical. It would be nice to be able to move those parts to a common syntax file as well, but then it would need its own script-local version handling (or defining buffer-local version-related variables before including it and undefining them after). Apologies for the long comment, I have done a lot of thinking about this, but am not really sure which method would work best for incorporating into the official Vim runtime, especially when it comes to potentially breaking backwards compatibility. [^1]: C89 tends to be the name people use most often in my experience, but the two are basically identical. [^2]: This probably made more sense when the language was more conservative and there were only a couple versions you had to worry about, but C23 and C2y have been *much* more ambitious. -- Reply to this email directly or view it on GitHub: https://github.com/vim/vim/issues/18224#issuecomment-5107941384 You are receiving this because you are subscribed to this thread. Message ID: <vim/vim/issues/18224/[email protected]> -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/vim/vim/issues/18224/5107941384%40github.com.