Skip to content

Commit

Permalink
[C] Add support for new preprocessor directives (#4065)
Browse files Browse the repository at this point in the history
This adds support for the new #elifdef and #elifndef preprocessor
directives that are a combination of #else with #ifdef or #ifndef.

C++, Objective-C, and Objective-C++ are also updated because they
derive from the C syntax family as well.

This has already made it into recent C and C++ compilers and is
part of the C23 and C++23 standards.
  • Loading branch information
braewoods authored Oct 24, 2024
1 parent 493cb82 commit d9c7642
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 83 deletions.
40 changes: 20 additions & 20 deletions C++/C++.sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ contexts:
scope: punctuation.section.block.begin.c++
push:
- meta_scope: meta.block.c++
- match: (?=^\s*#\s*(elif|else|endif)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else|endif)\b)
pop: true
- match: '\}'
scope: punctuation.section.block.end.c++
Expand Down Expand Up @@ -1281,7 +1281,7 @@ contexts:
- match: '\}'
scope: meta.function.c++ meta.block.c++ punctuation.section.block.end.c++
pop: true
- match: (?=^\s*#\s*(elif|else|endif)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else|endif)\b)
pop: true
- match: '(?=({{before_tag}})([^(;]+$|.*\{))'
push: data-structures
Expand Down Expand Up @@ -1776,7 +1776,7 @@ contexts:
- match: '\}'
scope: meta.method.c++ meta.block.c++ punctuation.section.block.end.c++
pop: true
- match: (?=^\s*#\s*(elif|else|endif)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else|endif)\b)
pop: true
- match: '(?=({{before_tag}})([^(;]+$|.*\{))'
push: data-structures
Expand Down Expand Up @@ -1923,11 +1923,11 @@ contexts:
- include: scope:source.c#preprocessor-comments
- match: \bdefined\b
scope: keyword.control.c++
# Enter a new scope where all elif/else branches have their
# contexts popped by a subsequent elif/else/endif. This ensures that
# preprocessor branches don't push multiple meta.block scopes on
# the stack, thus messing up the "global" context's detection of
# functions.
# Enter a new scope where all elif/elifdef/elifndef/else branches have
# their contexts popped by a subsequent elif/elifdef/elifndef/else/endif.
# This ensures that preprocessor branches don't push multiple meta.block
# scopes on the stack, thus messing up the "global" context's detection
# of functions.
- match: $\n
set: preprocessor-if-branch-global

Expand All @@ -1939,7 +1939,7 @@ contexts:
captures:
1: meta.preprocessor.c++ keyword.control.import.c++
pop: true
- match: (?=^\s*#\s*(elif|else)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else)\b)
push: preprocessor-elif-else-branch-global
- match: \{
scope: punctuation.section.block.begin.c++
Expand All @@ -1954,7 +1954,7 @@ contexts:
captures:
1: meta.preprocessor.c++ keyword.control.import.c++
set: preprocessor-block-finish-global
- match: (?=^\s*#\s*(elif|else)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else)\b)
push: preprocessor-elif-else-branch-global
- match: \}
scope: punctuation.section.block.end.c++
Expand Down Expand Up @@ -2053,11 +2053,11 @@ contexts:
- include: scope:source.c#preprocessor-comments
- match: \bdefined\b
scope: keyword.control.c++
# Enter a new scope where all elif/else branches have their
# contexts popped by a subsequent elif/else/endif. This ensures that
# preprocessor branches don't push multiple meta.block scopes on
# the stack, thus messing up the "global" context's detection of
# functions.
# Enter a new scope where all elif/elifdef/elifndef/else branches have
# their contexts popped by a subsequent elif/elifdef/elifndef/else/endif.
# This ensures that preprocessor branches don't push multiple meta.block
# scopes on the stack, thus messing up the "global" context's detection
# of functions.
- match: $\n
set: preprocessor-if-branch-statements

Expand All @@ -2069,7 +2069,7 @@ contexts:
captures:
1: meta.preprocessor.c++ keyword.control.import.c++
pop: true
- match: (?=^\s*#\s*(elif|else)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else)\b)
push: preprocessor-elif-else-branch-statements
- match: \{
scope: punctuation.section.block.begin.c++
Expand Down Expand Up @@ -2100,7 +2100,7 @@ contexts:
- match : \)
scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++
set: preprocessor-if-branch-statements
- match: ^\s*(#\s*(?:elif|else))\b
- match: ^\s*(#\s*(?:elif|elifdef|elifndef|else))\b
captures:
1: meta.preprocessor.c++ keyword.control.import.c++
set: preprocessor-if-branch-statements
Expand All @@ -2123,7 +2123,7 @@ contexts:
captures:
1: meta.preprocessor.c++ keyword.control.import.c++
set: preprocessor-block-finish-statements
- match: (?=^\s*#\s*(elif|else)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else)\b)
push: preprocessor-elif-else-branch-statements
- match: \}
scope: punctuation.section.block.end.c++
Expand Down Expand Up @@ -2166,7 +2166,7 @@ contexts:
- match: '\{'
scope: punctuation.section.block.begin.c++
pop: true
- match: (?=^\s*#\s*(elif|else|endif)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else|endif)\b)
pop: true
- include: statements

Expand Down Expand Up @@ -2267,7 +2267,7 @@ contexts:
pop: true

preprocessor-other:
- match: ^\s*(#\s*(?:if|ifdef|ifndef|elif|else|line|pragma|undef))\b
- match: ^\s*(#\s*(?:if|ifdef|ifndef|elif|elifdef|elifndef|else|line|pragma|undef))\b
captures:
1: keyword.control.import.c++
push:
Expand Down
38 changes: 19 additions & 19 deletions C++/C.sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ contexts:
- match: '\}'
scope: meta.function.c meta.block.c punctuation.section.block.end.c
pop: true
- match: (?=^\s*#\s*(elif|else|endif)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else|endif)\b)
pop: true
- match: '(?=({{before_tag}})([^(;]+$|.*\{))'
push: data-structures
Expand Down Expand Up @@ -775,7 +775,7 @@ contexts:
scope: punctuation.section.block.begin.c
push:
- meta_scope: meta.block.c
- match: (?=^\s*#\s*(elif|else|endif)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else|endif)\b)
pop: true
- match: '\}'
scope: punctuation.section.block.end.c
Expand Down Expand Up @@ -1025,11 +1025,11 @@ contexts:
- include: preprocessor-comments
- match: \bdefined\b
scope: keyword.control.c
# Enter a new scope where all elif/else branches have their
# contexts popped by a subsequent elif/else/endif. This ensures that
# preprocessor branches don't push multiple meta.block scopes on
# the stack, thus messing up the "global" context's detection of
# functions.
# Enter a new scope where all elif/elifdef/elifndef/else branches have
# their contexts popped by a subsequent elif/elifdef/elifndef/else/endif.
# This ensures that preprocessor branches don't push multiple meta.block
# scopes on the stack, thus messing up the "global" context's detection
# of functions.
- match: $\n
set: preprocessor-if-branch-global

Expand All @@ -1041,7 +1041,7 @@ contexts:
captures:
1: meta.preprocessor.c keyword.control.import.c
pop: true
- match: (?=^\s*#\s*(elif|else)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else)\b)
push: preprocessor-elif-else-branch-global
- match: \{
scope: punctuation.section.block.begin.c
Expand All @@ -1056,7 +1056,7 @@ contexts:
captures:
1: meta.preprocessor.c keyword.control.import.c
set: preprocessor-block-finish-global
- match: (?=^\s*#\s*(elif|else)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else)\b)
push: preprocessor-elif-else-branch-global
- match: \}
scope: punctuation.section.block.end.c
Expand Down Expand Up @@ -1144,11 +1144,11 @@ contexts:
- include: preprocessor-comments
- match: \bdefined\b
scope: keyword.control.c
# Enter a new scope where all elif/else branches have their
# contexts popped by a subsequent elif/else/endif. This ensures that
# preprocessor branches don't push multiple meta.block scopes on
# the stack, thus messing up the "global" context's detection of
# functions.
# Enter a new scope where all elif/elifdef/elifndef/else branches have
# their contexts popped by a subsequent elif/elifdef/elifndef/else/endif.
# This ensures that preprocessor branches don't push multiple meta.block
# scopes on the stack, thus messing up the "global" context's detection
# of functions.
- match: $\n
set: preprocessor-if-branch-statements

Expand All @@ -1160,7 +1160,7 @@ contexts:
captures:
1: meta.preprocessor.c keyword.control.import.c
pop: true
- match: (?=^\s*#\s*(elif|else)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else)\b)
push: preprocessor-elif-else-branch-statements
- match: \{
scope: punctuation.section.block.begin.c
Expand All @@ -1184,7 +1184,7 @@ contexts:
- match : \)
scope: meta.function-call.c meta.group.c punctuation.section.group.end.c
set: preprocessor-if-branch-statements
- match: ^\s*(#\s*(?:elif|else))\b
- match: ^\s*(#\s*(?:elif|elifdef|elifndef|else))\b
captures:
1: meta.preprocessor.c keyword.control.import.c
set: preprocessor-if-branch-statements
Expand All @@ -1207,7 +1207,7 @@ contexts:
captures:
1: meta.preprocessor.c keyword.control.import.c
set: preprocessor-block-finish-statements
- match: (?=^\s*#\s*(elif|else)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else)\b)
push: preprocessor-elif-else-branch-statements
- match: \}
scope: punctuation.section.block.end.c
Expand Down Expand Up @@ -1250,7 +1250,7 @@ contexts:
- match: '\{'
scope: punctuation.section.block.begin.c
pop: true
- match: (?=^\s*#\s*(elif|else|endif)\b)
- match: (?=^\s*#\s*(elif|elifdef|elifndef|else|endif)\b)
pop: true
- include: statements

Expand Down Expand Up @@ -1354,7 +1354,7 @@ contexts:
- include: expressions

preprocessor-other:
- match: ^\s*(#\s*(?:if|ifdef|ifndef|elif|else|line|pragma|undef))\b
- match: ^\s*(#\s*(?:if|ifdef|ifndef|elif|elifdef|elifndef|else|line|pragma|undef))\b
captures:
1: keyword.control.import.c
push:
Expand Down
2 changes: 1 addition & 1 deletion C++/Completion Rules.tmPreferences
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<key>settings</key>
<dict>
<key>cancelCompletion</key>
<string>(^.*\bconst\s*$)|^\s*(\}?\s*(else|try|do|#if|#ifdef|#else|#elif|#endif|#pragma\s+once)|(class|struct|union|enum|namespace)\s*[a-zA-Z_0-9]+*)$</string>
<string>(^.*\bconst\s*$)|^\s*(\}?\s*(else|try|do|#if|#ifdef|#else|#elif|#elifdef|#elifndef|#endif|#pragma\s+once)|(class|struct|union|enum|namespace)\s*[a-zA-Z_0-9]+*)$</string>
</dict>
</dict>
</plist>
10 changes: 9 additions & 1 deletion C++/syntax_test_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,10 +589,18 @@ int foo(int val, float val2[])
if (val == -1) {
/* ^^ keyword.control */
/* ^ meta.block meta.block punctuation.section.block.begin */
#else
#elifdef BAR
/* <- keyword.control.import */
if (val == -2) {
/* ^ meta.block meta.block punctuation.section.block.begin */
#elifndef BAZ
/* <- keyword.control.import */
if (val == -3) {
/* ^ meta.block meta.block punctuation.section.block.begin */
#else
/* <- keyword.control.import */
if (val == -4) {
/* ^ meta.block meta.block punctuation.section.block.begin */
#endif
/* <- keyword.control.import */
val += 1;
Expand Down
Loading

0 comments on commit d9c7642

Please sign in to comment.