lectures.alex.balgavy.eu

Lecture notes from university.
git clone git://git.alex.balgavy.eu/lectures.alex.balgavy.eu.git
Log | Files | Refs | Submodules

commit 904682d678b77515f3ee5f64da317e142cdee41e
parent e63763c8aeefd6f77deff857dcbd2f5dd04e668c
Author: Alex Balgavy <alex@balgavy.eu>
Date:   Wed,  9 Jun 2021 18:08:36 +0200

Manually adding syntaxes to fix highlighting

Defining `extra_syntaxes` in the config causes default syntaxes to stop
working, see https://github.com/getzola/zola/issues/1309. Fixed
temporarily by copying in the syntax files I use, will revert on a new
release from Zola.

Diffstat:
Asyntaxes/ASP/ASP.sublime-syntax | 694+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/ASP/Comments.tmPreferences | 21+++++++++++++++++++++
Asyntaxes/ASP/HTML-ASP.sublime-syntax | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/ASP/Indentation Rules.tmPreferences | 20++++++++++++++++++++
Asyntaxes/ASP/Indexed Symbol List.tmPreferences | 14++++++++++++++
Asyntaxes/ASP/Symbol List.tmPreferences | 22++++++++++++++++++++++
Asyntaxes/ASP/syntax_test_asp.asp | 1135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Assembly x86.sublime-syntax | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/C++/C Single File.sublime-build | 14++++++++++++++
Asyntaxes/C++/C Standard Includes.sublime-completions | 38++++++++++++++++++++++++++++++++++++++
Asyntaxes/C++/C++ Single File.sublime-build | 14++++++++++++++
Asyntaxes/C++/C++ Standard Includes.sublime-completions | 218+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/C++/C++.sublime-settings | 3+++
Asyntaxes/C++/C++.sublime-syntax | 2166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/C++/C.sublime-syntax | 1311+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/C++/Comments (C++).tmPreferences | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/C++/Completion Rules.tmPreferences | 12++++++++++++
Asyntaxes/C++/Default.sublime-keymap | 41+++++++++++++++++++++++++++++++++++++++++
Asyntaxes/C++/Indentation Rules Comments.tmPreferences | 14++++++++++++++
Asyntaxes/C++/Indentation Rules.tmPreferences | 36++++++++++++++++++++++++++++++++++++
Asyntaxes/C++/Snippets/#ifndef-#define-#endif.sublime-snippet | 8++++++++
Asyntaxes/C++/Snippets/#include-(#inc angle).sublime-snippet | 6++++++
Asyntaxes/C++/Snippets/#include-(#inc).sublime-snippet | 6++++++
Asyntaxes/C++/Snippets/#include-(inc angle).sublime-snippet | 6++++++
Asyntaxes/C++/Snippets/#include-(inc).sublime-snippet | 6++++++
Asyntaxes/C++/Snippets/$1.begin()-$1.end()-(beginend).sublime-snippet | 6++++++
Asyntaxes/C++/Snippets/030-for-int-loop-(fori).sublime-snippet | 9+++++++++
Asyntaxes/C++/Snippets/Enumeration.sublime-snippet | 9+++++++++
Asyntaxes/C++/Snippets/Typedef.sublime-snippet | 6++++++
Asyntaxes/C++/Snippets/class-..-(class).sublime-snippet | 11+++++++++++
Asyntaxes/C++/Snippets/do...while-loop-(do).sublime-snippet | 9+++++++++
Asyntaxes/C++/Snippets/forv.sublime-snippet | 9+++++++++
Asyntaxes/C++/Snippets/fprintf.sublime-snippet | 6++++++
Asyntaxes/C++/Snippets/if-..-(if).sublime-snippet | 9+++++++++
Asyntaxes/C++/Snippets/main()-(int main).sublime-snippet | 10++++++++++
Asyntaxes/C++/Snippets/main()-(main).sublime-snippet | 10++++++++++
Asyntaxes/C++/Snippets/namespace-..-(namespace).sublime-snippet | 10++++++++++
Asyntaxes/C++/Snippets/printf-..-(printf).sublime-snippet | 6++++++
Asyntaxes/C++/Snippets/read-file-(readF).sublime-snippet | 13+++++++++++++
Asyntaxes/C++/Snippets/std-map-(map).sublime-snippet | 6++++++
Asyntaxes/C++/Snippets/std-vector-(v).sublime-snippet | 6++++++
Asyntaxes/C++/Snippets/struct.sublime-snippet | 9+++++++++
Asyntaxes/C++/Snippets/template-typename-..-(template).sublime-snippet | 6++++++
Asyntaxes/C++/Symbol Index Hide Ctors.tmPreferences | 12++++++++++++
Asyntaxes/C++/Symbol Index Include Constants.tmPreferences | 12++++++++++++
Asyntaxes/C++/Symbol Index.tmPreferences | 12++++++++++++
Asyntaxes/C++/Symbol List - Indent Class Methods.tmPreferences | 16++++++++++++++++
Asyntaxes/C++/Symbol List - Namespace Spacing.tmPreferences | 14++++++++++++++
Asyntaxes/C++/Symbol List - Prefix Banner Items.tmPreferences | 17+++++++++++++++++
Asyntaxes/C++/Symbol List Hide Forward Decls.tmPreferences | 14++++++++++++++
Asyntaxes/C++/Symbol List.tmPreferences | 16++++++++++++++++
Asyntaxes/C++/syntax_test_accessor.c | 35+++++++++++++++++++++++++++++++++++
Asyntaxes/C++/syntax_test_accessor.cpp | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/C++/syntax_test_c.c | 939+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/C++/syntax_test_cpp.cpp | 2636+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/HTML/Comments.tmPreferences | 27+++++++++++++++++++++++++++
Asyntaxes/HTML/HTML.sublime-syntax | 732+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/HTML/Indentation Rules.tmPreferences | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/HTML/Snippets/html (begin tag).sublime-snippet | 14++++++++++++++
Asyntaxes/HTML/Snippets/html.sublime-snippet | 13+++++++++++++
Asyntaxes/HTML/Symbol List - ID.tmPreferences | 14++++++++++++++
Asyntaxes/HTML/encode_html_entities.py | 25+++++++++++++++++++++++++
Asyntaxes/HTML/html_completions.py | 504+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/HTML/syntax_test_html.html | 639+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Haskell/Comments.tmPreferences | 33+++++++++++++++++++++++++++++++++
Asyntaxes/Haskell/Haskell.sublime-build | 5+++++
Asyntaxes/Haskell/Haskell.sublime-syntax | 253+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Haskell/Indent Patterns.tmPreferences | 14++++++++++++++
Asyntaxes/Haskell/Literate Haskell.sublime-syntax | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Haskell/Snippets/Case.sublime-snippet | 7+++++++
Asyntaxes/Haskell/Snippets/Instance.sublime-snippet | 7+++++++
Asyntaxes/Haskell/Snippets/Lambda.sublime-snippet | 6++++++
Asyntaxes/Haskell/Snippets/Main.sublime-snippet | 8++++++++
Asyntaxes/Haskell/Snippets/module.sublime-snippet | 8++++++++
Asyntaxes/Haskell/Symbol List.tmPreferences | 14++++++++++++++
Asyntaxes/Haskell/syntax_test_haskell.hs | 188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Java/Ant.sublime-build | 12++++++++++++
Asyntaxes/Java/Comments - Properties.tmPreferences | 27+++++++++++++++++++++++++++
Asyntaxes/Java/Comments.tmPreferences | 33+++++++++++++++++++++++++++++++++
Asyntaxes/Java/Completion Rules.tmPreferences | 12++++++++++++
Asyntaxes/Java/Indentation Rules Annex.tmPreferences | 14++++++++++++++
Asyntaxes/Java/Indentation Rules.tmPreferences | 22++++++++++++++++++++++
Asyntaxes/Java/Indexed Symbol List.tmPreferences | 14++++++++++++++
Asyntaxes/Java/Java Server Pages (JSP).sublime-syntax | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Java/Java.sublime-completions | 224+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Java/Java.sublime-syntax | 1246+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Java/JavaC.sublime-build | 5+++++
Asyntaxes/Java/JavaDoc.sublime-syntax | 195+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Java/JavaProperties.sublime-syntax | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Java/Snippets/abstract.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/assert.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/break.sublime-snippet | 7+++++++
Asyntaxes/Java/Snippets/case.sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/catch.sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/class.sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/constant-string.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/constant.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/default.sublime-snippet | 7+++++++
Asyntaxes/Java/Snippets/else-if.sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/else.sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/final.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/for-(each).sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/for.sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/if.sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/import-junit_framework_TestCase;.sublime-snippet | 7+++++++
Asyntaxes/Java/Snippets/import.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/interface.sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/java_beans_.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/java_io.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/java_math.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/java_net_.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/java_util_.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/method-(main).sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/method.sublime-snippet | 9+++++++++
Asyntaxes/Java/Snippets/package.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/print.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/println.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/private.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/protected.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/public.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/return.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/static.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/switch.sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/synchronized.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/test-case.sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/test.sublime-snippet | 8++++++++
Asyntaxes/Java/Snippets/throw.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/variable.sublime-snippet | 6++++++
Asyntaxes/Java/Snippets/while.sublime-snippet | 8++++++++
Asyntaxes/Java/Symbol List - Classes.tmPreferences | 14++++++++++++++
Asyntaxes/Java/Symbol List - Constants.tmPreferences | 17+++++++++++++++++
Asyntaxes/Java/Symbol List - Inner Class Methods.tmPreferences | 19+++++++++++++++++++
Asyntaxes/Java/Symbol List - Inner Classes.tmPreferences | 16++++++++++++++++
Asyntaxes/Java/Symbol List - Inner Inner Class Methods.tmPreferences | 19+++++++++++++++++++
Asyntaxes/Java/Symbol List - Inner Inner Classes.tmPreferences | 16++++++++++++++++
Asyntaxes/Java/Symbol List - Method.tmPreferences | 19+++++++++++++++++++
Asyntaxes/Java/Symbol List - Modules.tmPreferences | 14++++++++++++++
Asyntaxes/Java/Symbol List - Properties.tmPreferences | 16++++++++++++++++
Asyntaxes/Java/syntax_test_java.java | 2550+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Java/syntax_test_java_properties.properties | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Java/syntax_test_jsp.jsp | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Python/Completion Rules.tmPreferences | 12++++++++++++
Asyntaxes/Python/Default.sublime-keymap | 25+++++++++++++++++++++++++
Asyntaxes/Python/Miscellaneous.tmPreferences | 33+++++++++++++++++++++++++++++++++
Asyntaxes/Python/Python.sublime-build | 15+++++++++++++++
Asyntaxes/Python/Python.sublime-syntax | 2210+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Python/Regular Expressions (Python).sublime-syntax | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Python/Snippets/New-Class.sublime-snippet | 9+++++++++
Asyntaxes/Python/Snippets/New-Property.sublime-snippet | 9+++++++++
Asyntaxes/Python/Snippets/Try-Except-Else-Finally.sublime-snippet | 13+++++++++++++
Asyntaxes/Python/Snippets/Try-Except-Else.sublime-snippet | 11+++++++++++
Asyntaxes/Python/Snippets/Try-Except-Finally.sublime-snippet | 11+++++++++++
Asyntaxes/Python/Snippets/Try-Except.sublime-snippet | 9+++++++++
Asyntaxes/Python/Snippets/__magic__.sublime-snippet | 6++++++
Asyntaxes/Python/Snippets/for.sublime-snippet | 9+++++++++
Asyntaxes/Python/Snippets/function.sublime-snippet | 7+++++++
Asyntaxes/Python/Snippets/if-__name__-==-'__main__'.sublime-snippet | 7+++++++
Asyntaxes/Python/Snippets/if.sublime-snippet | 9+++++++++
Asyntaxes/Python/Snippets/method.sublime-snippet | 7+++++++
Asyntaxes/Python/Snippets/while.sublime-snippet | 9+++++++++
Asyntaxes/Python/Symbol Index.tmPreferences | 14++++++++++++++
Asyntaxes/Python/Symbol List.tmPreferences | 19+++++++++++++++++++
Asyntaxes/Python/syntax_test_python.py | 1459+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/Python/syntax_test_python_strings.py | 702+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/SQL/Comments.tmPreferences | 33+++++++++++++++++++++++++++++++++
Asyntaxes/SQL/Miscellaneous.tmPreferences | 16++++++++++++++++
Asyntaxes/SQL/SQL.sublime-syntax | 240+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntaxes/SQL/syntax_test_sql.sql | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
168 files changed, 22711 insertions(+), 0 deletions(-)

diff --git a/syntaxes/ASP/ASP.sublime-syntax b/syntaxes/ASP/ASP.sublime-syntax @@ -0,0 +1,694 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: ASP +file_extensions: + - asa # asp is handled by HTML-ASP.sublime-syntax +scope: source.asp +variables: + apostrophe_comment_begin: "'" + rem_comment_begin: '\b(?i:REM)\b' + whitespace_or_end_of_statement: '(?=\s|$|:|{{apostrophe_comment_begin}}|{{rem_comment_begin}}|%>)' + identifier: '[a-zA-Z]\w*|\[(?:(?!%>|\]).)*(?:\]|(\n|(?=%>)))' # reserved words can be used if enclosed in square brackets, as can other characters not normally accepted + comparison_operators: '[=><]' + math_operators: '(?:[+*^&/\\-]|\b(?i:Mod)\b)' + logical_operators: '\b(?i:And|Not|Or|Xor|Is)\b' + operators: '{{comparison_operators}}|{{math_operators}}|{{logical_operators}}' + literal_number_hex: '(&[hH])\h+(&)?(?={{whitespace_or_end_of_statement}}|{{operators}}|[,)_])' + literal_number_decimal: '(?:(?:\d+\.\d*|\.?\d+)(?i:e[+-]?\d+)?)(?={{whitespace_or_end_of_statement}}|{{operators}}|[,)_])' + reserved_words: '\b(?i:Class|Sub|Function|Const|Dim|ReDim|Public|Private|End|Preserve|Select|Case|If|Else|ElseIf|Then|For|Each|Next|ByRef|ByVal|Set|Call|New|Option|With|To|In|While|Wend|Until|Loop|On|GoTo|Resume|Let|Get|Exit|Do)\b' # Default|Step|Error|Property are not reserved words + keywords: '\b(?i:Empty|False|Nothing|Null|True)\b' + constants: '\b(?i:vbTrue|vbFalse|vbCr|vbCrLf|vbFormFeed|vbLf|vbNewLine|vbNullChar|vbNullString|vbTab|vbVerticalTab|vbBinaryCompare|vbTextCompare|vbSunday|vbMonday|vbTuesday|vbWednesday|vbThursday|vbFriday|vbSaturday|vbUseSystemDayOfWeek|vbFirstJan1|vbFirstFourDays|vbFirstFullWeek|vbGeneralDate|vbLongDate|vbShortDate|vbLongTime|vbShortTime|vbObjectError|vbEmpty|vbNull|vbInteger|vbLong|vbSingle|vbDouble|vbCurrency|vbDate|vbString|vbObject|vbError|vbBoolean|vbVariant|vbDataObject|vbDecimal|vbByte|vbArray|vbOkCancel|vbOkOnly|vbYesNo|vbYesNoCancel|vbAbortRetryIgnore|vbRetryCancel|vbYes|vbNo|vbAbort|vbCancel|vbIgnore|vbRetry|vbCritical|vbExclamation|vbInformation|vbQuestion|vbDefaultButton[123])\b' + functions: '\b(?i:Abs|Array|Add|Asc|Atn|CBool|CByte|CCur|CDate|CDbl|Chr|CInt|CLng|Conversions|Cos|CreateObject|CSng|CStr|Date|DateAdd|DateDiff|DatePart|DateSerial|DateValue|Day|Derived|Math|Escape|Eval|Exists|Exp|Filter|FormatCurrency|FormatDateTime|FormatNumber|FormatPercent|GetLocale|GetObject|GetRef|Hex|Hour|InputBox|InStr|InStrRev|Int|Fix|IsArray|IsDate|IsEmpty|IsNull|IsNumeric|IsObject|Item|Items|Join|Keys|LBound|LCase|Left|Len|LoadPicture|Log|LTrim|RTrim|Trim|Maths|Mid|Minute|Month|MonthName|MsgBox|Now|Oct|Remove|RemoveAll|Replace|RGB|Right|Rnd|Round|ScriptEngine|ScriptEngineBuildVersion|ScriptEngineMajorVersion|ScriptEngineMinorVersion|Second|SetLocale|Sgn|Sin|Space|Split|Sqr|StrComp|String|StrReverse|Tan|Time|TimeSerial|TimeValue|TypeName|UBound|UCase|Unescape|VarType|Weekday|WeekdayName|Year)\b' + asp_builtin_classes: '\b(?i:Application|ObjectContext|Request|Response|Server|Session)\b' + asp_builtin_events: '\b(?i:Application_OnEnd|Application_OnStart|OnTransactionAbort|OnTransactionCommit|Session_OnEnd|Session_OnStart)\b' + class_magic_funcs: '\b(?i:Class_Initialize|Class_Terminate)\b' + +contexts: + root_asp: + - match: '(?=%>)' + pop: true + + main: + - match: '\b(?i:End){{whitespace_or_end_of_statement}}' + scope: invalid.illegal.unexpected-token.asp + - match: '(?i:Option\s+Explicit)' + scope: keyword.asp + - include: definitions + - include: statements + + comments: + - match: '{{apostrophe_comment_begin}}' + scope: punctuation.definition.comment.asp + push: + - meta_scope: comment.line.apostrophe.asp + - include: root_asp + - match: \n + pop: true + - match: '{{rem_comment_begin}}' + scope: punctuation.definition.comment.asp + push: + - meta_scope: comment.line.rem.asp + - include: root_asp + - match: \n + pop: true + + line_continuation_char: + - match: '\b_' + scope: punctuation.separator.continuation.line.asp + push: + - match: '\S.*' + scope: invalid.illegal.expected-end-of-line.asp + - match: $ + set: + - match: '(?=\S)' # for VBS, use ^, but ASP allows multiple whitespace-only lines after the _, so we use (?=\S) + pop: true + + allow_line_continuation: + - match: '[\t ]+' + scope: '' + - include: line_continuation_char + - include: comments + + not_end_of_statement: + - match: ':' + scope: invalid.illegal.unexpected-end-of-statement.asp + pop: true + - match: \n + scope: invalid.illegal.unexpected-end-of-statement.asp + pop: true + - match: '{{rem_comment_begin}}|{{apostrophe_comment_begin}}' + set: + - meta_scope: invalid.illegal.unexpected-end-of-statement.asp + - match: \n + pop: true + - include: allow_line_continuation + + expect_not_end_of_statement: + - match: '' # this match pattern has been added to disable the illegal highlighting where a statement ends unexpectedly - to more closely match other syntaxes + pop: true + - include: not_end_of_statement + - match: '\s*(?=\S)' + pop: true + + expect_identifier_member_reference: + - match: '\s*({{identifier}})' + captures: + 1: variable.other.member.asp + pop: true + - match: '' # this match pattern has been added to disable the illegal highlighting where a statement ends unexpectedly - to more closely match other syntaxes + pop: true + - include: unexpected_token + + expect_identifier_reference: + - match: '\s*({{identifier}})' + captures: + 1: variable.other.asp + # 2: invalid.illegal.unclosed-variable-identifier.asp + pop: true + - match: '' # this match pattern has been added to disable the illegal highlighting where a statement ends unexpectedly - to more closely match other syntaxes + pop: true + - include: unexpected_token + + inside_string: + - meta_scope: string.quoted.double.asp + - include: root_asp + - match: \n + scope: invalid.illegal.unclosed-string.asp + pop: true + - match: '""' + scope: constant.character.escape.apostrophe.asp + - match: '"' + scope: punctuation.definition.string.end.asp + pop: true + + illegal_names: + - match: '{{keywords}}|{{constants}}|{{reserved_words}}|{{functions}}|{{asp_builtin_classes}}' + scope: invalid.illegal.name.asp + pop: true + + allow_statement_separator: + - match: ':' + scope: punctuation.terminator.statement.asp + pop: true + + unexpected_token: + - match: \n + scope: invalid.illegal.missing-token.asp + pop: true + - match: '\S+' + scope: invalid.illegal.unexpected-token.asp + pop: true + + statements: + - include: variable_definitions + - include: allow_line_continuation + - match: '\b(?i:On\s+Error\s+)' + scope: storage.type.asp + push: + - include: not_end_of_statement + - match: '\b(?i:Resume\s+Next){{whitespace_or_end_of_statement}}' + scope: storage.type.asp + pop: true + - match: '\b(?i:Goto\s+0){{whitespace_or_end_of_statement}}' + scope: storage.type.asp + pop: true + - include: unexpected_token + - match: '\b(?i:Randomize\s+Timer){{whitespace_or_end_of_statement}}' + scope: storage.type.asp + - match: '\b(?i:(Call)|(Set)){{whitespace_or_end_of_statement}}' + captures: + 1: keyword.other.call.asp + 2: keyword.other.set.asp + push: expect_identifier_reference + - match: '\b(?i:Exit\s+(?:Sub|Function|Property|For|Do)){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + - include: control_flow + - include: expression + + definitions: + - include: class_definitions + - include: method_definitions + - include: variable_definitions + + class_definitions: + - match: '\b(?i:Class)[ \t]+' + scope: storage.type.asp + push: class_name + + class_name: + - meta_scope: meta.class.asp meta.class.identifier.asp + - include: allow_line_continuation + - include: illegal_names + - match: '{{identifier}}' + scope: entity.name.class.asp + set: inside_class + - include: unexpected_token + + inside_class: + - meta_content_scope: meta.class.asp meta.class.body.asp + - match: '\b(?i:End){{whitespace_or_end_of_statement}}' + set: + - meta_scope: meta.class.asp meta.class.body.asp storage.type.class.end.asp + - include: allow_line_continuation + - match: '\b(?i:Class){{whitespace_or_end_of_statement}}' + pop: true + - include: unexpected_token + - include: method_definitions + - match: '\b((?i:Public(?:\s+Default)?|Private)\s+)?((?i:Property)){{whitespace_or_end_of_statement}}' + captures: + 1: storage.modifier.asp + 2: storage.type.function.asp + push: + - meta_scope: meta.method.asp meta.method.identifier.asp + - meta_content_scope: storage.type.function.asp + - include: not_end_of_statement + - match: '\b(?i:Get|Let|Set){{whitespace_or_end_of_statement}}' + set: [inside_method_without_meta, method_name_without_meta] + - include: unexpected_token + - include: variable_definitions + - include: allow_line_continuation + - match: '\S' # only field/method/property definitions allowed inside a class definition + scope: invalid.illegal.unexpected-token.asp + + inside_method_without_meta: + - match: '' + set: inside_method + + method_name_without_meta: + - match: '' + set: method_name + + variable_definitions: + - match: '\b(?i:(?:(?:Public|Private)\s+)?Const){{whitespace_or_end_of_statement}}' + scope: storage.modifier.asp + push: constant_body + - match: '\b(?i:Dim|ReDim(?:\s+Preserve)?){{whitespace_or_end_of_statement}}' + scope: storage.modifier.asp + push: dim_body + - match: '\b(?i:Private|Public(?!\s+Default))\s+(?!(?i:Function|Sub|Property))' + scope: storage.modifier.asp + push: dim_body + + constant_body: + - include: not_end_of_statement + - include: illegal_names + - match: '{{identifier}}' + scope: entity.name.constant.asp + set: + - include: not_end_of_statement + - match: '\s*(=)\s*' + captures: + 1: keyword.operator.assignment.asp + set: [constant_separator, constant_value] + - include: unexpected_token + + constant_separator: + - match: '\s*(,)\s*' + captures: + 1: punctuation.separator.variable-declaration.asp + set: constant_body + - include: allow_statement_separator + - match: '' + pop: true + + constant_value: + #- include: not_end_of_statement # this include has been commented out to disable the illegal highlighting where a statement ends unexpectedly - to more closely match other syntaxes + - include: allow_line_continuation # as the above include has been commented out, this one has been added in it's place + - match: '{{whitespace_or_end_of_statement}}' # as the above include has been commented out, this match pattern has been added to pop at the end of the logical statement + pop: true + - match: '{{literal_number_hex}}' + scope: constant.numeric.integer.hexadecimal.asp + captures: + 1: punctuation.definition.numeric.hexadecimal.asp + 2: punctuation.definition.numeric.hexadecimal.asp + pop: true + - match: '{{literal_number_decimal}}' + scope: constant.numeric.float.decimal.asp + pop: true + - match: '{{constants}}' + scope: constant.language.asp + pop: true + - match: '{{keywords}}' + scope: support.type.vb.asp # maybe should be keyword or constant? + pop: true + - match: '"' + scope: punctuation.definition.string.begin.asp + set: inside_string + - include: unexpected_token + + dim_body: + - include: not_end_of_statement + - include: illegal_names + - match: '{{identifier}}' + scope: variable.other.asp + set: + - include: allow_line_continuation + - match: '\(' + scope: punctuation.section.array.begin.asp + push: + - meta_scope: meta.array.definition.asp + - include: not_end_of_statement + - match: \) + scope: punctuation.section.array.end.asp + pop: true + - include: expression + - match: ',' + scope: punctuation.separator.array.asp + - match: '\s*(,)\s*' + captures: + 1: punctuation.separator.variable-declaration.asp + set: dim_body + - match: '' + pop: true + - include: unexpected_token + + method_definitions: + - match: '\b((?i:Public(?:\s+Default)?|Private)\s+)?((?i:Sub|Function)){{whitespace_or_end_of_statement}}' + captures: + 0: meta.method.asp meta.method.identifier.asp + 1: storage.modifier.asp + 2: storage.type.function.asp + push: [inside_method_without_meta, method_name_without_meta] + + method_name: + - meta_content_scope: meta.method.asp meta.method.identifier.asp + - include: allow_line_continuation + - include: illegal_names + - match: '{{asp_builtin_events}}|{{class_magic_funcs}}' + scope: entity.name.function.asp support.function.magic.event.asp + set: after_method_name + - match: '{{identifier}}' + scope: entity.name.function.asp + set: after_method_name + - match: $ + set: inside_method + + after_method_name: + - meta_content_scope: meta.method.asp meta.method.identifier.asp + - match: \( + scope: punctuation.section.parens.begin.asp + set: + - match: \) + scope: meta.method.asp meta.method.identifier.asp punctuation.section.parens.end.asp + pop: true + - match: $ + set: not_end_of_statement + - match: '(?=\S)' + push: + - meta_scope: meta.method.asp meta.method.identifier.asp + - match: '(?=\)|$)' + pop: true + - include: not_end_of_statement + - match: '((?i:ByRef|ByVal)\s+)?({{identifier}})' + captures: + 1: storage.modifier.reference.asp + 2: variable.parameter.function.asp + push: + - match: '\s*(\()(\))\s*' + captures: + 1: punctuation.section.array.begin.asp + 2: punctuation.section.array.end.asp + set: after_method_param_name + - include: after_method_param_name + - match: '(?:(?![,)])\S)+' + scope: invalid.illegal.unexpected-token.asp + - match: '\s+' + - match: ':' + scope: meta.method.asp punctuation.terminator.statement.asp + pop: true + - include: allow_line_continuation + - match: $ + pop: true + - include: unexpected_token + + after_method_param_name: + - match: '(?=\)|$)' + pop: true + - include: not_end_of_statement + - match: '\s*(,)\s*' + captures: + 1: punctuation.separator.parameter-declaration.asp + pop: true + - match: '(?:(?![,)])\S)+' + scope: invalid.illegal.unexpected-token.asp + pop: true + + inside_method: + - meta_content_scope: meta.method.asp meta.method.body.asp + - include: inside_block + - match: '\b(?i:End){{whitespace_or_end_of_statement}}' + scope: storage.type.function.end.asp + set: + - meta_content_scope: meta.method.asp storage.type.function.end.asp + - include: allow_line_continuation + - match: '\b(?i:Function|Sub|Property){{whitespace_or_end_of_statement}}' + scope: meta.method.asp storage.type.function.end.asp + pop: true + - include: unexpected_token + - include: statements + + control_flow: + - match: '\b(?i:If){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + push: then_could_be_block_or_single_line + - match: '\b(?i:With){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + push: [inside_control_flow_with, expression_until_end_of_statement, expect_not_end_of_statement] + - match: '\b(?i:Select\s+Case){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + push: [inside_control_flow_select, expression_until_end_of_statement, expect_not_end_of_statement] + - match: '\b(?i:Do){{whitespace_or_end_of_statement}}' + scope: meta.do.block.asp keyword.control.flow.asp + push: + - match: '\s+(?i:While|Until){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + set: [inside_control_flow_do, expression_until_end_of_statement, expect_not_end_of_statement] + - match: '' + set: inside_control_flow_do + - match: '\b(?i:While){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + push: [inside_control_flow_while, expression_until_end_of_statement, expect_not_end_of_statement] + - match: '\b(?i:For\s+Each){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + push: [control_flow_foreach_in, expect_identifier_reference] + - match: '\b(?i:For){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + push: [control_flow_forto, expect_identifier_reference] + + then_could_be_block_or_single_line: + - meta_content_scope: meta.between-if-and-then.asp + - match: '[\t ]+' + scope: '' # so that the meta_content_scope will apply to whitespace + - match: '\b(?i:Then){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + set: + - match: '\s*(?=$|{{apostrophe_comment_begin}}|{{rem_comment_begin}}|%>)' + set: inside_control_flow_if_block + - match: '' # if the above didn't match, then it is a single line if block + set: inside_control_flow_if_single_line + #- include: not_end_of_statement # this include has been commented out to disable the illegal highlighting where a statement ends unexpectedly - to more closely match other syntaxes + - match: '{{whitespace_or_end_of_statement}}' # the above commented out include has been replaced with this, to exit the if scope if there is no `Then` on the same logical line + pop: true + - include: expression + + elseif_then_block: + - meta_content_scope: meta.between-if-and-then.asp + - match: '\b(?i:Then){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + set: inside_control_flow_if_block + - include: expression + - include: not_end_of_statement + + expression: + - match: \) + scope: invalid.illegal.stray-close-bracket.asp + - match: '{{literal_number_hex}}' + scope: constant.numeric.integer.hexadecimal.asp + captures: + 1: punctuation.definition.numeric.hexadecimal.asp + 2: punctuation.definition.numeric.hexadecimal.asp + - match: '{{literal_number_decimal}}' + scope: constant.numeric.float.decimal.asp + - match: '{{constants}}' + scope: support.type.vb.asp # maybe this should be constant.language.asp + - match: '{{functions}}' + scope: support.function.vb.asp # TODO: scope opening and closing parens i.e. LBound(var_name) but needs to handle (ignore) nested parens LBound((var_name)). Will also apply to things like Response.Write below. Note that parens are optional (when return value is not used) i.e. on it's own line, `LBound var_name` is valid. In other cases the parens can't be accurately scoped, because we don't know if they are for array access or method params + - match: '{{keywords}}' + scope: storage.type.asp + - include: operators + - match: '\b(?i:New){{whitespace_or_end_of_statement}}' + scope: keyword.other.new.asp + push: expect_identifier_reference + - match: '{{reserved_words}}' + scope: invalid.illegal.unexpected-token.literal.asp + - match: '"' + scope: punctuation.definition.string.begin.asp + push: inside_string + - match: '\b((?i:Request))\b(?:(?i:(\.)\s*(?:(BinaryRead)|(ClientCertificate|Cookies|Form|QueryString|ServerVariables)|(TotalBytes)))\b)?' + captures: # https://msdn.microsoft.com/en-us/library/ms524948%28v=vs.90%29.aspx + 1: support.class.asp + 2: punctuation.accessor.dot.asp + 3: support.function.asp + 4: support.class.collection.asp + 5: support.property.asp + - match: '\b((?i:Response))\b(?:(?i:(\.)\s*(?:(AddHeader|AppendToLog|BinaryWrite|Clear|End|Flush|Redirect|Write)|(Buffer|CacheControl|Charset|CodePage|ContentType|Expires|ExpiresAbsolute|IsClientConnected|LCID|PICS|Status)|(Cookies)))\b)?' + captures: # https://msdn.microsoft.com/en-us/library/ms525405%28v=vs.90%29.aspx + 1: support.class.asp + 2: punctuation.accessor.dot.asp + 3: support.function.asp + 4: support.property.asp + 5: support.class.collection.asp + - match: '\b((?i:Server))\b(?:(?i:(\.)\s*(?:(CreateObject|Execute|GetLastError|HTMLEncode|MapPath|Transfer|URLEncode)|(ScriptTimeout)))\b)?' + captures: # https://msdn.microsoft.com/en-us/library/ms525541%28v=vs.90%29.aspx + 1: support.class.asp + 2: punctuation.accessor.dot.asp + 3: support.function.asp + 4: support.property.asp + - match: '\b((?i:Server))\b(?:(?i:(\.)\s*(?:(Abandon)|(CodePage|LCID|SessionID|Timeout)|(Contents|StaticObjects)))\b)?' + captures: # https://msdn.microsoft.com/en-us/library/ms524319%28v=vs.90%29.aspx + 1: support.class.asp + 2: punctuation.accessor.dot.asp + 3: support.function.asp + 4: support.property.asp + 5: support.class.collection.asp + - match: '\b((?i:ObjectContext))\b(?:(?i:(\.)\s*(SetAbort|SetComplete))\b)?' + captures: # https://msdn.microsoft.com/en-us/library/ms525667%28v=vs.90%29.aspx + 1: support.class.asp + 2: punctuation.accessor.dot.asp + 3: support.function.asp + - match: '\b((?i:Application))\b(?:(?i:(\.)\s*(?:(Lock|Unlock)|(Contents|StaticObjects)))\b)?' + captures: # https://msdn.microsoft.com/en-us/library/ms524319%28v=vs.90%29.aspx + 1: support.class.asp + 2: punctuation.accessor.dot.asp + 3: support.function.asp + 4: support.class.collection.asp + - match: '{{identifier}}' + captures: + 0: variable.other.asp + #1: invalid.illegal.unclosed-variable-identifier.asp + push: + - match: '\s+(?=\.)' + scope: invalid.illegal.unexpected-token.asp # . punctuation accessor must come immediately after an identifier + pop: true + - match: '' + pop: true + - match: \( + scope: punctuation.section.parens.begin.asp + push: inside_parens + - include: allow_line_continuation + + inside_parens: + - match: \) + scope: punctuation.section.parens.end.asp + pop: true + - match: '\s+' # this match pattern has been added to disable the illegal highlighting where a statement ends unexpectedly - to more closely match other syntaxes + scope: '' + - match: '{{whitespace_or_end_of_statement}}' # this match pattern has been added to disable the illegal highlighting where a statement ends unexpectedly - to more closely match other syntaxes + pop: true + - match: $\n + scope: invalid.illegal.missing-close-bracket.asp + pop: true + - include: expression + + operators: + - match: '(?i:Is\s+Not\b)' # the correct syntax is: If Not (x Is y) Then ' the parens are optional but make it clearer + scope: invalid.illegal.unexpected-token.asp + - match: '{{math_operators}}\s*=' # ASP does not support shorthand + scope: invalid.illegal.unexpected-token.asp + - match: '><' # ASP not equal comparison is <> + scope: invalid.illegal.unexpected-token.asp + - match: '({{math_operators}}|{{comparison_operators}})|({{logical_operators}})' + captures: + 1: keyword.operator.asp + 2: keyword.operator.logical.asp + push: expect_not_end_of_statement + - match: ':' + scope: punctuation.terminator.statement.asp + - match: (\.)(\.)? + captures: + 1: punctuation.accessor.dot.asp + 2: invalid.illegal.unexpected-token.asp + push: expect_identifier_member_reference + + inside_control_flow_with: + - meta_scope: meta.with.block.asp + - include: inside_block + - match: '\b(?i:End){{whitespace_or_end_of_statement}}' + set: + - meta_scope: keyword.control.flow.asp + - include: allow_line_continuation + - match: '\b(?i:With){{whitespace_or_end_of_statement}}' + pop: true + - include: unexpected_token + - include: statements + + inside_control_flow_if_single_line: + - meta_scope: meta.if.line.asp + - match: $ + pop: true + - include: inside_control_flow_if_common + + inside_control_flow_if_block: + - meta_scope: meta.if.block.asp + - match: '\b(?i:ElseIf){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + set: elseif_then_block + - match: '\b(?i:End){{whitespace_or_end_of_statement}}' + set: + - meta_scope: keyword.control.flow.asp + - include: allow_line_continuation + - match: '\b(?i:If){{whitespace_or_end_of_statement}}' + pop: true + - include: unexpected_token + - include: inside_control_flow_if_common + + inside_control_flow_if_common: + - include: inside_block + - match: '\b(?i:Else){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + # the else retains the block or single line mode of the opening if statement, so we don't set a different context + - include: statements + + inside_control_flow_select: + - meta_scope: meta.select.block.asp + - include: inside_block + - match: '\b(?i:End){{whitespace_or_end_of_statement}}' + set: + - meta_scope: keyword.control.flow.asp + - include: allow_line_continuation + - match: '\b(?i:Select){{whitespace_or_end_of_statement}}' + pop: true + - include: unexpected_token + - match: '\b(?i:Case\s+Else){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + - match: '\b(?i:Case){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + push: [expression_until_end_of_statement, expect_not_end_of_statement] + - include: statements + + expression_until_end_of_statement: + - include: allow_statement_separator + - include: root_asp + - match: $ + pop: true + - include: expression + + inside_control_flow_do: + - meta_scope: meta.do.block.asp + - include: inside_block + - match: '\b(?i:Loop){{whitespace_or_end_of_statement}}' + set: + - meta_scope: keyword.control.flow.asp + - include: allow_line_continuation + - match: '\b(?i:While|Until){{whitespace_or_end_of_statement}}' + set: expression_until_end_of_statement + - match: '' + pop: true + - include: statements + + inside_control_flow_while: + - meta_scope: meta.while.block.asp + - include: inside_block + - match: '\b(?i:Wend){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + pop: true + - include: statements + + inside_control_flow_for: + - meta_scope: meta.for.block.asp + - include: inside_block + - match: '\b(?i:Next){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + pop: true + - include: statements + + control_flow_foreach_in: + - meta_scope: meta.for.block.asp + - match: '\b(?i:In){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + set: [inside_control_flow_for, expression_until_end_of_statement] + + control_flow_forto: + - meta_scope: meta.for.block.asp + - match: '\b(?i:To){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + set: [inside_control_flow_for, for_after_to, expect_not_end_of_statement] + - include: not_end_of_statement + - include: expression + + for_after_to: + - match: '\b(?i:Step){{whitespace_or_end_of_statement}}' + scope: keyword.control.flow.asp + set: [expression_until_end_of_statement, expect_not_end_of_statement] + - include: expression_until_end_of_statement + + inside_block: + - match: '%>' + scope: punctuation.section.embedded.end.inside-block.asp + push: + - clear_scopes: true + - meta_scope: text.html.asp + - match: '<%=?' + scope: punctuation.section.embedded.begin.inside-block.asp + pop: true + - match: '\s+$' # eat whitespace so that the lookahead on the next match pattern can match the next line if appropriate + push: + - match: ^ + pop: true + - match: '(\s*")?(?=[^<>]*>|\s+\w+=\s*")' # if the next occurrence of a < or > is a >, we are inside a tag. If it looks like an attribute is being defined, we are probably in a tag + scope: string.quoted.double.html punctuation.definition.string.end.html + push: # use a push and an include so that the root scope (text.html.basic) isn't applied + - meta_scope: meta.tag.after-embedded-asp.any.html + - match: '>' + scope: punctuation.definition.tag.end.html + set: scope:text.html.asp#html + - include: scope:text.html.basic#tag-attributes + with_prototype: + - match: '(?=<%)' + pop: true + - match: '' + push: scope:text.html.asp#html + with_prototype: + - match: '(?=<%)' + pop: true diff --git a/syntaxes/ASP/Comments.tmPreferences b/syntaxes/ASP/Comments.tmPreferences @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Comments</string> + <key>scope</key> + <string>source.asp</string> + <key>settings</key> + <dict> + <key>shellVariables</key> + <array> + <dict> + <key>name</key> + <string>TM_COMMENT_START</string> + <key>value</key> + <string>' </string> + </dict> + </array> + </dict> +</dict> +</plist> diff --git a/syntaxes/ASP/HTML-ASP.sublime-syntax b/syntaxes/ASP/HTML-ASP.sublime-syntax @@ -0,0 +1,60 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: HTML (ASP) +file_extensions: + - asp +scope: text.html.asp +contexts: + main: + - include: html + + asp_punctuation_begin: + - match: '<%' + scope: punctuation.section.embedded.begin.asp + push: + - match: '@' # https://msdn.microsoft.com/en-us/library/ms525579%28v=vs.90%29.aspx + set: asp_directive + - match: '=' + scope: punctuation.section.embedded.begin.asp + set: [close_embedded_asp, begin_embedded_asp_expression] + - match: '(?=\S)' + set: [close_embedded_asp, begin_embedded_asp] + + asp_directive: + - match: '@?\s*\b((?i:ENABLESESSIONSTATE|LANGUAGE|LCID|TRANSACTION))\b' + captures: + 1: constant.language.processing-directive.asp + push: + - match: '\s*(=)\s*' + scope: punctuation.separator.key-value.asp + pop: true + - match: '(?=%>)' + pop: true + - match: '%>' + scope: punctuation.section.embedded.end.asp + pop: true + + html: + - match: '' + set: + - include: scope:text.html.basic + with_prototype: + - include: asp_punctuation_begin + + begin_embedded_asp: + - meta_content_scope: source.asp.embedded.html + - match: '(?=%>)' + pop: true + - include: scope:source.asp + + begin_embedded_asp_expression: + - meta_content_scope: source.asp.embedded.html + - match: '(?=%>)' + pop: true + - include: scope:source.asp#expression + + close_embedded_asp: + - match: '%>' + scope: punctuation.section.embedded.end.asp + pop: true diff --git a/syntaxes/ASP/Indentation Rules.tmPreferences b/syntaxes/ASP/Indentation Rules.tmPreferences @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Indentation Rules</string> + <key>scope</key> + <string>source.asp - comment</string> + <key>settings</key> + <dict> + <key>decreaseIndentPattern</key> + <string>^\s*(?i:end|else|elseif|loop|wend|next)(\s|$)</string> + <key>increaseIndentPattern</key> + <string>(?x)(^\s*( + ((?i:private|public(?!\s+default))\s+)?(?i:function|sub|property)\s + | + (?i:class|if|select\s+case|with|do|for|while)\s + ))</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/ASP/Indexed Symbol List.tmPreferences b/syntaxes/ASP/Indexed Symbol List.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List</string> + <key>scope</key> + <string>source.asp entity.name.class.asp, source.asp entity.name.method.asp</string> + <key>settings</key> + <dict> + <key>showInIndexedSymbolList</key> + <integer>1</integer> + </dict> +</dict> +</plist> diff --git a/syntaxes/ASP/Symbol List.tmPreferences b/syntaxes/ASP/Symbol List.tmPreferences @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List</string> + <key>scope</key> + <string>source.asp meta.class.identifier.asp, source.asp meta.method.identifier.asp</string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>1</integer> + <key>symbolTransformation</key> + <string><![CDATA[ + s/(\[[^\]]*\])|\b_\b\s*|\(.*|(\s{2,})/$1(?2 )/g; (?# this ignores anything in square brackets, and: + - finds an underscore line continuation character and any whitespace following it, and replaces it with nothing + - finds an open paren and anything following it, and replaces it with nothing + - collapses multiple spaces into one + We don't have to worry about comments, because they are not allowed after an underscore.) + ]]></string> + </dict> +</dict> +</plist> diff --git a/syntaxes/ASP/syntax_test_asp.asp b/syntaxes/ASP/syntax_test_asp.asp @@ -0,0 +1,1135 @@ +' SYNTAX TEST "Packages/ASP/HTML-ASP.sublime-syntax" +<!DOCTYPE html> +<html> +'<- meta.tag.structure.any.html punctuation.definition.tag.begin.html - source.asp.embedded.html +'^^^^ meta.tag.structure.any.html entity.name.tag.structure.any.html +' ^ meta.tag.structure.any.html punctuation.definition.tag.end.html + <%@ TRANSACTION = Required %> +'^^ punctuation.section.embedded.begin.asp +' ^^^^^^^^^^^ constant.language.processing-directive.asp +' ^ punctuation.separator.key-value.asp +' ^^ punctuation.section.embedded.end.asp +<% + @language = VBScript ENABLESESSIONSTATE=False @@LCID=1033 +' ^^^^^^^^ constant.language.processing-directive.asp +' ^ punctuation.separator.key-value.asp +' ^^^^^^^^^^^^^^^^^^ constant.language.processing-directive.asp +' ^ punctuation.separator.key-value.asp +' ^^^^ constant.language.processing-directive.asp +' ^ punctuation.separator.key-value.asp +' comments are not supported here +'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - comment +%> +<% @ + transaction +' ^^^^^^^^^^^ constant.language.processing-directive.asp += required +'<- punctuation.separator.key-value.asp +%> +<% transaction=required %> +' ^^^^^^^^^^^ variable.other.asp - constant.language.processing-directive.asp +<head> +'<- meta.tag + <title>ASP Test Page: <%=Request.ServerVariables("SCRIPT_NAME")%></title> + ' ^^^ punctuation.section.embedded.begin.asp - source.asp + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.asp + ' ^^^^^^^ support.class.asp + ' ^ punctuation.accessor.dot.asp + ' ^^^^^^^^^^^^^^^ support.class.collection.asp + ' ^^ punctuation.section.embedded.end.asp - source.asp + ' ^^^^^^^^ meta.tag +</head> +<body> + <% + '^^ punctuation.section.embedded.begin.asp + 'this is a comment + '^ punctuation.definition.comment.asp + '^^^^^^^^^^^^^^^^^^^ comment.line.apostrophe.asp + + Option Explicit + '^^^^^^^^^^^^^^^ keyword + + Class TestClass + '^^^^^^^^^^^^^^^ meta.class.asp meta.class.identifier.asp - meta.class.body.asp + '^^^^^ storage.type.asp + ' ^^^^^^^^^ meta.class.asp meta.class.identifier.asp entity.name.class.asp + ' comment + '^^^^^^^^^^ comment.line.apostrophe.asp + '<- meta.class.body.asp - meta.class.identifier.asp + Private m_NameVar + '^^^^^^^ storage.modifier.asp - meta.method.identifier.asp + ' ^^^^^^^^^ variable.other.asp + Private m_CategoryVar + Public Const a = 2e-3, b2="c""": const c = 4, const = + '^^^^^^^^^^^^ storage.modifier.asp + ' ^ entity.name.constant.asp + ' ^ keyword.operator.assignment.asp + ' ^^^^ constant.numeric.float.decimal.asp + ' ^ punctuation.separator.variable-declaration.asp + ' ^^ entity.name.constant.asp + ' ^ keyword.operator.assignment.asp + ' ^^^^^ string.quoted.double.asp + ' ^ punctuation.terminator.statement.asp + ' ^^^^^ storage.modifier.asp + ' ^^^^^ invalid.illegal.name.asp - entity.name.constant.asp +'<- - invalid.illegal.unexpected-token.asp + Const d = &HAB + '^^^^^ storage.modifier.asp + ' ^^^^ constant.numeric.integer.hexadecimal.asp + ' ^^ punctuation.definition.numeric.hexadecimal.asp + Const e = "I am an unclosed string + ' ^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.asp + ' ^ invalid.illegal.unclosed-string.asp +'<- - invalid.illegal.unclosed-string.asp + + private sub Class_Initialize () + '^^^^^^^ storage.modifier.asp + ' ^^^ storage.type.function.asp + ' ^^^^^^^^^^^^^^^^ support.function.magic.event.asp + m_NameVar = "" + '^^^^^^^^^ variable.other.asp + ' ^ punctuation.definition.string.begin.asp + ' ^ punctuation.definition.string.end.asp + ' ^^ string.quoted.double.asp + ' ^ - string + End Sub + + Public Property Get Name() + '^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.asp meta.method.identifier.asp + '^^^^^^ storage.modifier.asp + ' ^^^^^^^^^^^^ storage.type.function.asp + ' ^^^^ entity.name.function.asp + ' ^ punctuation.section.parens.begin.asp - entity.name.function.asp + ' ^ punctuation.section.parens.end.asp + Name = m_NameVar +'<- meta.method.asp meta.method.body.asp - meta.method.identifier.asp + End Property + '^^^^^^^^^^^^ meta.method.asp + '^^^^^^^^^^^^ storage.type.function.end.asp + ' ^ - meta.method.asp - meta.method.body.asp - storage.type.function.end.asp + + public property let Name(nameParam) + '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.asp meta.method.identifier.asp + '^^^^^^ storage.modifier.asp + ' ^^^^^^^^^^^^ storage.type.function.asp + ' ^^^^ entity.name.function.asp - storage.type.function.asp + ' ^ punctuation.section.parens.begin.asp - entity.name.function.asp + ' ^^^^^^^^^ variable.parameter.function.asp + ' ^ punctuation.section.parens.end.asp + m_NameVar = nameParam + End Property + + Public Property Get Category + '^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.asp meta.method.identifier.asp + ' ^^^^^^^^^^^^ storage.type.function.asp + ' ^^^^^^^^ entity.name.function.asp + Category = m_CategoryVar +'<- meta.method.asp meta.method.body.asp - meta.method.identifier.asp + End Property + + Property Let Category(categoryParam + '^^^^^^^^^^^^^^^^^^^^^ meta.method.asp meta.method.identifier.asp + '^^^^^^^^^^^^ storage.type.function.asp + ' ^^^^^^^^ entity.name.function.asp + ' ^ punctuation.section.parens.begin.asp + ' ^^^^^^^^^^^^^ variable.parameter.function.asp + ' ^ invalid.illegal.unexpected-end-of-statement.asp + m_CategoryVar = categoryParam +'<- meta.method.asp meta.method.body.asp - meta.method.identifier.asp + End Property + '^^^^^^^^^^^^ meta.method.asp + '^^^^^^^^^^^^ storage.type.function.end.asp + ' ^ - meta.method.asp - meta.method.body.asp - storage.type.function.end.asp + + Private Property Set Category(categoryParam) Set m_CategoryVar = categoryParam End Property + '^^^^^^^ storage.modifier.asp + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.asp meta.class.body.asp meta.method.asp meta.method.identifier.asp - meta.method.identifier.asp meta.method.identifier.asp - meta.method.body.asp + ' ^^^^^^^^^^^^ storage.type.function.asp + ' ^^^^^^^^ entity.name.function.asp + ' ^ punctuation.section.parens.begin.asp + ' ^^^^^^^^^^^^^ variable.parameter.function.asp + ' ^ punctuation.section.parens.end.asp + ' ^^^ storage.type.function.asp - keyword - storage.type.asp + ' ^ meta.method.asp meta.method.body.asp - meta.method.identifier.asp + ' ^^^^^^^^^^^^ storage.type.function.end.asp + ' ^ - meta.method + + Public Default Function Go rem no parens + '^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.asp meta.method.identifier.asp + '^^^^^^^^^^^^^^ storage.modifier.asp + ' ^^^^^^^^ storage.type.function.asp + ' ^^ entity.name.function.asp + ' ^^^^^^^^^^^^^ comment.line.rem.asp + Go = "going... going... gone!" +'<- meta.method.asp meta.method.body.asp - meta.method.identifier.asp + '^^ - invalid + ' ^ keyword.operator.asp + End Function + '^^^^^^^^^^^^ meta.method.asp + '^^^^^^^^^^^^ storage.type.function.end.asp + ' ^ - meta.method + + Sub Test123:Call DoSomething:End Sub + '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.asp + '^^^ meta.method.asp meta.method.identifier.asp storage.type.function.asp + ' ^^^^^^^ meta.method.identifier.asp entity.name.function.asp + ' ^ punctuation.terminator.statement.asp + ' ^^^^^^^^^^^^^^^^ meta.method.body.asp + ' ^^^^^^^ storage.type.function.end.asp + ' ^ - meta.method + + Class SubClass ' nested classes are not allowed +'<- - invalid.illegal.unexpected-token.asp + '^^^^^ invalid.illegal.unexpected-token.asp + ' ^^^^^^^^ invalid.illegal.unexpected-token.asp + ' ^ comment.line.apostrophe.asp - invalid.illegal.unexpected-token.asp + + Sub Test1234 Set x = y + '^^^ invalid.illegal.unexpected-token.asp + End Sub + '^^^^^^^ meta.class.asp meta.method.asp storage.type.function.end.asp + + code_in_class_definition_but_outside_of_a_method = "invalid" + '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid.illegal.unexpected-token.asp + ' ^ invalid.illegal.unexpected-token.asp + ' ^^^^^^^^^ invalid.illegal.unexpected-token.asp + End Class + '^^^^^^^^^ storage.type.class.end.asp + '^^^^^^^^^ meta.class.body.asp + ' ^ - storage.type.class.end.asp - meta.class.body.asp + + Const blah = _ + + "blah"rem-"testing" + ' ^^^^^^ string.quoted.double.asp + ' ^^^^^^^^^^^^^^ comment.line.rem.asp - string + + Class TestClass2 Public Sub TestSub () Response.Write("wow") End Sub End Class + '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.asp + '^^^^^^^^^^^^^^^^ meta.class.identifier.asp - meta.class.body.asp - meta.class.identifier.asp meta.class.identifier.asp + '^^^^^ storage.type.asp + ' ^^^^^^^^^^ entity.name.class.asp + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.body.asp - meta.class.identifier.asp + ' ^^^^^^^^^^^^^^^^^^^^^ meta.method.asp meta.method.identifier.asp + ' ^^^^^^ storage.modifier.asp + ' ^^^ storage.type.function.asp + ' ^^^^^^^ entity.name.function.asp + ' ^^ punctuation.section.parens - meta.method.identifier.asp meta.method.identifier.asp + ' ^ meta.method.asp meta.method.body.asp - meta.method.identifier.asp + ' ^^^^^^ storage.type.function.end.asp + ' ^^^^^^^^^ meta.class.body.asp + ' ^^^^^^^^^ storage.type.class.end.asp + ' ^ - meta.class + + Const abc = 'fgfg + '^^^^^ storage.modifier.asp + ' ^^^ entity.name.constant.asp + Private a, b + '^^^^^^^ storage.modifier.asp + ' ^ variable.other.asp + ' ^ punctuation.separator.variable-declaration.asp + ' ^ variable.other.asp + Set a = new TestClass + '^^^ keyword.other.set.asp - storage.type.function.asp + ' ^ variable.other.asp + ' ^^^ keyword.other.new.asp + a.Name = blah + '^ variable.other.asp + ' ^ punctuation.accessor.dot.asp + + Function GetModifiedDate(path) ' test function + '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.asp meta.method.identifier.asp + ' ^ punctuation.definition.comment.asp + ' ^^^^^^^^^^^^^^^^ comment.line.apostrophe.asp + ' ^ - meta.method.identifier.asp + '^^^^^^^^ storage.type.function.asp + ' ^^^^^^^^^^^^^^^ entity.name.function.asp + ' ^ punctuation.section.parens.begin.asp + ' ^^^^ variable.parameter.function.asp + ' ^ punctuation.section.parens.end.asp + On Error Resume Next +'<- meta.method.body.asp - comment + '^^^^^^^^^^^^^^^^^^^^ storage.type.asp + Set fs = Server.CreateObject("Scripting.FileSystemObject") + '^^^ keyword.other.set.asp + ' ^ keyword.operator.asp + ' ^^^^^^ support.class.asp + ' ^ punctuation.accessor.dot.asp + ' ^^^^^^^^^^^^ support.function + ' ^ punctuation.definition.string.begin.asp + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.asp - punctuation.accessor.dot.asp + ' ^ punctuation.definition.string.end.asp + With fs + '^^^^ keyword.control.flow.asp + ' ^^ variable.other.asp + ' ^ meta.with.block.asp + Set rs = .GetFile(Server.MapPath(path)) + ' ^ meta.with.block.asp punctuation.accessor.dot.asp + ' ^ meta.with.block.asp punctuation.accessor.dot.asp + GetModifiedDate = rs.DateLastModified + Set rs = Nothing + '^^^ keyword.other.set.asp + ' ^ keyword.operator.asp + ' ^^^^^^^ storage.type.asp + .Close + '^ punctuation.accessor.dot.asp + ' ^^^^^ variable + . Close + '^ punctuation.accessor.dot.asp + ' ^ - invalid + ' ^^^^^ variable + End With + '^^^^^^^^ keyword.control.flow.asp + ' ^ - meta.with.block.asp + + Set fs = Nothing + On Error Goto 0 + '^^^^^^^^^^^^^^^ storage.type.asp + ' ^ - storage.type.asp + End Function + '^^^^^^^^^^^^ storage.type.function.end.asp + + modified = GetModifiedDate("demo_lastmodified.asp") + ' ^^^^^^^^^^^^^^^ variable + + Sub Example () + '^^^^^^^^^^^^^^ meta.method.asp meta.method.identifier.asp + '^^^ storage.type.function.asp + ' ^^^^^^^ entity.name.function.asp + ' ^ - entity.name.function.asp + ' ^^ punctuation.section.parens + div = 4 + ' ^ keyword.operator.asp + ' ^ constant.numeric + + If 1<div And 2>1 Then ' if block + '^^ keyword.control.flow.asp + ' ^^^^^^^^^^^^^^^ meta.between-if-and-then.asp + ' ^ keyword.operator.asp - punctuation.definition.tag.begin.html + ' ^^^ keyword.operator.logical.asp + ' ^ keyword.operator.asp - punctuation.definition.tag.end.html + ' ^^^^ keyword.control.flow.asp + ' ^ meta.if.block.asp + Exit Sub + '^^^^^^^^ keyword.control.flow.asp + ElseIf "abc>"<>"def= then " Then + '^^^^^^ keyword.control.flow.asp + ' ^^^^^^^^^^^^^^^^^^^^^^ meta.between-if-and-then.asp + ' ^ string.quoted.double.asp - keyword.operator.asp + ' ^^ keyword.operator.asp + ' ^ string.quoted.double.asp - keyword.operator + ' ^^^^ string.quoted.double.asp - keyword.control.flow.asp + ' ^^^^ keyword.control.flow.asp + ' ^ meta.if.block.asp + ElseIf new TestClass Then + ' ^^^ keyword.other.new.asp + ' ^^^^^^^^^ variable + Else + '^^^^ keyword.control.flow.asp + ' ^ meta.if.block.asp + example = example - 1 + ' ^ keyword.operator.asp + example -= 1 + ' ^^ invalid.illegal.unexpected-token.asp + example = example \ 5 + ' ^ keyword.operator.asp + End If + '^^^^^^ keyword.control.flow.asp + ' ^ - meta.if.block.asp + End Sub + '^^^^^^^ storage.type.function.end.asp + + If 1 _ + = 2 Then Call DoSomething + ' ^^^^ keyword.control.flow.asp + ' ^^^^^^^^^^^^^^^^^ meta.if.line.asp - meta.if.block.asp + ' ^^^^ keyword.other.call.asp + ' ^^^^^^^^^^^ variable + ' ^ - meta.if.line.asp + + Function IIf(expr, true_part, false_part) ' https://support.microsoft.com/en-us/kb/219271 + ' ^^^^ variable.parameter.function.asp + ' ^^^^^^^^^ variable.parameter.function.asp + ' ^^^^^^^^^^ variable.parameter.function.asp + If expr Then IIf = true_part Else IIf = false_part + ' ^^^^^^^^^^^^^^^^^ meta.if.line.asp + ' ^^ - keyword.control.flow.asp + ' ^^^^^^^^^^^^^^^^^ meta.if.line.asp + ' ^ - meta.if.line.asp + End Function + + If a is not nothing then a.b = a.b + 2 + ' ^^^^^^ invalid.illegal.unexpected-token.asp + ' ^^^^^^^ storage.type.asp + ' ^^^^ keyword.control.flow.asp + ' ^^^^^^^^^^^^^^^^^^ meta.between-if-and-then.asp + ' ^^^^^^^^^^^^^^ meta.if.line.asp + ' ^ - meta.if.line.asp + If not a is nothing then a.b = a.b + 2 + ' ^^^^^^^^^^^^^^^^^^ meta.between-if-and-then.asp + ' ^^^^^^^^^^^^^^ meta.if.line.asp + ' ^ variable.other.asp + ' ^ punctuation.accessor.dot.asp + ' ^ variable + ' ^ - meta.if.line.asp + ' ^^^^^^ - invalid + ' ^^ keyword.operator.logical.asp + ' ^^^^^^^ storage.type.asp + + If a Then + ' ^ meta.if.block.asp - meta.if.line.asp + DoSomething ( invalid_token_inside_parens, 2, if ) + ' ^^ invalid.illegal.unexpected-token.literal.asp + '^^^^^^^^^^^ variable + ' ^ punctuation.section.parens.begin.asp + ' ^ punctuation.section.parens.end.asp + ElseIf a = b Then AnotherSomething ' despite this being on the same line as the ElseIf, the End If is still required because the opening if statement was a block + ' ^ meta.if.block.asp - meta.if.line.asp + Else DoSomethingElse ' despite this being on the same line as the Else, the End If is still required because the opening if statement was a block + '^^^^ keyword.control.flow.asp + ' ^^^^^^^^^^^^^^^^ meta.if.block.asp + End If + ' ^ - meta.if.block.asp + + If a Then Call + + Dim str1_ REM example + '^^^ storage.modifier.asp + ' ^ - constant.numeric.asp + ' ^ - punctuation.separator.continuation.line.asp + ' ^^^ punctuation.definition.comment.asp + ' ^^^^^^^^^^^^ comment.line.rem.asp + str1 = "this is a ""hello-world""" & " " &"""" + "test" +_ 'continue on next line, comments not allowed here +'<- - comment.line.rem.asp + ' ^^ string.quoted.double.asp constant.character.escape.apostrophe.asp + ' ^ string.quoted.double.asp - keyword.operator.asp + ' ^^ string.quoted.double.asp constant.character.escape.apostrophe.asp - punctuation.definition.string.end.asp + ' ^ string.quoted.double.asp punctuation.definition.string.end.asp + ' ^ keyword.operator.asp + ' ^^^ string.quoted.double.asp + ' ^ keyword.operator.asp + ' ^^^^ string.quoted.double.asp + ' ^^ constant.character.escape.apostrophe.asp - punctuation.definition.string.end.asp + ' ^ keyword.operator.asp + ' ^ punctuation.separator.continuation.line.asp + ' ^^^^^^^^^^^^^ invalid.illegal.expected-end-of-line.asp - comment + Chr(34) & vbCrLf _ + + ' ^^^ support.function.vb.asp + ' ^ punctuation.section.parens.begin.asp + ' ^ punctuation.section.parens.end.asp + ' ^^^^^^ support.type.vb.asp + ' ^ punctuation.separator.continuation.line.asp + ' ^ invalid.illegal.expected-end-of-line.asp + + value = 1/2 + ' ^ keyword.operator.asp + value = &HFF mod 3 + ' ^^^^ constant.numeric.integer.hexadecimal.asp + ' ^^^ keyword.operator.asp + Select Case call value:Case 1 + '^^^^^^^^^^^ keyword.control.flow.asp + ' ^^^^ meta.select.block.asp invalid.illegal.unexpected-token.literal.asp + ' ^ meta.select.block.asp punctuation.terminator.statement.asp + ' ^^^^ keyword.control.flow.asp + Case 2 + '^^^^ keyword.control.flow.asp +'<- meta.select.block.asp + Case + Case vbNullString + '^^^^ keyword.control.flow.asp + ' ^^^^^^^^^^^^ support.type.vb.asp + Case Else + '^^^^^^^^^ keyword.control.flow.asp + If value >= 4 and Value<=5 Then MsgBox("no end if required here") + ' ^^ keyword.operator.asp + ' ^^ keyword.operator.asp + ' ^^^^^^ support.function.vb.asp + If Not (value Is Nothing) then valueis = vbFalse + ' ^^^ keyword.operator.logical.asp + ' ^ punctuation.section.parens.begin.asp + ' ^^ keyword.operator.logical.asp + ' ^ punctuation.section.parens.end.asp + ' ^^ - keyword.operator + ' ^^^^^^^ support.type.vb.asp +'<- meta.select.block.asp + End Select + '^^^^^^^^^^ keyword.control.flow.asp + ' ^ - meta.select.block.asp + 'the underscore in this comment should be ignored _ as should the colon : + ' ^ comment.line.apostrophe.asp - keyword - invalid - punctuation + ' ^ comment.line.apostrophe.asp - keyword - punctuation - invalid + + Sub Test _ + _ ' ^ punctuation.separator.continuation.line.asp + _ '^^^ storage.type.function.asp + _ ' ^^^^ entity.name.function.asp + _ '^^^^^^^^^ meta.method.asp meta.method.identifier.asp + (_ + _ ' ^ meta.method.asp meta.method.identifier.asp punctuation.section.parens.begin.asp + _ ' ^ punctuation.separator.continuation.line.asp + abc, ByRef def _ + _ '^^^ meta.method.asp meta.method.identifier.asp variable.parameter.function.asp + _ ' ^ meta.method.asp meta.method.identifier.asp punctuation.separator.parameter-declaration.asp + _ ' ^^^^^ meta.method.asp meta.method.identifier.asp storage.modifier.reference.asp + _ ' ^^^ meta.method.asp meta.method.identifier.asp variable.parameter.function.asp + _ ' ^ meta.method.asp meta.method.identifier.asp punctuation.separator.continuation.line.asp + ) + '^ meta.method.asp meta.method.identifier.asp punctuation.section.parens.end.asp + + Dim x _ + ,y() + ' ^^ meta.array.definition.asp punctuation.section.array + a) + '^ invalid.illegal.stray-close-bracket.asp + a( + ReDim arr(2,b) + '^^^^^ storage.modifier.asp + ' ^^^ variable.other.asp + ' ^^^^^ meta.array.definition.asp + ' ^ constant.numeric + ' ^ punctuation.separator.array.asp + ' ^ variable.other.asp - invalid - constant.numeric + ' ^ punctuation.section.array.end.asp + + ReDim arr(dim, other) + ' ^^^ invalid.illegal + ' ^ - invalid + ' ^^^^^^^^ - invalid + ReDim Dim(2,4) + ' ^^^ invalid.illegal.name.asp + +'<- - invalid + + Dim a(0,&H5&) + ' ^^^^^^^ meta.array.definition.asp + ' ^ punctuation.section.array.begin.asp + ' ^ constant.numeric + ' ^ punctuation.separator.array.asp + ' ^^^^ constant.numeric.integer.hexadecimal.asp + ' ^^ punctuation.definition.numeric.hexadecimal.asp + ' ^ punctuation.definition.numeric.hexadecimal.asp + ' ^ punctuation.section.array.end.asp + b = a Is Empty : Dim loop,nope : Dim foobar + '^^^^^^^^^^^^^^^^^^^^^ - invalid.illegal.unexpected-token.asp - invalid.illegal.name.asp + ' ^^^^^^^^^^^^^ - invalid + ' ^ punctuation.terminator.statement.asp + ' ^^^ storage.modifier.asp + ' ^^^^ invalid.illegal.name.asp - variable.other.asp + ' ^ punctuation.terminator.statement.asp + ' ^^^ storage.modifier.asp + Dim hello_world, 2 + ' ^ invalid.illegal.unexpected-token.asp - variable + ' ^ - invalid + + ReDim Preserve arr ( &HA,c) + '^^^^^^^^^^^^^^ storage.modifier.asp + ' ^^^ variable.other.asp + ' ^^^^^^^^ meta.array.definition.asp + ' ^ punctuation.section.array.begin.asp + ' ^^^ constant.numeric.integer.hexadecimal.asp + ' ^ punctuation.separator.array.asp + ' ^ punctuation.section.array.end.asp + For x = LBound(a) to UBound(a) Step 2 'test + '^^^ keyword.control.flow.asp + ' ^ variable.other.asp + ' ^ keyword.operator.asp + ' ^^^^^^ support.function.vb.asp + ' ^ punctuation.section.parens.begin.asp + ' ^ variable.other.asp + ' ^ punctuation.section.parens.end.asp + ' ^ punctuation.section.parens.begin.asp + ' ^ variable.other.asp + ' ^ punctuation.section.parens.end.asp + ' ^^ keyword.control.flow.asp + ' ^^^^^^ support.function.vb.asp + ' ^^^^ keyword.control.flow.asp + ' ^ constant.numeric + ' ^ meta.for.block.asp + ' ^^^^^^ comment.line.apostrophe.asp + a(x) = x * 10 + '^ variable.other.asp + ' ^ variable.other.asp + ' ^ punctuation.section.parens.begin.asp - variable.other.asp + ' ^ punctuation.section.parens.end.asp - variable.other.asp + ' ^ variable.other.asp + ' ^ keyword.operator.asp + Next + '^^^^ keyword.control.flow.asp + ' ^ - meta.for.block.asp + End Sub + + Sub NoParens fg + ' ^^^^^^^^ meta.method.asp meta.method.identifier.asp entity.name.function.asp + ' ^^ invalid.illegal.unexpected-token.asp - meta.method.identifier.asp + End Sub + + Function NoParams'() + '^^^^^^^^^^^^^^^^^ meta.method.asp meta.method.identifier.asp + ' ^^^^^^^^ entity.name.function.asp + ' ^^^ comment.line.apostrophe.asp - entity.name.function.asp - invalid.illegal.unexpected-token-after-method-declaration.asp - punctuation.section.parens + NoParams = InStr(1, "hello_'", "L", vbTextCompare) +'<- meta.method.body.asp - invalid.illegal.unexpected-token-after-method-declaration.asp - meta.method.identifier.asp + '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - invalid.illegal.unexpected-token-after-method-declaration.asp - meta.method.asp meta.method.identifier.asp - invalid.illegal.expected-end-of-line.asp - comment.line.rem.asp + ' ^^^^^ support.function.vb.asp + ' ^ punctuation.section.parens.begin.asp + ' ^^^^^^^^^^^^^ support.type.vb.asp + ' ^ punctuation.section.parens.end.asp + Test = True Xor False + ' ^^^^ storage.type.asp + ' ^^^ keyword.operator.logical.asp + ' ^^^^^ storage.type.asp + End Function + Sub Test2 + '^^^ meta.method.asp meta.method.identifier.asp storage.type.function.asp + ' ^^^^^ meta.method.asp meta.method.identifier.asp entity.name.function.asp + hello = world + '^ - entity.name.function.asp - meta.method.asp meta.method.identifier.asp + End Sub + Call Test + '^^^^ keyword.other.call.asp + Call NoParams + + Sub Wow (test _ 'test + ,def _ '^^^^^^^^^^^^^^^^^^^^^^ meta.method.asp meta.method.identifier.asp + _ '^^^ storage.type.function.asp + ' ^^^ entity.name.function.asp + ' ^^^^^ invalid.illegal.expected-end-of-line.asp + ) ' this bracket doesn't form part of the method declaration - the line above is missing a _ and contains non-whitespace + '^ meta.method.body.asp - meta.method.identifier.asp - punctuation.section.parens.end.asp + MsgBox "hi", vbOkCancel or vbExclamation or vbDefaultButton1, "title" + ' ^^^^^^^^^^ support.type.vb.asp - variable.other.asp + ' ^^ keyword.operator.logical.asp + ' ^^^^^^^^^^^^^ support.type.vb.asp + ' ^^^^^^^^^^^^^^^^ support.type.vb.asp + End Sub + + Dim [], [ažė+, (], [dim], [a(4)] + ' ^^ variable.other.asp + ' ^ punctuation.separator.variable-declaration.asp - meta.variable-definition.asp + ' ^^^^^^^^^ variable.other.asp - keyword - punctuation + ' ^^^^^ variable.other.asp + ' ^ punctuation.separator.variable-declaration.asp + ' ^^^^^^ variable.other.asp - meta.array.definition.asp - punctuation.section.array + [dim] = 5 ^ 2 + '^^^^^ variable.other.asp + ' ^ keyword.operator.asp + + Function [abcdef()hij] (blah) + '^^^^^^^^ storage.type.function.asp + ' ^^^^^^^^^^^^^ entity.name.function.asp + ' ^ - entity.name.function.asp + ' ^^^^ variable.parameter.function.asp + [abcdef()hij] = blah + '^^^^^^^^^^^^^ variable.other.asp + ' ^^^^ variable.other.asp + End Function + '^^^^^^^^^^^^ storage.type.function.end.asp + Response.Write [abcdef()hij]("hello") + ' ^^^^^^^^^^^^^ variable.other.asp + ' ^ punctuation.section.parens.begin.asp + ' ^ punctuation.section.parens.end.asp + + End If ' nothing to end + '^^^ invalid.illegal.unexpected-token.asp +' check that the incomplete if gets dropped off after the end of the line +'<- - meta.between-if-and-then.asp invalid.illegal.unexpected-end-of-statement.asp + + For Each cookie In Request.Cookies + '<- - meta.between-if-and-then.asp + '^^^^^^^^ keyword.control.flow.asp + ' ^^^^^^ variable.other.asp + ' ^^ keyword.control.flow.asp + ' ^ meta.for.block.asp + Response.Write(vbCrLf & cookie) + '^^^^^^^^ support.class.asp + ' ^ punctuation.accessor.dot.asp + ' ^^^^^^ support.type.vb.asp + ' ^ keyword.operator.asp + ' ^^^^^^ variable.other.asp + If x = y Then Exit For + '^^ keyword.control.flow.asp + ' ^ variable.other.asp + ' ^ variable.other.asp + ' ^^^^ keyword.control.flow.asp + ' ^^^^^^^^^ meta.if.line.asp + ' ^^^^^^^^ keyword.control.flow.asp + ' ^ - meta.if.line.asp + Response.Write("----" & vbCrLf) + '^^^^^^^^ support.class.asp + ' ^ punctuation.section.parens.begin.asp + ' ^ punctuation.section.parens.end.asp + + abc = x >< y + ' ^^ invalid.illegal.unexpected-token.asp + abc = x <> y + ' ^^ keyword.operator.asp + Next + '^^^^ keyword.control.flow.asp + ' ^ - meta.for.block.asp + + If + '^^ keyword.control.flow.asp + ' ^ meta.between-if-and-then.asp + ' the above if statement has no "Then" + '^ - meta.between-if-and-then.asp + + Do + '^^ meta.do.block.asp keyword.control.flow.asp + Exit Do + '^^^^^^^ meta.do.block.asp keyword.control.flow.asp + Loop + '^^^^ keyword.control.flow.asp + ' ^ - meta.do.block.asp + + Do + Exit Do + Loop Until x = y + '^^^^^^^^^^ keyword.control.flow.asp + ' ^ variable.other.asp + ' ^ keyword.operator.asp + ' ^ variable.other.asp + ' ^ - meta.do.block.asp + + Do + Exit Do + Loop While x <> y + '^^^^^^^^^^ keyword.control.flow.asp + ' ^ variable.other.asp + ' ^ variable.other.asp + ' ^ - meta.do.block.asp - meta.while.block.asp + + While True + '^^^^^ meta.while.block.asp keyword.control.flow.asp + ' ^^^^ storage.type.asp - variable.other.asp + Wend + '^^^^ keyword.control.flow.asp + ' ^ - meta.while.block.asp + + Application.Lock + '^^^^^^^^^^^ support.class.asp - variable.other.asp + ' ^ punctuation.accessor.dot.asp + ' ^^^^ support.function.asp - variable.other.asp + Application("NumVisits") = Application("NumVisits") + 1 + '^^^^^^^^^^^ support.class.asp + ' ^ punctuation.section.parens.begin.asp + ' ^ punctuation.section.parens.end.asp + ' ^ punctuation.section.parens.begin.asp + ' ^ punctuation.section.parens.end.asp + Application.Unlock + '^^^^^^^^^^^ support.class.asp + ' ^ punctuation.accessor.dot.asp + ' ^^^^^^ support.function.asp + %> + This application page has been visited + <%= Application("NumVisits") %> times! + <% + + Sub Application_OnStart() + '^^^ storage.type.function.asp + ' ^^^^^^^^^^^^^^^^^^^ entity.name.function.asp support.function.magic.event.asp + Application("NumVisits") = 0 + ' ^ punctuation.section.parens.begin.asp + ' ^ punctuation.section.parens.end.asp + End Sub + '^^^^^^^ storage.type.function.end.asp + + Sub Application_OnStartup() + ' ^^^^^^^^^^^^^^^^^^^^^ entity.name.function.asp - support.function.magic.event.asp + End Sub + + Sub Func_With_Explicit_Arrays(ByRef array_variable(), blah ()) + ' ^ punctuation.section.array.begin.asp + ' ^ punctuation.section.array.end.asp + ' ^^^^^^^^^^^^ - invalid + ' ^ punctuation.separator.parameter-declaration.asp + ' ^^^^ variable.parameter.function.asp + ' ^ punctuation.section.array.begin.asp + ' ^ punctuation.section.array.end.asp + ' ^ punctuation.section.parens.end.asp + End Sub + + Sub Another_Test()rem + '^^^ storage.type.function.asp + ' ^^^^^^^^^^^^ entity.name.function.asp + ' ^^ punctuation.section.parens + ' ^^^^ comment.line.rem.asp - meta.method.identifier.asp + Const ForAppending = 8 + '^^^^^ meta.method.body.asp storage.modifier.asp + + Set objFSO = CreateObject("Scripting.FileSystemObject") + ' ^^^^^^ variable.other.asp + Set objTextFile = objFSO.OpenTextFile("d:\logfile.c", ForAppending, True) + ' ^^^^^^^^^^^^ variable.other.asp + + Dim Line + ' ^^^^ variable.other.asp + Line = 0 + '^^^^ variable.other.asp + Do While Line < 2000 + '^^^^^^^^ keyword.control.flow.asp + '^^^^^^^^^^^^^^^^^^^^^ meta.do.block.asp - meta.while.block.asp + ' ^^^^ variable.other.asp + ' ^ keyword.operator.asp + ' ^^^^ constant.numeric + objTextFile.WriteLine("long l" & Line & " = " & Line) + '^^^^^^^^^^^ variable.other.asp + ' ^^^^^^^^^ variable + Line = Line + 1 + Dim WshShell 'http://stackoverflow.com/a/2237479/4473405 + Set WshShell=Server.CreateObject("WScript.Shell") + WshShell.Run "waitfor /T " & numberOfSecond & "SignalThatWontHappen", , True + + do until Line = Line + '^^^^^^^^ keyword.control.flow.asp + ' ^^^^ variable.other.asp + ' ^^^^ variable.other.asp + '^^^^^^^^^^^^^^^^^^^^^ meta.do.block.asp meta.do.block.asp - invalid + ' this code will never run + loop + '^^^^ keyword.control.flow.asp + Loop + '^^^^ keyword.control.flow.asp + ' ^ - meta.do.block.asp + + objTextFile.Close + + Set objTextFile = Nothing + Set objFSO = Nothing + End _ + Sub + ' ^^^ storage.type.function.end.asp - meta.method.identifier.asp + + a=3.4*.5*6.*0.25 + ' ^^^ constant.numeric.float.decimal.asp + ' ^^ constant.numeric.float.decimal.asp + ' ^^ constant.numeric.float.decimal.asp + ' ^^^^ constant.numeric.float.decimal.asp + a=a+0.8 + ' ^^^ constant.numeric.float.decimal.asp + ExampleSub 3.4,.5,6.,&HA,&H2,7*2.1e2,9,-3.402823E+38, 3.402823E38 ,1.401298E-45,Round(4.94065645841247E-324),a2,2a,123.456.789.321.654.321 + ' ^^^ constant.numeric.float.decimal.asp + ' ^^ constant.numeric.float.decimal.asp + ' ^^ constant.numeric.float.decimal.asp + ' ^^^ constant.numeric.integer.hexadecimal.asp + ' ^^^ constant.numeric.integer.hexadecimal.asp + ' ^ constant.numeric + ' ^^^^^ constant.numeric.float.decimal.asp + ' ^ constant.numeric + ' ^^^^^^^^^^^^ constant.numeric.float.decimal.asp + ' ^^^^^^^^^^^ constant.numeric.float.decimal.asp + ' ^^^^^^^^^^^^ constant.numeric.float.decimal.asp + ' ^^^^^ support.function.vb.asp + ' ^^^^^^^^^^^^^^^^^^^^^ constant.numeric.float.decimal.asp + ' ^^ - constant.numeric + ' ^ - constant.numeric + ' ^^^^^^^^ - constant.numeric + + response.write(test..b) + ' ^ punctuation.accessor.dot.asp + ' ^ invalid.illegal.unexpected-token.asp + + [abc=123:def] = 4 + '^^^^^^^^^^^^^ variable.other.asp - punctuation - keyword - constant + + Randomize Timer + '^^^^^^^^^^^^^^^ storage.type.asp + a=Abs(-6)*Rnd()*2+Fix(2.75) + Int(3.14)/Sin(30)+Cos(20)+Tan(40)+Sqr(4)+Log(6)+Sgn(3) + ' ^^^ support.function.vb.asp + ' ^^^ support.function.vb.asp + ' ^^^ support.function.vb.asp + ' ^^^ support.function.vb.asp + ' ^^^ support.function.vb.asp + ' ^^^ support.function.vb.asp + ' ^^^ support.function.vb.asp + ' ^^^ support.function.vb.asp + ' ^^^ support.function.vb.asp + ' ^^^ support.function.vb.asp + + b=Oct(12) & Hex(12) + ' ^^^ support.function.vb.asp + ' ^^^ support.function.vb.asp + c = CSng("123") + CDbl("123") + CInt("123")+CLng("123") + ' ^^^^ support.function.vb.asp + ' ^^^^ support.function.vb.asp + ' ^^^^ support.function.vb.asp + ' ^^^^ support.function.vb.asp + d = Time + ' ^^^^ support.function.vb.asp + e = Date() + ' ^^^^ support.function.vb.asp + + submit = 2 + '^^^^^^ variable.other.asp - storage.type.function.asp + function_hello = 2 + '^^^^^^^^^^^^^^ variable.other.asp - storage.type.function.asp + + %> + '^^ punctuation.section.embedded.end.asp + ' ^ - source.asp.embedded.html + This file was last modified on: <%response.write(modified) + '^ - source.asp.embedded.html + ' ^^ punctuation.section.embedded.begin.asp + ' ^ source.asp.embedded.html + ' ^^^^^^^^ support.class.asp + ' ^^^^^ support.function.asp + %> + + <p>foobar</p> + '^^^ text.html.asp meta.tag.block.any.html - source.asp.embedded.html + <%='test %> + '^^^ punctuation.section.embedded.begin.asp - source.asp + ' ^^^^^^ comment.line.apostrophe.asp + ' ^^ punctuation.section.embedded.end.asp - comment + ' ^^^ - source.asp.embedded.html + <%= "this" + Chr(32) + "that" %> + '^^^ punctuation.section.embedded.begin.asp - source.asp.embedded.html + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.asp.embedded.html + ' ^^^^^^ string.quoted.double.asp + ' ^ keyword.operator.asp + ' ^^^ support.function.vb.asp + ' ^^ punctuation.section.embedded.end.asp - source.asp +<% + +Class ClassContainingMethodsWithReservedWords + Sub [Select]() + '^^^ storage.type.function.asp + ' ^^^^^^^^ entity.name.function.asp + ' ^ - entity.name.function.asp + + End Sub + + Sub [End]() + '^^^ storage.type.function.asp + ' ^^^^^ entity.name.function.asp + ' ^ - entity.name.function.asp + + End Sub +End Class +Set ccmwrw = new ClassContainingMethodsWithReservedWords +ccmwrw.Select() +' ^ punctuation.accessor.dot.asp +' ^^^^^^ variable.other.member.asp - invalid - keyword +' ^^ - variable - invalid - keyword +ccmwrw. Select() ' spaces are not allowed after the . +' ^ punctuation.accessor.dot.asp +' ^ - invalid +' ^^^^^^ variable.other.member.asp - invalid - keyword +' ^^ - variable - invalid - keyword +ccmwrw.End +' ^ punctuation.accessor.dot.asp +' ^^^ variable.other.member.asp - invalid - keyword +' ^ - invalid - variable +ccmwrw .End +' ^ invalid.illegal.unexpected-token.asp +' ^ punctuation.accessor.dot.asp +' ^^^ variable.other.member.asp - invalid - keyword +' ^ - invalid +ccmwrw.[End] () +' ^ punctuation.accessor.dot.asp +' ^^^^^ variable.other.member.asp - invalid - keyword +' ^^^ - variable - invalid - keyword +ccmwrw. [End] () +' ^ punctuation.accessor.dot.asp +' ^ - invalid - variable +' ^^^^^ variable.other.member.asp - invalid - keyword +' ^^^ - variable - invalid - keyword + +_ + 'a line continuation char can be followed by just a comment on the next non blank line + ' ^ punctuation.definition.comment.asp + ' ^^^^^^ comment.line.apostrophe.asp + +t = [unclosed variable identifier +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.other.asp +Dim test +'<- storage.modifier.asp - variable + rem the syntax on the next line will cause an unterminated string constant error +'^^^^^^ comment.line.rem.asp +test = "hello%> +' ^^^^^^ source.asp.embedded.html string.quoted.double.asp +' ^^ punctuation.section.embedded.end.asp - string.quoted.double.asp +' ^ - source.asp.embedded.html + +<footer> +'^^^^^^ text.html.asp meta.tag.block.any.html entity.name.tag.block.any.html + <% With abc %> + ' ^^^^ keyword.control.flow.asp + ' ^^ text.html.asp punctuation.section.embedded.end.inside-block.asp + <p>Some conditional content in the footer</p> + '<- text.html.asp meta.tag.block.any.html punctuation.definition.tag.begin.html + <% End With %> + '^^ punctuation.section.embedded.begin.inside-block.asp + ' ^^^^^^^^ keyword.control.flow.asp + ' ^^ punctuation.section.embedded.end.asp - meta.with.block.asp + ' ^ - source.asp.embedded.html + <% If abc = "def" Then %> + ' ^ meta.if.block.asp - meta.if.line.asp + <span id="span1">Text here</span> + ' ^^ text.html.asp meta.tag.inline.any.html meta.attribute-with-value.id.html entity.other.attribute-name.id.html + ' ^^ text.html.asp meta.tag.inline.any.html punctuation.definition.tag.begin.html + <% End If %> + ' ^ meta.if.block.asp + ' ^^^^^^ keyword.control.flow.asp + ' ^^^^ - meta.if.block.asp + +</footer><% [%><br /> +' ^^ punctuation.section.embedded.end.asp +' ^^ text.html.asp meta.tag.inline.any.html entity.name.tag.inline.any.html +<% Sub InventiveMethodNameHere(list) %> +' ^^^ meta.method.identifier.asp storage.type.function.asp +' ^ text.html.asp source.asp.embedded.html meta.method.asp meta.method.body.asp +' ^^ text.html.asp punctuation.section.embedded.end.inside-block.asp + <ul> +<% + for each item in list + '^^^^^^^^ text.html.asp source.asp.embedded.html meta.method.asp meta.method.body.asp meta.for.block.asp keyword.control.flow.asp + ' ^^ text.html.asp source.asp.embedded.html meta.method.asp meta.method.body.asp meta.for.block.asp keyword.control.flow.asp + %><li><%= item %></li><% + '^^^^^^ text.html.asp source.asp.embedded.html meta.method.asp meta.method.body.asp meta.for.block.asp + ' ^ meta.tag.inline.any.html punctuation.definition.tag.begin.html + ' ^^^ punctuation.section.embedded.begin.inside-block.asp + ' ^^ punctuation.section.embedded.end.inside-block.asp + Next + '^^^^ text.html.asp source.asp.embedded.html meta.method.asp meta.method.body.asp keyword.control.flow.asp + ' ^ - meta.for.block.asp +%></ul> +<% End Sub %> +' ^^^^^^^ text.html.asp source.asp.embedded.html meta.method.asp storage.type.function.end.asp +' ^ - meta.method.asp + <p class="<% If True Then %>test<% End If %>"></p> +'^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.block.any.html +' ^^^^^^^^^ meta.tag.block.any.html +' ^^^^^ meta.attribute-with-value.class.html entity.other.attribute-name.class.html +' ^^^ meta.attribute-with-value.class.html string.quoted.double.html +' ^^^^^^^^^^ meta.attribute-with-value.class.html string.quoted.double.html +' ^ - string +' ^^^^^^^^^^^^^^^^ meta.class-name.html +' ^^^^^^^^^^ meta.class-name.html +' ^^ punctuation.section.embedded.begin.asp +' ^^^^^^^^^^^^^ source.asp.embedded.html +' ^^ keyword.control.flow.asp +' ^^^^ meta.between-if-and-then.asp storage.type.asp +' ^^^^ keyword.control.flow.asp +' ^ meta.if.block.asp +' ^ meta.if.block.asp +' ^^ punctuation.section.embedded.end.inside-block.asp +' ^^ punctuation.section.embedded.begin.inside-block.asp +' ^^^^^^ keyword.control.flow.asp +' ^^ punctuation.section.embedded.end.asp - meta.if.block.asp +' ^ punctuation.definition.tag.end.html + + <p <%= "class=""test""" %> id="test1"></p> +'^^^ meta.tag.block.any.html +' ^^^^^^^^^^^^^^^^ meta.tag.block.any.html +'^ punctuation.definition.tag.begin.html +' ^ entity.name.tag.block.any.html +' ^^^ punctuation.section.embedded.begin.asp +' ^^^^^^^^^^^^^^^^ string.quoted.double.asp +' ^^ punctuation.section.embedded.end.asp +' ^^ meta.attribute-with-value.id.html entity.other.attribute-name.id.html +' ^^^^^ meta.attribute-with-value.id.html string.quoted.double.html meta.toc-list.id.html +' ^ punctuation.definition.tag.end.html +' ^ - meta.tag.block.any.html +<% If True Then + Do + %> + <span <%= "class=""test""" %> id="test2"></span> + '^^^^^^ meta.tag.inline.any.html + '^ punctuation.definition.tag.begin.html + ' ^^^^ entity.name.tag.inline.any.html + ' ^^^ punctuation.section.embedded.begin.inside-block.asp + ' ^^^^^^^^^^^^^^^^ string.quoted.double.asp + ' ^^ punctuation.section.embedded.end.inside-block.asp + ' ^^^^^^^^^^^^ meta.tag + ' ^^ meta.attribute-with-value.id.html entity.other.attribute-name.id.html + ' ^^^^^ meta.attribute-with-value.id.html string.quoted.double.html meta.toc-list.id.html + ' ^ punctuation.definition.tag.end.html + ' ^^^^^^^ meta.tag.inline.any.html - meta.tag.after-embedded-asp.any.html + ' ^^ punctuation.definition.tag.begin.html + ' ^^^^ entity.name.tag.inline.any.html + ' ^ punctuation.definition.tag.end.html +<% Loop + End If %> + '^^^^^^ keyword.control.flow.asp + + <span <% If False Then %> class="test" <% End If %> id="test3"></span> +'^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.inline.any.html +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.inline.any.html +'^ punctuation.definition.tag.begin.html +' ^^^^ entity.name.tag.inline.any.html +' ^^ punctuation.section.embedded.begin.asp +' ^^ keyword.control.flow.asp +' ^^^^^ meta.between-if-and-then.asp storage.type.asp +' ^^^^ keyword.control.flow.asp +' ^^ punctuation.section.embedded.end.inside-block.asp +' ^^^^^^^^^^^^ meta.attribute-with-value.class.html +' ^^^^^ entity.other.attribute-name.class.html +' ^ punctuation.separator.key-value.html +' ^ string.quoted.double.html punctuation.definition.string.begin.html +' ^^^^ string.quoted.double.html meta.class-name.html +' ^ string.quoted.double.html punctuation.definition.string.end.html +' ^^ punctuation.section.embedded.begin.inside-block.asp +' ^^^^^^ keyword.control.flow.asp +' ^^ punctuation.section.embedded.end.asp +' ^^ meta.attribute-with-value.id.html entity.other.attribute-name.id.html +' ^^^^^ meta.attribute-with-value.id.html string.quoted.double.html meta.toc-list.id.html +' ^ punctuation.definition.tag.end.html + <span <% If True Then %> + class="test" +'^^^^^^^^^^^^^^ meta.tag +' ^^^^^^^^^^^^ meta.attribute-with-value.class.html +' ^^^^^ entity.other.attribute-name.class.html +' ^ punctuation.separator.key-value.html +' ^ string.quoted.double.html punctuation.definition.string.begin.html +' ^^^^ string.quoted.double.html meta.class-name.html +' ^ string.quoted.double.html punctuation.definition.string.end.html + <% End If %> +'^^ punctuation.section.embedded.begin.inside-block.asp +' ^^^^^^ keyword.control.flow.asp +' ^^ punctuation.section.embedded.end.asp + id="test4"></span> +'^^^^^^^^^^^ meta.tag +'^^ meta.attribute-with-value.id.html entity.other.attribute-name.id.html +' ^^^^^ meta.attribute-with-value.id.html string.quoted.double.html meta.toc-list.id.html +' ^ punctuation.definition.tag.end.html +' ^^^^^^^ meta.tag.inline.any.html - meta.tag.after-embedded-asp.any.html +' ^^ punctuation.definition.tag.begin.html +' ^^^^ entity.name.tag.inline.any.html +' ^ punctuation.definition.tag.end.html + <% If True Then %> +'^^ punctuation.section.embedded.begin.asp +' ^^ punctuation.section.embedded.end.inside-block.asp + <span class="<%= "test" %>" id="test5"></span> +'^^^^^^^^^^^^^ meta.tag.inline.any.html +' ^ string.quoted.double.html punctuation.definition.string.begin.html +' ^^^ punctuation.section.embedded.begin.inside-block.asp +' ^^ punctuation.section.embedded.end.inside-block.asp +' ^^^^^^^^^^^^^ meta.tag +' ^ string.quoted.double.html punctuation.definition.string.end.html +' ^^ meta.attribute-with-value.id.html entity.other.attribute-name.id.html +' ^^^^^ meta.attribute-with-value.id.html string.quoted.double.html meta.toc-list.id.html +' ^ punctuation.definition.tag.end.html +' ^^^^^^^ meta.tag.inline.any.html - meta.tag.after-embedded-asp.any.html +' ^^ punctuation.definition.tag.begin.html +' ^^^^ entity.name.tag.inline.any.html +' ^ punctuation.definition.tag.end.html + <% End If %> +'^^ punctuation.section.embedded.begin.inside-block.asp +' ^^^^^^ keyword.control.flow.asp +' ^^ punctuation.section.embedded.end.asp + <% + = hi = 2 ' will output a boolean expression - True or False %> +' ^ punctuation.section.embedded.begin.asp +' ^^^^^^^^^^ source.asp.embedded.html +' ^^ variable.other.asp +' ^ keyword.operator.asp +' ^ constant.numeric +' ^ comment + +'<- - comment - source.asp.embedded.html + </body> +'^^^^^^^ meta.tag.structure.any.html +<script type="text/javascript"> +<% If True Then %>var hello = "world";<% End If %> +</script> +</html> diff --git a/syntaxes/Assembly x86.sublime-syntax b/syntaxes/Assembly x86.sublime-syntax @@ -0,0 +1,68 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: Assembly x86 (NASM) +file_extensions: + - asm + - inc + - nasm +scope: source.assembly +contexts: + main: + - match: \b(?i)(v)?(aaa|aad|aam|aas|adc|add|addpd|addps|addsd|addss|addsubpd|addsubps|aesdec|aesdeclast|aesenc|aesenclast|aesimc|aeskeygenassist|and|andpd|andps|andnpd|andnps|arpl|blendpd|bmi|blendps|blendvpd|blendvps|bound|bsf|bsr|bswap|bt|btc|btr|bts|cbw|cwde|cdqe|clc|cld|cflush|clts|cmc|cmov(n?e|ge?|ae?|le?|be?|n?o|n?z)|cmp|cmppd|cmpps|cmps|cnpsb|cmpsw|cmpsd|cmpsq|cmpss|cmpxchg|cmpxchg8b|cmpxchg16b|comisd|comiss|cpuid|crc32|cvtdq2pd|cvtdq2ps|cvtpd2dq|cvtpd2pi|cvtpd2ps|cvtpi2pd|cvtpi2ps|cvtps2dq|cvtps2pd|cvtps2pi|cvtsd2si|cvtsd2ss|cvts2sd|cvtsi2ss|cvtss2sd|cvtss2si|cvttpd2dq|cvtpd2pi|cvttps2dq|cvttps2pi|cvttps2dq|cvttps2pi|cvttsd2si|cvttss2si|cwd|cdq|cqo|daa|das|dec|div|divpd|divps|divsd|divss|dppd|dpps|emms|enter|extractps|f2xm1|fabs|fadd|faddp|fiadd|fbld|fbstp|fchs|fclex|fnclex|fcmov(n?e|ge?|ae?|le?|be?|n?o|n?z)|fcom|fcmop|fcompp|fcomi|fcomip|fucomi|fucomip|fcos|fdecstp|fdiv|fdivp|fidiv|fdivr|fdivrp|fidivr|ffree|ficom|ficomp|fild|fincstp|finit|fnint|fist|fistp|fisttp|fld|fld1|fldl2t|fldl2e|fldpi|fldlg2|fldln2|fldz|fldcw|fldenv|fmul|fmulp|fimul|fnop|fpatan|fprem|fprem1|fptan|frndint|frstor|fsave|fnsave|fscale|fsin|fsincos|fsqrt|fst|fstp|fstcw|fnstcw|fstenv|fnstenv|fsts(w?)|fnstsw|fsub|fsubp|fisub|fsubr|fsubrp|fisubr|ftst|fucom|fucomp|fucompp|fxam|fxch|fxrstor|fxsave|fxtract|fyl2x|fyl2xp1|haddpd|haddps|husbpd|hsubps|idiv|imul|in|inc|ins|insb|insw|insd|insertps|int|into|invd|invlpg|invpcid|iret|iretd|iretq|lahf|lar|lddqu|ldmxcsr|lds|les|lfs|lgs|lss|lea|leave|lfence|lgdt|lidt|llgdt|lmsw|lock|lods|lodsb|lodsw|lodsd|lodsq|lsl|ltr|maskmovdqu|maskmovq|maxpd|maxps|maxsd|maxss|mfence|minpd|minps|minsd|minss|monitor|mov|movapd|movaps|movbe|movd|movq|movddup|movdqa|movdqu|movq2q|movhlps|movhpd|movhps|movlhps|movlpd|movlps|movmskpd|movmskps|movntdqa|movntdq|movnti|movntpd|movntps|movntq|movq|movq2dq|movs|movsb|movsw|movsd|movsq|movsd|movshdup|movsldup|movss|movsx|movsxd|movupd|movups|movzx|mpsadbw|mul|mulpd|mulps|mulsd|mulss|mwait|neg|not|or|orpd|orps|out|outs|outsb|outsw|outsd|pabsb|pabsw|pabsd|packsswb|packssdw|packusdw|packuswb|paddb|paddw|paddd|paddq|paddsb|paddsw|paddusb|paddusw|palignr|pand|pandn|pause|pavgb|pavgw|pblendvb|pblendw|pclmulqdq|pcmpeqb|pcmpeqw|pcmpeqd|pcmpeqq|pcmpestri|pcmpestrm|pcmptb|pcmptgw|pcmpgtd|pcmpgtq|pcmpistri|pcmpisrm|pdep|pext|pextrb|pextrd|pextrq|pextrw|phaddw|phaddd|phaddsw|phinposuw|phsubw|phsubd|phsubsw|pinsrb|pinsrd|pinsrq|pinsrw|pmaddubsw|pmadddwd|pmaxsb|pmaxsd|pmaxsw|pmaxsw|pmaxub|pmaxud|pmaxuw|pminsb|pminsd|pminsw|pminub|pminud|pminuw|pmovmskb|pmovsx|pmovzx|pmuldq|pmulhrsw|pmulhuw|pmulhw|pmulld|pmullw|pmuludw|pop|popa|popad|popcnt|popf|popfd|popfq|por|prefetch|psadbw|pshufb|pshufd|pshufhw|pshuflw|pshufw|psignb|psignw|psignd|pslldq|psllw|pslld|psllq|psraw|psrad|psrldq|psrlw|psrld|psrlq|psubb|psubw|psubd|psubq|psubsb|psubsw|psubusb|psubusw|test|ptest|punpckhbw|punpckhwd|punpckhdq|punpckhddq|punpcklbw|punpcklwd|punpckldq|punpckldqd|push|pusha|pushad|pushf|pushfd|pxor|prcl|rcr|rol|ror|rcpps|rcpss|rdfsbase|rdgsbase|rdmsr|rdpmc|rdrand|rdtsc|rdtscp|rep|repe|repz|repne|repnz|roundpd|roundps|roundsd|roundss|rsm|rsqrps|rsqrtss|sahf|sal|sar|shl|shr|sbb|scas|scasb|scasw|scasd|set(n?e|ge?|ae?|le?|be?|n?o|n?z)|sfence|sgdt|shld|shrd|shufpd|shufps|sidt|sldt|smsw|sqrtpd|sqrtps|sqrtsd|sqrtss|stc|std|stmxcsr|stos|stosb|stosw|stosd|stosq|str|sub|subpd|subps|subsd|subss|swapgs|syscall|sysenter|sysexit|sysret|teset|ucomisd|ucomiss|ud2|unpckhpd|unpckhps|unpcklpd|unpcklps|vbroadcast|vcvtph2ps|vcvtp2sph|verr|verw|vextractf128|vinsertf128|vmaskmov|vpermilpd|vpermilps|vperm2f128|vtestpd|vzeroall|vzeroupper|wait|fwait|wbinvd|wrfsbase|wrgsbase|wrmsr|xadd|xchg|xgetbv|xlat|xlatb|xor|xorpd|xorps|xrstor|xsave|xsaveopt|xsetbv|lzcnt|extrq|insertq|movntsd|movntss|vfmaddpd|vfmaddps|vfmaddsd|vfmaddss|vfmaddsubbpd|vfmaddsubps|vfmsubaddpd|vfmsubaddps|vfmsubpd|vfmsubps|vfmsubsd|vfnmaddpd|vfnmaddps|vfnmaddsd|vfnmaddss|vfnmsubpd|vfnmusbps|vfnmusbsd|vfnmusbss|vbroadcastss|vbroadcastsd|vbroadcastf128|vmaskmovps|vmaskmovpd|cvt|xor|cli|sti|hlt|nop|lock|wait|enter|leave|ret|loop(n?e|n?z)?|call|j(mp|n?e|n?ge?|n?ae?|le?|be?|n?o|n?z|n?c|n?p|n?b))\b + scope: keyword.control.assembly + - match: '\b(?i)(RBP|EBP|BP|CS|DS|ES|FS|GS|SS|RAX|EAX|RBX|EBX|RCX|ECX|RDX|EDX|RIP|EIP|IP|RSP|ESP|SP|RSI|ESI|SI|RDI|EDI|DI|RFLAGS|EFLAGS|FLAGS|R(8|9|10|11|12|13|14|15)(d|w|b)?|(Y|X)MM([0-9]|10|11|12|13|14|15)|(A|B|C|D)(X|H|L)|CR[0-4]|DR[0-7]|TR6|TR7|EFER)\b' + scope: variable.parameter.register.assembly + - match: '\b[0-9]+\b' + scope: constant.character.decimal.assembly + - match: '\b(0x)(?i)[A-F0-9]+\b' + scope: constant.character.hexadecimal.assembly + - match: '\b(?i)[A-F0-9]+h\b' + scope: constant.character.hexadecimal.assembly + - match: \b(?i)(0|1)+b\b + scope: constant.character.binary.assembly + - match: ("|').*?("|') + scope: string.assembly + - match: '^\[' + push: + - meta_scope: support.function.directive.assembly + - match: '\]' + pop: true + - match: "(^struc) ([_a-zA-Z][_a-zA-Z0-9]*)" + scope: support.function.directive.assembly + captures: + 2: entity.name.function.assembly + - match: ^endstruc + scope: support.function.directive.assembly + - match: "^%macro ([_a-zA-Z][_a-zA-Z0-9]*) ([0-9]+)" + scope: support.function.directive.assembly + captures: + 1: entity.name.function.assembly + 2: constant.character.assembly + - match: ^%endmacro + scope: support.function.directive.assembly + - match: ^%comment + push: + - meta_scope: comment.assembly + - match: ^%endcomment + pop: true + - match: '\s*(?i)(%define|%ifndef|%xdefine|%idefine|%undef|%assign|%defstr|%strcat|%strlen|%substr|%00|%0|%rotate|%rep|%endrep|%include|\$\$|\$|%unmacro|%if|%elif|%else|%endif|%(el)?ifdef|%(el)?ifmacro|%(el)?ifctx|%(el)?ifidn|%(el)?ifidni|%(el)?ifid|%(el)?ifnum|%(el)?ifstr|%(el)?iftoken|%(el)?ifempty|%(el)?ifenv|%pathsearch|%depend|%use|%push|%pop|%repl|%arg|%stacksize|%local|%error|%warning|%fatal|%line|%!|%comment|%endcomment|__NASM_VERSION_ID__|__NASM_VER__|__FILE__|__LINE__|__BITS__|__OUTPUT_FORMAT__|__DATE__|__TIME__|__DATE_NUM__|_TIME__NUM__|__UTC_DATE__|__UTC_TIME__|__UTC_DATE_NUM__|__UTC_TIME_NUM__|__POSIX_TIME__|__PASS__|ISTRUC|AT|IEND|BITS 16|BITS 32|BITS 64|USE16|USE32|__SECT__|ABSOLUTE|EXTERN|GLOBAL|COMMON|CPU|FLOAT)\b ?([_a-zA-Z][_a-zA-Z0-9]*)?' + captures: + 1: support.function.directive.assembly + 13: entity.name.function.assembly + - match: \b(?i)(d(b|w|d|q|t|o|y)|res(b|w|d|q|t|o)|equ|times|align|alignb|sectalign|section|ptr|byte|word|dword|qword|incbin|)\b + scope: support.function.directive.assembly + - match: (\s)*;.*$ + scope: comment.assembly + - match: '(,|\[|\]|\+|\-|\*)' + scope: source.assembly + - match: '^\s*%%(.-[;])+?:$' + scope: entity.name.function.assembly + - match: '^\s*%\$(.-[;])+?:$' + scope: entity.name.function.assembly + - match: '^\.?(.-[;])+?:$' + scope: entity.name.function.assembly + - match: '^\.?(.-[;])+?\b' + scope: entity.name.function.assembly + - match: .+? + scope: entity.name.function.assembly diff --git a/syntaxes/C++/C Single File.sublime-build b/syntaxes/C++/C Single File.sublime-build @@ -0,0 +1,14 @@ +{ + "shell_cmd": "gcc \"${file}\" -o \"${file_path}/${file_base_name}\"", + "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$", + "working_dir": "${file_path}", + "selector": "source.c", + + "variants": + [ + { + "name": "Run", + "shell_cmd": "gcc \"${file}\" -o \"${file_path}/${file_base_name}\" && \"${file_path}/${file_base_name}\"" + } + ] +} diff --git a/syntaxes/C++/C Standard Includes.sublime-completions b/syntaxes/C++/C Standard Includes.sublime-completions @@ -0,0 +1,38 @@ +{ + "scope": "(source.c | source.objc) & (meta.preprocessor.include string.quoted.other)", + + // Taken from http://en.cppreference.com/w/c/header + // Update as needed. + "completions": + [ + { "trigger": "assert.h\tstandard header", "contents": "assert.h" }, // Conditionally compiled macro that compares its argument to zero + { "trigger": "complex.h\tstandard header (since c99)", "contents": "complex.h" }, // (since C99) Complex number arithmetic + { "trigger": "ctype.h\tstandard header", "contents": "ctype.h" }, // Functions to determine the type contained in character data + { "trigger": "errno.h\tstandard header", "contents": "errno.h" }, // Macros reporting error conditions + { "trigger": "fenv.h\tstandard header (since c99)", "contents": "fenv.h" }, // (since C99) Floating-point environment + { "trigger": "float.h\tstandard header", "contents": "float.h" }, // Limits of float types + { "trigger": "inttypes.h\tstandard header (since c99)", "contents": "inttypes.h" }, // (since C99) Format conversion of integer types + { "trigger": "iso646.h\tstandard header (since c95)", "contents": "iso646.h" }, // (since C95) Alternative operator spellings + { "trigger": "limits.h\tstandard header", "contents": "limits.h" }, // Sizes of basic types + { "trigger": "locale.h\tstandard header", "contents": "locale.h" }, // Localization utilities + { "trigger": "math.h\tstandard header", "contents": "math.h" }, // Common mathematics functions + { "trigger": "setjmp.h\tstandard header", "contents": "setjmp.h" }, // Nonlocal jumps + { "trigger": "signal.h\tstandard header", "contents": "signal.h" }, // Signal handling + { "trigger": "stdalign.h\tstandard header (since c11)", "contents": "stdalign.h" }, // (since C11) alignas and alignof convenience macros + { "trigger": "stdarg.h\tstandard header", "contents": "stdarg.h" }, // Variable arguments + { "trigger": "stdatomic.h\tstandard header (since c11)", "contents": "stdatomic.h" }, // (since C11 Atomic types + { "trigger": "stdbool.h\tstandard header (since c99)", "contents": "stdbool.h" }, // (since C99) Boolean type + { "trigger": "stddef.h\tstandard header", "contents": "stddef.h" }, // Common macro definitions + { "trigger": "stdint.h\tstandard header (since c99)", "contents": "stdint.h" }, // (since C99) Fixed-width integer types + { "trigger": "stdio.h\tstandard header", "contents": "stdio.h" }, // Input/output + { "trigger": "stdlib.h\tstandard header", "contents": "stdlib.h" }, // General utilities: memory management, program utilities, string conversions, random numbers + { "trigger": "stdnoreturn.h\tstandard header (since c11)", "contents": "stdnoreturn.h" }, // (since C11) noreturn convenience macros + { "trigger": "string.h\tstandard header", "contents": "string.h" }, // String handling + { "trigger": "tgmath.h\tstandard header (since c99)", "contents": "tgmath.h" }, // (since C99) Type-generic math (macros wrapping math.h and complex.h) + { "trigger": "threads.h\tstandard header (since c11)", "contents": "threads.h" }, // (since C11) Thread library + { "trigger": "time.h\tstandard header", "contents": "time.h" }, // Time/date utilities + { "trigger": "uchar.h\tstandard header (since c11)", "contents": "uchar.h" }, // (since C11) UTF-16 and UTF-32 character utilities + { "trigger": "wchar.h\tstandard header (since c95)", "contents": "wchar.h" }, // (since C95) Extended multibyte and wide character utilities + { "trigger": "wctype.h\tstandard header (since c95)", "contents": "wctype.h" }, // (since C95) Wide character classification and mapping utilities + ] +} diff --git a/syntaxes/C++/C++ Single File.sublime-build b/syntaxes/C++/C++ Single File.sublime-build @@ -0,0 +1,14 @@ +{ + "shell_cmd": "g++ \"${file}\" -o \"${file_path}/${file_base_name}\"", + "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$", + "working_dir": "${file_path}", + "selector": "source.c++", + + "variants": + [ + { + "name": "Run", + "shell_cmd": "g++ \"${file}\" -o \"${file_path}/${file_base_name}\" && \"${file_path}/${file_base_name}\"" + } + ] +} diff --git a/syntaxes/C++/C++ Standard Includes.sublime-completions b/syntaxes/C++/C++ Standard Includes.sublime-completions @@ -0,0 +1,218 @@ +{ + "scope": "(source.c++ | source.objc++) & (meta.preprocessor.include string.quoted.other)", + + // Taken from http://en.cppreference.com/w/cpp/header + // Update as needed. + "completions": + [ + // Utilities library + { "trigger": "cstdlib\tstandard header", "contents": "cstdlib" }, // General purpose utilities: program control, dynamic memory allocation, random numbers, sort and search + { "trigger": "csignal\tstandard header", "contents": "csignal" }, // Functions and macro constants for signal management + { "trigger": "csetjmp\tstandard header", "contents": "csetjmp" }, // Macro (and function) that saves (and jumps) to an execution context + { "trigger": "cstdarg\tstandard header", "contents": "cstdarg" }, // Handling of variable length argument lists + { "trigger": "typeinfo\tstandard header", "contents": "typeinfo" }, // Runtime type information utilities + { "trigger": "typeindex\tstandard header (since c++11)", "contents": "typeindex" }, // (since C++11) std::type_index + { "trigger": "type_traits\tstandard header (since c++11)", "contents": "type_traits" }, // (since C++11) Compile-time type information + { "trigger": "bitset\tstandard header", "contents": "bitset" }, // std::bitset class template + { "trigger": "functional\tstandard header", "contents": "functional" }, // Function objects, designed for use with the standard algorithms + { "trigger": "utility\tstandard header", "contents": "utility" }, // Various utility components + { "trigger": "ctime\tstandard header", "contents": "ctime" }, // C-style time/date utilites + { "trigger": "chrono\tstandard header (since c++11)", "contents": "chrono" }, // (since C++11) C++ time utilities + { "trigger": "cstddef\tstandard header", "contents": "cstddef" }, // typedefs for types such as size_t, NULL and others + { "trigger": "initializer_list\tstandard header since (c++11)", "contents": "initializer_list" }, // (since C++11) std::initializer_list class template + { "trigger": "tuple\tstandard header (since c++11)", "contents": "tuple" }, // (since C++11) std::tuple class template + { "trigger": "any\tstandard header (since c++17)", "contents": "any" }, // (since C++17) std::any class template + { "trigger": "optional\tstandard header (since c++17)", "contents": "optional" }, // (since C++17) std::optional class template + { "trigger": "variant\tstandard header (since c++17)", "contents": "variant" }, // (since C++17) std::variant class template + + // Dynmamic memory management utilities + { "trigger": "new\tstandard header", "contents": "new" }, // Low-level memory management utilities + { "trigger": "memory\tstandard header", "contents": "memory" }, // Higher level memory management utilities + { "trigger": "scoped_allocator\tstandard header (since c++11)", "contents": "scoped_allocator" }, // (since C++11) Nested allocator class + { "trigger": "memory_resource\tstandard header (since c++17)", "contents": "memory_resource" }, // (since C++17) Polymorphic allocators and memory resources + + // Numeric limits + { "trigger": "climits\tstandard header", "contents": "climits" }, // limits of integral types + { "trigger": "cfloat\tstandard header", "contents": "cfloat" }, // limits of float types + { "trigger": "cstdint\tstandard header (since c++11)", "contents": "cstdint" }, // (since C++11) fixed-size types and limits of other types + { "trigger": "cinttypes\tstandard header (since c++11)", "contents": "cinttypes" }, // (since C++11) formatting macros , intmax_t and uintmax_t math and conversions + { "trigger": "limits\tstandard header", "contents": "limits" }, // standardized way to query properties of arithmetic types + + // Error handling + { "trigger": "exception\tstandard header", "contents": "exception" }, // Exception handling utilities + { "trigger": "stdexcept\tstandard header", "contents": "stdexcept" }, // Standard exception objects + { "trigger": "system_error\tstandard header (since c++11)", "contents": "system_error" }, // (since C++11) defines std::error_code, a platform-dependent error code + { "trigger": "cerrno\tstandard header", "contents": "cerrno" }, // Macro containing the last error number + + // String library + { "trigger": "cctype\tstandard header", "contents": "cctype" }, // functions to determine the type contained in character data + { "trigger": "cwctype\tstandard header", "contents": "cwctype" }, // functions for determining the type of wide character data + { "trigger": "cstring\tstandard header", "contents": "cstring" }, // various narrow character string handling functions + { "trigger": "cwchar\tstandard header", "contents": "cwchar" }, // various wide and multibyte string handling functions + { "trigger": "cuchar\tstandard header (since c++11)", "contents": "cuchar" }, // (since C++11) C-style Unicode character conversion functions + { "trigger": "string\tstandard header", "contents": "string" }, // std::basic_string class template + { "trigger": "string_view\tstandard header (since c++17)", "contents": "string_view" }, // (since C++17) std::basic_string_view class template + { "trigger": "charconv\tstandard header (since c++20)", "contents": "charconv" }, // (since C++20) std::to_chars and std::from_chars + + // Containers library + { "trigger": "array\tstandard header (since c++11)", "contents": "array" }, // (since C++11) std::array container + { "trigger": "vector\tstandard header", "contents": "vector" }, // std::vector container + { "trigger": "deque\tstandard header", "contents": "deque" }, // std::deque container + { "trigger": "list\tstandard header", "contents": "list" }, // std::list container + { "trigger": "forward_list\tstandard header (since c++11)", "contents": "forward_list" }, // (since C++11) std::forward_list container + { "trigger": "set\tstandard header", "contents": "set" }, // std::set and std::multiset associative containers + { "trigger": "map\tstandard header", "contents": "map" }, // std::map and std::multimap associative containers + { "trigger": "unordered_set\tstandard header (since c++11)", "contents": "unordered_set" }, // (since C++11) std::unordered_set and std::unordered_multiset unordered associative containers + { "trigger": "unordered_map\tstandard header (since c++11)", "contents": "unordered_map" }, // (since C++11) std::unordered_map and std::unordered_multimap unordered associative containers + { "trigger": "stack\tstandard header", "contents": "stack" }, // std::stack container adaptor + { "trigger": "queue\tstandard header", "contents": "queue" }, // std::queue and std::priority_queue container adaptors + + // Algorithms library + { "trigger": "algorithm\tstandard header", "contents": "algorithm" }, // Algorithms that operate on containers + { "trigger": "execution\tstandard header (since c++17)", "contents": "execution" }, // (C++17) Predefined execution policies for parallel versions of the algorithms + + // Iterators library + { "trigger": "iterator\tstandard header", "contents": "iterator" }, // Container iterators + + // Numerics library + { "trigger": "cmath\tstandard header", "contents": "cmath"}, // Common mathematics functions + { "trigger": "complex\tstandard header", "contents": "complex" }, // Complex number type + { "trigger": "valarray\tstandard header", "contents": "valarray" }, // Class for representing and manipulating arrays of values + { "trigger": "random\tstandard header (since c++11)", "contents": "random" }, // (since C++11) Random number generators and distributions + { "trigger": "numeric\tstandard header", "contents": "numeric" }, // Numeric operations on values in containers + { "trigger": "ratio\tstandard header (since c++11)", "contents": "ratio" }, // (since C++11) Compile-time rational arithmetic + { "trigger": "cfenv\tstandard header (since c++11)", "contents": "cfenv" }, // (since C++11) Floating-point environment access functions + + // Input/output library + { "trigger": "iosfwd\tstandard header", "contents": "iosfwd" }, // forward declarations of all classes in the input/output library + { "trigger": "ios\tstandard header", "contents": "ios" }, // std::ios_base class, std::basic_ios class template and several typedefs + { "trigger": "istream\tstandard header", "contents": "istream" }, // std::basic_istream class template and several typedefs + { "trigger": "ostream\tstandard header", "contents": "ostream" }, // std::basic_ostream, std::basic_iostream class templates and several typedefs + { "trigger": "iostream\tstandard header", "contents": "iostream" }, // several standard stream objects + { "trigger": "fstream\tstandard header", "contents": "fstream" }, // std::basic_fstream, std::basic_ifstream, std::basic_ofstream class templates and several typedefs + { "trigger": "sstream\tstandard header", "contents": "sstream" }, // std::basic_stringstream, std::basic_istringstream, std::basic_ostringstream class templates and several typedefs + { "trigger": "iomanip\tstandard header", "contents": "iomanip" }, // Helper functions to control the format or input and output + { "trigger": "streambuf\tstandard header", "contents": "streambuf" }, // std::basic_streambuf class template + { "trigger": "cstdio\tstandard header", "contents": "cstdio" }, // C-style input-output functions + + // Localization library + { "trigger": "locale\tstandard header", "contents": "locale" }, // Localization utilities + { "trigger": "clocale\tstandard header", "contents": "clocale" }, // C localization utilities + { "trigger": "codecvt\tstandard header (since c++11)", "contents": "codecvt" }, // (since C++11) Unicode conversion facilities + + // Regular Expressions library + { "trigger": "regex\tstandard header (since c++11)", "contents": "regex" }, // (since C++11) Classes, algorithms and iterators to support regular expression processing + + // Atomic Operations library + { "trigger": "atomic\tstandard header (since c++11)", "contents": "atomic" }, // (since C++11) Atomic operations library + + // Thread support library + { "trigger": "thread\tstandard header (since c++11)", "contents": "thread" }, // (since C++11) std::thread class and supporting functions + { "trigger": "mutex\tstandard header (since c++11)", "contents": "mutex" }, // (since C++11) mutual exclusion primitives + { "trigger": "shared_mutex\tstandard header (since c++14)", "contents": "shared_mutex" }, // (since C++14) shared mutual exclusion primitives + { "trigger": "future\tstandard header (since c++11)", "contents": "future" }, // (since C++11) primitives for asynchronous computations + { "trigger": "condition_variable\tstandard header (since c++11)", "contents": "condition_variable" }, // (since C++11) thread waiting conditions + + // Filesystem library + { "trigger": "filesystem\tstandard header (since c++17)", "contents": "filesystem" }, // (since C++17) std::path class and supporting functions + + // Experimental libraries + { "trigger": "experimental/algorithm\tlibrary fundamentals TS", "contents": "experimental/algorithm" }, // Standard libraries extensions and Extensions for Parallelism + { "trigger": "experimental/any\tlibrary fundamentals TS", "contents": "experimental/any" }, // Standard libraries extensions + { "trigger": "experimental/chrono\tlibrary fundamentals TS", "contents": "experimental/chrono" }, // Standard libraries extensions + { "trigger": "experimental/deque\tlibrary fundamentals TS", "contents": "experimental/deque" }, // Standard libraries extensions + { "trigger": "experimental/execution_policy\tlibrary fundamentals TS", "contents": "experimental/execution_policy" }, // Extensions for Parallelism + { "trigger": "experimental/exception_list\tlibrary fundamentals TS", "contents": "experimental/exception_list" }, // Extensions for Parallelism + { "trigger": "experimental/filesystem\tlibrary fundamentals TS", "contents": "experimental/filesystem" }, // Filesystem library + { "trigger": "experimental/forward_list\tlibrary fundamentals TS", "contents": "experimental/forward_list" }, // Standard libraries extensions + { "trigger": "experimental/future\tlibrary fundamentals TS", "contents": "experimental/future" }, // Standard libraries extensions + { "trigger": "experimental/list\tlibrary fundamentals TS", "contents": "experimental/list" }, // Standard libraries extensions + { "trigger": "experimental/functional\tlibrary fundamentals TS", "contents": "experimental/functional" }, // Standard libraries extensions + { "trigger": "experimental/map\tlibrary fundamentals TS", "contents": "experimental/map" }, // Standard libraries extensions + { "trigger": "experimental/memory\tlibrary fundamentals TS", "contents": "experimental/memory" }, // Standard libraries extensions + { "trigger": "experimental/memory_resource\tlibrary fundamentals TS", "contents": "experimental/memory_resource" }, // Standard libraries extensions + { "trigger": "experimental/numeric\tlibrary fundamentals TS", "contents": "experimental/numeric" }, // Extensions for Parallelism + { "trigger": "experimental/optional\tlibrary fundamentals TS", "contents": "experimental/optional" }, // Standard libraries extensions + { "trigger": "experimental/ratio\tlibrary fundamentals TS", "contents": "experimental/ratio" }, // Standard libraries extensions + { "trigger": "experimental/regex\tlibrary fundamentals TS", "contents": "experimental/regex" }, // Standard libraries extensions + { "trigger": "experimental/set\tlibrary fundamentals TS", "contents": "experimental/set" }, // Standard libraries extensions + { "trigger": "experimental/string\tlibrary fundamentals TS", "contents": "experimental/string" }, // Standard libraries extensions + { "trigger": "experimental/string_view\tlibrary fundamentals TS", "contents": "experimental/string_view" }, // Standard libraries extensions + { "trigger": "experimental/system_error\tlibrary fundamentals TS", "contents": "experimental/system_error" }, // Standard libraries extensions + { "trigger": "experimental/tuple\tlibrary fundamentals TS", "contents": "experimental/tuple" }, // Standard libraries extensions + { "trigger": "experimental/type_traits\tlibrary fundamentals TS", "contents": "experimental/type_traits" }, // Standard libraries extensions + { "trigger": "experimental/unordered_map\tlibrary fundamentals TS", "contents": "experimental/unordered_map" }, // Standard libraries extensions + { "trigger": "experimental/unordered_set\tlibrary fundamentals TS", "contents": "experimental/unordered_set" }, // Standard libraries extensions + { "trigger": "experimental/utility\tlibrary fundamentals TS", "contents": "experimental/utility" }, // Standard libraries extensions + { "trigger": "experimental/vector\tlibrary fundamentals TS", "contents": "experimental/vector" }, // Standard libraries extensions + + // C compatibility headers + // + // For some of the C standard library headers of + // the form xxx.h, the C++ standard library both includes an + // identically-named header and another header of the form cxxx (all + // meaningful cxxx headers are listed above). With the exception of + // complex.h , each xxx.h header included in the C++ standard library + // places in the global namespace each name that the corresponding cxxx + // header would have placed in the std namespace. These headers are + // allowed to also declare the same names in the std namespace, and the + // corresponding cxxx headers are allowed to also declare the same names + // in the global namespace: including <cstdlib> definitely provides + // std::malloc and may also provide ::malloc. Including <stdlib.h> + // definitely provides ::malloc and may also provide std::malloc. This + // applies even to functions and function overloads that are not part of + // C standard library. + { "trigger": "assert.h\tstandard header (deprecated)", "contents": "assert.h" }, // behaves as if each name from <cassert> is placed in global namespace + { "trigger": "ctype.h\tstandard header (deprecated)", "contents": "ctype.h" }, // behaves as if each name from <cctype> is placed in global namespace + { "trigger": "errno.h\tstandard header (deprecated)", "contents": "errno.h" }, // behaves as if each name from <cerrno> is placed in global namespace + { "trigger": "fenv.h\tstandard header (deprecated)", "contents": "fenv.h" }, // behaves as if each name from <cfenv> is placed in global namespace + { "trigger": "float.h\tstandard header (deprecated)", "contents": "float.h" }, // behaves as if each name from <cfloat> is placed in global namespace + { "trigger": "inttypes.h\tstandard header (deprecated)", "contents": "inttypes.h" }, // behaves as if each name from <cinttypes> is placed in global namespace + { "trigger": "limits.h\tstandard header (deprecated)", "contents": "limits.h" }, // behaves as if each name from <climits> is placed in global namespace + { "trigger": "locale.h\tstandard header (deprecated)", "contents": "locale.h" }, // behaves as if each name from <clocale> is placed in global namespace + { "trigger": "math.h\tstandard header (deprecated)", "contents": "math.h" }, // behaves as if each name from <cmath> is placed in global namespace + { "trigger": "setjmp.h\tstandard header (deprecated)", "contents": "setjmp.h" }, // behaves as if each name from <csetjmp> is placed in global namespace + { "trigger": "signal.h\tstandard header (deprecated)", "contents": "signal.h" }, // behaves as if each name from <csignal> is placed in global namespace + { "trigger": "stdarg.h\tstandard header (deprecated)", "contents": "stdarg.h" }, // behaves as if each name from <cstdarg> is placed in global namespace + { "trigger": "stddef.h\tstandard header (deprecated)", "contents": "stddef.h" }, // behaves as if each name from <cstddef> is placed in global namespace + { "trigger": "stdint.h\tstandard header (deprecated)", "contents": "stdint.h" }, // behaves as if each name from <cstdint> is placed in global namespace + { "trigger": "stdio.h\tstandard header (deprecated)", "contents": "stdio.h" }, // behaves as if each name from <cstdio> is placed in global namespace + { "trigger": "stdlib.h\tstandard header (deprecated)", "contents": "stdlib.h" }, // behaves as if each name from <cstdlib> is placed in global namespace + { "trigger": "string.h\tstandard header (deprecated)", "contents": "string.h" }, // behaves as if each name from <cstring> is placed in global namespace + { "trigger": "time.h\tstandard header (deprecated)", "contents": "time.h" }, // behaves as if each name from <ctime> is placed in global namespace + { "trigger": "uchar.h\tstandard header (deprecated)", "contents": "uchar.h" }, // behaves as if each name from <cuchar> is placed in global namespace + { "trigger": "wchar.h\tstandard header (deprecated)", "contents": "wchar.h" }, // behaves as if each name from <cwchar> is placed in global namespace + { "trigger": "wctype.h\tstandard header (deprecated)", "contents": "wctype.h" }, // behaves as if each name from <cwctype> is placed in global namespace + + // Unsupported C headers + // + // The C headers <stdatomic.h>, <stdnoreturn.h>, + // and <threads.h> are not included in C++ and have no cxxx equivalents. + + // Empty C headers + // + // The headers <complex.h>, <ccomplex>, <tgmath.h>, and <ctgmath> do not + // contain any content from the C standard library and instead merely + // include other headers from the C++ standard library. The use of all + // these headers is deprecated in C++. + // + // <ccomplex> (since C++11)(deprecated in C++17) simply includes the header <complex> + // <complex.h> (deprecated) simply includes the header <complex> + // <ctgmath> (since C++11)(deprecated in C++17) simply includes the headers <complex> and <cmath>: the overloads equivalent to the contents of the C header tgmath.h are already provided by those headers + // <tgmath.h> (deprecated) simply includes the header <ctgmath> + + // Meaningless C headers + // + // The headers <ciso646>, <cstdalign>, and <cstdbool> are meaningless in + // C++ because the macros they provide in C are language keywords in + // C++. + // + // <ciso646> empty header. The macros that appear in iso646.h in C are keywords in C++ + // <iso646.h> (deprecated) behaves as if each name from <ciso646> is placed in global namespace + // <cstdalign> (since C++11)(deprecated in C++17) defines one compatibility macro constant + // <stdalign.h> (deprecated) behaves as if each name from <cstdalign> is placed in global namespace + // <cstdbool> (since C++11)(deprecated in C++17) defines one compatibility macro constant + // <stdbool.h> (deprecated) behaves as if each name from <cstdbool> is placed in global namespace + + ] +} diff --git a/syntaxes/C++/C++.sublime-settings b/syntaxes/C++/C++.sublime-settings @@ -0,0 +1,3 @@ +{ + "extensions": ["h"] +} diff --git a/syntaxes/C++/C++.sublime-syntax b/syntaxes/C++/C++.sublime-syntax @@ -0,0 +1,2166 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: C++ +comment: I don't think anyone uses .hp. .cp tends to be paired with .h. (I could be wrong. :) -- chris +file_extensions: + - cpp + - cc + - cp + - cxx + - c++ + - C + - h + - hh + - hpp + - hxx + - h++ + - inl + - ipp +first_line_match: '-\*- C\+\+ -\*-' +scope: source.c++ +variables: + # number digits + dec_digits: '(?:\d(?:[\d'']*\d)?)' + + # number exponents + dec_exponent: '(?:[eE][-+]??{{dec_digits}})' + hex_exponent: '(?:[pP][-+]??{{dec_digits}})' + + # number suffixes + # note: nearly everything can be defined as suffix via `operator` keyword + # see: https://en.cppreference.com/w/cpp/numeric/complex/operator%22%22i + dec_suffix: '(?:[a-zA-Z_][[:alnum:]_]*|(?=[^[:alnum:]_'']))' + hex_suffix: '(?:[g-zG-Z_][[:alnum:]_]*|(?=[^[:alnum:]_'']))' + float_suffix: '[fF]' + integer_suffix: '[lL]{1,2}[uU]?|[uU][lL]{0,2}' + + identifier: \b[[:alpha:]_][[:alnum:]_]*\b # upper and lowercase + macro_identifier: \b[[:upper:]_][[:upper:][:digit:]_]{2,}\b # only uppercase, at least 3 chars + path_lookahead: '(?:::\s*)?(?:{{identifier}}\s*::\s*)*(?:template\s+)?{{identifier}}' + operator_method_name: '\boperator\s*(?:[-+*/%^&|~!=<>]|[-+*/%^&|=!<>]=|<<=?|>>=?|&&|\|\||\+\+|--|,|->\*?|\(\)|\[\]|""\s*{{identifier}})' + casts: 'const_cast|dynamic_cast|reinterpret_cast|static_cast' + operator_keywords: 'and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|xor|xor_eq|noexcept' + control_keywords: 'break|case|catch|continue|default|do|else|for|goto|if|_Pragma|return|switch|throw|try|while' + memory_operators: 'new|delete' + basic_types: 'asm|__asm__|auto|bool|_Bool|char|_Complex|double|float|_Imaginary|int|long|short|signed|unsigned|void' + before_tag: 'struct|union|enum\s+class|enum\s+struct|enum|class' + declspec: '__declspec\(\s*\w+(?:\([^)]+\))?\s*\)' + storage_classes: 'static|export|extern|friend|explicit|virtual|register|thread_local' + type_qualifier: 'const|constexpr|mutable|typename|volatile' + compiler_directive: 'inline|restrict|__restrict__|__restrict' + visibility_modifiers: 'private|protected|public' + other_keywords: 'typedef|nullptr|{{visibility_modifiers}}|static_assert|sizeof|using|typeid|alignof|alignas|namespace|template' + modifiers: '{{storage_classes}}|{{type_qualifier}}|{{compiler_directive}}' + non_angle_brackets: '(?=<<|<=)' + + regular: '[^(){}&;*^%=<>-]*' + regular_plus: '[^(){}&;*^%=<>-]+' + paren_open: (?:\( + paren_close: '\))?' + generic_open: (?:{{regular_plus}}(?:< + generic_close: '>)?)?' + balance_parentheses: '{{regular}}{{paren_open}}{{regular}}{{paren_close}}{{regular}}' + generic_lookahead: <{{generic_open}}{{generic_open}}{{regular}}{{generic_close}}\s*{{generic_close}}{{balance_parentheses}}> + + data_structures_forward_decl_lookahead: '(\s+{{macro_identifier}})*\s*(:\s*({{path_lookahead}}|{{visibility_modifiers}}|,|\s|<[^;]*>)+)?;' + non_func_keywords: 'if|for|switch|while|decltype|sizeof|__declspec|__attribute__|typeid|alignof|alignas|static_assert' + +contexts: + main: + - include: preprocessor-global + - include: global + + ############################################################################# + # Reusable contexts + # + # The follow contexts are currently constructed to be reused in the + # Objetive-C++ syntax. They are specifically constructed to not push into + # sub-contexts, which ensures that Objective-C++ code isn't accidentally + # lexed as plain C++. + # + # The "unique-*" contexts are additions that C++ makes over C, and thus can + # be directly reused in Objective-C++ along with contexts from Objective-C + # and C. + ############################################################################# + + unique-late-expressions: + # This is highlighted after all of the other control keywords + # to allow operator overloading to be lexed properly + - match: \boperator\b + scope: keyword.control.c++ + + unique-modifiers: + - match: \b({{modifiers}})\b + scope: storage.modifier.c++ + + unique-variables: + - match: \bthis\b + scope: variable.language.c++ + # common C++ instance var naming idiom -- fMemberName + - match: '\b(f|m)[[:upper:]]\w*\b' + scope: variable.other.readwrite.member.c++ + # common C++ instance var naming idiom -- m_member_name + - match: '\bm_[[:alnum:]_]+\b' + scope: variable.other.readwrite.member.c++ + + unique-constants: + - match: \bnullptr\b + scope: constant.language.c++ + + unique-keywords: + - match: \busing\b + scope: keyword.control.c++ + - match: \bbreak\b + scope: keyword.control.flow.break.c++ + - match: \bcontinue\b + scope: keyword.control.flow.continue.c++ + - match: \bgoto\b + scope: keyword.control.flow.goto.c++ + - match: \breturn\b + scope: keyword.control.flow.return.c++ + - match: \bthrow\b + scope: keyword.control.flow.throw.c++ + - match: \b({{control_keywords}})\b + scope: keyword.control.c++ + - match: '\bdelete\b(\s*\[\])?|\bnew\b(?!])' + scope: keyword.control.c++ + - match: \b({{operator_keywords}})\b + scope: keyword.operator.word.c++ + + unique-types: + - match: \b(char16_t|char32_t|wchar_t|nullptr_t)\b + scope: storage.type.c++ + - match: \bclass\b + scope: storage.type.c++ + + unique-strings: + - match: '((?:L|u8|u|U)?R)("([^\(\)\\ ]{0,16})\()' + captures: + 1: storage.type.string.c++ + 2: punctuation.definition.string.begin.c++ + push: + - meta_scope: string.quoted.double.c++ + - match: '\)\3"' + scope: punctuation.definition.string.end.c++ + pop: true + + numbers: + # https://en.cppreference.com/w/cpp/language/floating_literal + + # decimal floats + - match: |- + (?x: + \b{{dec_digits}} + (?: + (?: + (\.) + (?: + # 1.1, 1.1e1, 1.1e-1, 1.1f, 1.1e1f, 1.1e-1f, 1.1L, 1.1e1L, 1.1e-1L + {{dec_digits}} {{dec_exponent}}? + # 1.e1, 1.e-1, 1.e1f, 1.e-1f, 1.e1L, 1.e-1L + | {{dec_exponent}} + # 1., 1.f, 1.L # but not `..` + | (?!\.) + ) + # 1e1 1e1f 1e1L + | {{dec_exponent}} + ) ({{dec_suffix}})? + # 1f + | ({{float_suffix}}) + ) + # .1, .1e1, .1e-1, .1f, .1e1f, .1e-1f, .1L, .1e1L, .1e-1L + | (\.) {{dec_digits}} {{dec_exponent}}? ({{dec_suffix}})? + ) + scope: constant.numeric.float.decimal.c++ + captures: + 1: punctuation.separator.decimal.c++ + 2: storage.type.numeric.c++ + 3: storage.type.numeric.c++ + 4: punctuation.separator.decimal.c++ + 5: storage.type.numeric.c++ + + # hexadecimal float (C99) + - match: \b0[xX](?=[[:alnum:]_''.]+?[pP]) + scope: punctuation.definition.numeric.base.c++ + push: + - meta_include_prototype: false + - meta_scope: constant.numeric.float.hexadecimal.c++ + - match: '{{hex_exponent}}' + pop: true + - match: \. + scope: punctuation.separator.decimal.c++ + - match: \H + scope: invalid.illegal.numeric.digit.c++ + + # https://en.cppreference.com/w/c/language/integer_constant + + # binary integer + - match: \b0[bB] + scope: punctuation.definition.numeric.base.c++ + push: + - meta_include_prototype: false + - meta_scope: constant.numeric.integer.binary.c++ + - include: decimal-suffix + - match: '[2-9]' + scope: invalid.illegal.numeric.digit.c++ + # hexadecimal integer + - match: \b0[xX] + scope: punctuation.definition.numeric.base.c++ + push: + - meta_include_prototype: false + - meta_scope: constant.numeric.integer.hexadecimal.c++ + - include: hexadecimal-suffix + # octal integer + - match: \b0(?=[\d'']) + scope: punctuation.definition.numeric.base.c++ + push: + - meta_include_prototype: false + - meta_scope: constant.numeric.integer.octal.c++ + - include: decimal-suffix + - match: '[89]' + scope: invalid.illegal.numeric.digit.c++ + # decimal integer + - match: \b\d+ + push: + - meta_include_prototype: false + - meta_scope: constant.numeric.integer.decimal.c++ + - include: decimal-suffix + + decimal-suffix: + - match: '{{dec_suffix}}' + scope: storage.type.numeric.c++ + pop: true + + hexadecimal-suffix: + - match: '{{hex_suffix}}' + scope: storage.type.numeric.c++ + pop: true + + identifiers: + - match: '(?:(::)\s*)?{{identifier}}\s*(::)\s*' + captures: + 1: punctuation.accessor.double-colon.c++ + 2: punctuation.accessor.double-colon.c++ + - match: '(?:(::)\s*)?{{identifier}}' + captures: + 1: punctuation.accessor.double-colon.c++ + + identifier-path-generic: + - include: angle-brackets + - match: '(?:(::)\s*)?{{identifier}}\s*(?=(<.*>)?\s*(::))\s*' + captures: + 1: punctuation.accessor.double-colon.c++ + 2: punctuation.accessor.double-colon.c++ + + function-specifiers: + - match: \b(const|final|noexcept|override)\b + scope: storage.modifier.c++ + + ############################################################################# + # The following are C++-specific contexts that should not be reused. This is + # because they push into subcontexts and use variables that are C++-specific. + ############################################################################# + + ## Common context layout + + global: + - match: '(?=\btemplate\b)' + push: + - include: template + - match: (?=\S) + set: global-modifier + - include: using-namespace + - include: namespace + - include: keywords-angle-brackets + - match: '(?={{path_lookahead}}\s*<)' + push: global-modifier + # Take care of comments just before a function definition. + - match: /\* + scope: punctuation.definition.comment.c + push: + - - match: \s*(?=\w) + set: global-modifier + - match: "" + pop: true + - - meta_scope: comment.block.c + - match: \*/ + scope: punctuation.definition.comment.c + pop: true + - match: ^\s*(\*)(?!/) + captures: + 1: punctuation.definition.comment.c + - include: early-expressions + - match: ^\s*\b(extern)(?=\s+"C(\+\+)?") + scope: storage.modifier.c++ + push: + - include: comments + - include: strings + - match: '\{' + scope: punctuation.section.block.begin.c++ + set: + - meta_scope: meta.extern-c.c++ + - match: '^\s*(#\s*ifdef)\s*__cplusplus\s*' + scope: meta.preprocessor.c++ + captures: + 1: keyword.control.import.c++ + set: + - match: '\}' + scope: punctuation.section.block.end.c++ + pop: true + - include: preprocessor-global + - include: global + - match: '\}' + scope: punctuation.section.block.end.c++ + pop: true + - include: preprocessor-global + - include: global + - match: (?=\S) + set: global-modifier + - match: ^\s*(?=\w) + push: global-modifier + - include: late-expressions + + statements: + - include: preprocessor-statements + - include: scope:source.c#label + - include: expressions + + expressions: + - include: early-expressions + - include: late-expressions + + early-expressions: + - include: early-expressions-before-generic-type + - include: generic-type + - include: early-expressions-after-generic-type + + early-expressions-before-generic-type: + - include: preprocessor-expressions + - include: comments + - include: case-default + - include: using-namespace + - include: typedef + - include: using-alias + - include: keywords-angle-brackets + - include: keywords-parens + - include: keywords + - include: numbers + # Prevent a '<' from getting scoped as the start of another template + # parameter list, if in reality a less-than-or-equals sign is meant. + - match: <= + scope: keyword.operator.comparison.c + + early-expressions-after-generic-type: + - include: members-arrow + - include: operators + - include: members-dot + - include: strings + - include: parens + - include: brackets + - include: block + - include: variables + - include: constants + - match: ',' + scope: punctuation.separator.c++ + - match: '\)|\}' + scope: invalid.illegal.stray-bracket-end.c++ + + expressions-minus-generic-type: + - include: early-expressions-before-generic-type + - include: angle-brackets + - include: early-expressions-after-generic-type + - include: late-expressions + + expressions-minus-generic-type-function-call: + - include: early-expressions-before-generic-type + - include: angle-brackets + - include: early-expressions-after-generic-type + - include: late-expressions-before-function-call + - include: identifiers + - match: ';' + scope: punctuation.terminator.c++ + + late-expressions: + - include: late-expressions-before-function-call + - include: function-call + - include: identifiers + - match: ';' + scope: punctuation.terminator.c++ + + late-expressions-before-function-call: + - include: unique-late-expressions + - include: modifiers-parens + - include: modifiers + - include: types + + expressions-minus-function-call: + - include: early-expressions + - include: late-expressions-before-function-call + - include: identifiers + - match: ';' + scope: punctuation.terminator.c++ + + comments: + - include: scope:source.c#comments + + operators: + - include: scope:source.c#operators + + modifiers: + - include: unique-modifiers + - include: scope:source.c#modifiers + + variables: + - include: unique-variables + - include: scope:source.c#variables + + constants: + - include: unique-constants + - include: scope:source.c#constants + + keywords: + - include: unique-keywords + - include: scope:source.c#keywords + + types: + - include: unique-types + - include: types-parens + - include: scope:source.c#types + + strings: + - include: unique-strings + - include: scope:source.c#strings + + ## C++-specific contexts + + case-default: + - match: '\b(default|case)\b' + scope: keyword.control.c++ + push: + - match: (?=[);,]) + pop: true + - match: ':' + scope: punctuation.separator.c++ + pop: true + - include: expressions + + modifiers-parens: + - match: '\b(alignas)\b\s*(\()' + captures: + 1: storage.modifier.c++ + 2: meta.group.c++ punctuation.section.group.begin.c++ + push: + - meta_content_scope: meta.group.c++ + - match: '\)' + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + - match: \b(__attribute__)\s*(\(\() + captures: + 1: storage.modifier.c++ + 2: meta.group.c++ punctuation.section.group.begin.c++ + push : + - meta_scope: meta.attribute.c++ + - meta_content_scope: meta.group.c++ + - include: parens + - include: strings + - match: \)\) + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - match: \b(__declspec)(\() + captures: + 1: storage.modifier.c++ + 2: meta.group.c++ punctuation.section.group.begin.c++ + push: + - meta_content_scope: meta.group.c++ + - match: '\)' + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - match: '\b(align|allocate|code_seg|deprecated|property|uuid)\b\s*(\()' + captures: + 1: storage.modifier.c++ + 2: meta.group.c++ punctuation.section.group.begin.c++ + push: + - meta_content_scope: meta.group.c++ + - match: '\)' + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: numbers + - include: strings + - match: \b(get|put)\b + scope: variable.parameter.c++ + - match: ',' + scope: punctuation.separator.c++ + - match: '=' + scope: keyword.operator.assignment.c++ + - match: '\b(appdomain|deprecated|dllimport|dllexport|jintrinsic|naked|noalias|noinline|noreturn|nothrow|novtable|process|restrict|safebuffers|selectany|thread)\b' + scope: constant.other.c++ + + types-parens: + - match: '\b(decltype)\b\s*(\()' + captures: + 1: storage.type.c++ + 2: meta.group.c++ punctuation.section.group.begin.c++ + push: + - meta_content_scope: meta.group.c++ + - match: '\)' + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + + keywords-angle-brackets: + - match: \b({{casts}})\b\s* + scope: keyword.operator.word.cast.c++ + push: + - match: '>' + scope: punctuation.section.generic.end.c++ + pop: true + - match: '<' + scope: punctuation.section.generic.begin.c++ + push: + - match: '(?=>)' + pop: true + - include: expressions-minus-generic-type-function-call + + keywords-parens: + - match: '\b(alignof|typeid|static_assert|sizeof)\b\s*(\()' + captures: + 1: keyword.operator.word.c++ + 2: meta.group.c++ punctuation.section.group.begin.c++ + push: + - meta_content_scope: meta.group.c++ + - match: '\)' + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + + using-namespace: + - match: '\b(using)\s+(namespace)\b' + captures: + 1: keyword.control.c++ + 2: keyword.control.c++ + push: + - include: identifiers + - match: '' + pop: true + + namespace: + - match: '\b(namespace)\s+(?=({{path_lookahead}})?(?!\s*[;,]))' + scope: meta.namespace.c++ + captures: + 1: keyword.control.c++ + push: + - meta_content_scope: meta.namespace.c++ entity.name.namespace.c++ + - include: identifiers + - match: '' + set: + - meta_scope: meta.namespace.c++ + - include: comments + - match: '=' + scope: keyword.operator.alias.c++ + - match: '(?=;)' + pop: true + - match: '\}' + scope: meta.block.c++ punctuation.section.block.end.c++ + pop: true + - match: '\{' + scope: punctuation.section.block.begin.c++ + push: + - meta_scope: meta.block.c++ + - match: '(?=\})' + pop: true + - include: preprocessor-global + - include: global + - include: expressions + + template-common: + # Exit the template scope if we hit some basic invalid characters. This + # helps when a user is in the middle of typing their template types and + # prevents re-highlighting the whole file until the next > is found. + - match: (?=[{};]) + pop: true + - include: expressions + + template: + - match: \btemplate\b + scope: storage.type.template.c++ + push: + - meta_scope: meta.template.c++ + # Explicitly include comments here at the top, in order to NOT match the + # \S lookahead in the case of comments. + - include: comments + - match: < + scope: punctuation.section.generic.begin.c++ + set: + - meta_content_scope: meta.template.c++ + - match: '>' + scope: meta.template.c++ punctuation.section.generic.end.c++ + pop: true + - match: \.{3} + scope: keyword.operator.variadic.c++ + - match: \b(typename|{{before_tag}})\b + scope: storage.type.c++ + - include: template # include template here for nested templates + - include: template-common + - match: (?=\S) + set: + - meta_content_scope: meta.template.c++ + - match: \b({{before_tag}})\b + scope: storage.type.c++ + - include: template-common + + generic-type: + - match: '(?=(?!template){{path_lookahead}}\s*{{generic_lookahead}}\s*(\(|\{))' + push: + - meta_scope: meta.function-call.c++ + - match: \btemplate\b + scope: storage.type.template.c++ + - match: (?:(::)\s*)?({{identifier}})\s*(<) + captures: + 1: punctuation.accessor.double-colon.c++ + 2: variable.function.c++ + 3: punctuation.section.generic.begin.c++ + push: + - match: '>' + scope: punctuation.section.generic.end.c++ + pop: true + - include: expressions-minus-generic-type-function-call + - match: (?:(::)\s*)?({{identifier}})\s*(\() + captures: + 1: punctuation.accessor.double-colon.c++ + 2: variable.function.c++ + 3: punctuation.section.group.begin.c++ + set: + - meta_scope: meta.function-call.c++ + - meta_content_scope: meta.group.c++ + - match: '\)' + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + - match: (?:(::)\s*)?({{identifier}})\s*(\{) + captures: + 1: punctuation.accessor.double-colon.c++ + 2: variable.function.c++ + 3: punctuation.section.group.begin.c++ + set: + - meta_scope: meta.function-call.c++ + - meta_content_scope: meta.group.c++ + - match: '\}' + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + - include: identifiers + - include: angle-brackets + - match: '\(' + scope: meta.group.c++ punctuation.section.group.begin.c++ + set: + - meta_scope: meta.function-call.c++ + - meta_content_scope: meta.group.c++ + - match: '\)' + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + - match: '\{' + scope: meta.group.c++ punctuation.section.group.begin.c++ + set: + - meta_scope: meta.function-call.c++ + - meta_content_scope: meta.group.c++ + - match: '\}' + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + - match: '(?=(?!template){{path_lookahead}}\s*{{generic_lookahead}})' + push: + - include: identifiers + - match: '<' + scope: punctuation.section.generic.begin.c++ + set: + - match: '>' + scope: punctuation.section.generic.end.c++ + pop: true + - include: expressions-minus-generic-type-function-call + + angle-brackets: + - match: '<(?!<)' + scope: punctuation.section.generic.begin.c++ + push: + - match: '>' + scope: punctuation.section.generic.end.c++ + pop: true + - include: expressions-minus-generic-type-function-call + + block: + - match: '\{' + scope: punctuation.section.block.begin.c++ + push: + - meta_scope: meta.block.c++ + - match: (?=^\s*#\s*(elif|else|endif)\b) + pop: true + - match: '\}' + scope: punctuation.section.block.end.c++ + pop: true + - include: statements + + function-call: + - match: (?={{path_lookahead}}\s*(\(|\{)) + push: + - meta_scope: meta.function-call.c++ + - include: scope:source.c#c99 + - match: '(?:(::)\s*)?{{identifier}}\s*(::)\s*' + captures: + 1: punctuation.accessor.double-colon.c++ + 2: punctuation.accessor.double-colon.c++ + - match: '(?:(::)\s*)?({{identifier}})' + captures: + 1: punctuation.accessor.c++ + 2: variable.function.c++ + - match: '\(' + scope: meta.group.c++ punctuation.section.group.begin.c++ + set: + - meta_content_scope: meta.function-call.c++ meta.group.c++ + - match: '\)' + scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + - match: '\{' + scope: meta.group.c++ punctuation.section.group.begin.c++ + set: + - meta_content_scope: meta.function-call.c++ meta.group.c++ + - match: '\}' + scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + + members-inside-function-call: + - meta_content_scope: meta.method-call.c++ meta.group.c++ + - match: \) + scope: meta.method-call.c++ meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + + members-after-accessor-junction: + # After we've seen an accessor (dot or arrow), this context decides what + # kind of entity we're accessing. + - include: comments + - match: \btemplate\b + scope: meta.method-call.c++ storage.type.template.c++ + # Guaranteed to be a template member function call after we match this + set: + - meta_content_scope: meta.method-call.c++ + - include: comments + - match: '{{identifier}}' + scope: variable.function.member.c++ + set: + - meta_content_scope: meta.method-call.c++ + - match: \( + scope: meta.group.c++ punctuation.section.group.begin.c++ + set: members-inside-function-call + - include: comments + - include: angle-brackets + - match: (?=\S) # safety pop + pop: true + - match: (?=\S) # safety pop + pop: true + # Operator overloading + - match: '({{operator_method_name}})\s*(\()' + captures: + 0: meta.method-call.c++ + 1: variable.function.member.c++ + 2: meta.group.c++ punctuation.section.group.begin.c++ + set: members-inside-function-call + # Non-templated member function call + - match: (~?{{identifier}})\s*(\() + captures: + 0: meta.method-call.c++ + 1: variable.function.member.c++ + 2: meta.group.c++ punctuation.section.group.begin.c++ + set: members-inside-function-call + # Templated member function call + - match: (~?{{identifier}})\s*(?={{generic_lookahead}}) + captures: + 1: variable.function.member.c++ + set: + - meta_scope: meta.method-call.c++ + - match: < + scope: punctuation.section.generic.begin.c++ + set: + - meta_content_scope: meta.method-call.c++ + - match: '>' + scope: punctuation.section.generic.end.c++ + set: + - meta_content_scope: meta.method-call.c++ + - include: comments + - match: \( + scope: punctuation.section.group.begin.c++ + set: members-inside-function-call + - match: (?=\S) # safety pop + pop: true + - include: expressions + # Explicit base-class access + - match: ({{identifier}})\s*(::) + captures: + 1: variable.other.base-class.c++ + 2: punctuation.accessor.double-colon.c++ + set: members-after-accessor-junction # reset + # Just a regular member variable + - match: '{{identifier}}' + scope: variable.other.readwrite.member.c++ + pop: true + + members-dot: + - include: scope:source.c#access-illegal + # No lookahead required because members-dot goes after operators in the + # early-expressions-after-generic-type context. This means triple dots + # (i.e. "..." or "variadic") is attempted first. + - match: \. + scope: punctuation.accessor.dot.c++ + push: members-after-accessor-junction + + members-arrow: + # This needs to be before operators in the + # early-expressions-after-generic-type context because otherwise the "->" + # from the C language will match. + - match: -> + scope: punctuation.accessor.arrow.c++ + push: members-after-accessor-junction + + using-alias: + # consume keyword if followed by typename + - match: '\b(using)\b(?=\s+typename\b)' + captures: + 1: keyword.control.c++ + - match: '\b(using)\b\s+({{identifier}})(?!\s*(<|::))' + captures: + 1: keyword.control.c++ + 2: entity.name.type.using.c++ + + typedef: + - match: \btypedef\b + scope: storage.type.c++ + push: + - match: ({{identifier}})?\s*(?=;) + captures: + 1: entity.name.type.typedef.c++ + pop: true + - match: \b(struct)\s+({{identifier}})\b + captures: + 1: storage.type.c++ + - include: expressions-minus-generic-type + + parens: + - match: \( + scope: punctuation.section.group.begin.c++ + push: + - meta_scope: meta.group.c++ + - match: \) + scope: punctuation.section.group.end.c++ + pop: true + - include: expressions + + brackets: + - match: \[ + scope: punctuation.section.brackets.begin.c++ + push: + - meta_scope: meta.brackets.c++ + - match: \] + scope: punctuation.section.brackets.end.c++ + pop: true + - include: expressions + + function-trailing-return-type: + - match: '{{non_angle_brackets}}' + pop: true + - include: angle-brackets + - include: types + - include: modifiers-parens + - include: modifiers + - include: identifiers + - match: \*|& + scope: keyword.operator.c++ + - include: function-trailing-return-type-parens + - match: '(?=\S)' + pop: true + + function-trailing-return-type-parens: + - match: \( + scope: punctuation.section.group.begin.c++ + push: + - meta_scope: meta.group.c++ + - match: \) + scope: punctuation.section.group.end.c++ + pop: true + - include: function-trailing-return-type + + ## Detection of function and data structure definitions at the global level + + global-modifier: + - include: comments + - include: modifiers-parens + - include: modifiers + # Constructors and destructors don't have a type + - match: '(?={{path_lookahead}}\s*(?:{{generic_lookahead}})?\s*::\s*{{identifier}}\s*\()' + set: + - meta_content_scope: meta.function.c++ meta.toc-list.full-identifier.c++ + - include: identifier-path-generic + - match: '(?:(::)\s*)?({{identifier}})' + captures: + 1: punctuation.accessor.double-colon.c++ + 2: entity.name.function.constructor.c++ + - match: '(?=[^\w\s])' + set: function-definition-params + - match: '(?={{path_lookahead}}\s*(?:{{generic_lookahead}})?\s*::\s*~{{identifier}}\s*(\(|$))' + set: + - meta_content_scope: meta.function.c++ meta.toc-list.full-identifier.c++ + - include: identifier-path-generic + - match: '(?:(::)\s*)?(~{{identifier}})' + captures: + 1: punctuation.accessor.double-colon.c++ + 2: entity.name.function.destructor.c++ + - match: '(?=[^\w\s])' + set: function-definition-params + # If we see a path ending in :: before a newline, we don't know if it is + # a constructor or destructor, or a long return type, so we are just going + # to treat it like a regular function. Most likely it is a constructor, + # since it doesn't seem most developers would create such a long typename. + - match: '(?={{path_lookahead}}\s*(?:{{generic_lookahead}})?::\s*$)' + set: + - meta_content_scope: meta.function.c++ meta.toc-list.full-identifier.c++ + - include: identifier-path-generic + - match: '(::)\s*$' + captures: + 1: punctuation.accessor.double-colon.c++ + - match: '(?:(::)\s*)?(~?{{identifier}})(?=\s*\()' + captures: + 1: punctuation.accessor.double-colon.c++ + 2: entity.name.function.c++ + - match: '(?=[^\w\s])' + set: function-definition-params + - include: unique-strings + - match: '(?=\S)' + set: global-type + + global-type: + - include: comments + - match: \*|& + scope: keyword.operator.c++ + - match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}}|operator)\b)' + pop: true + - match: '(?=\s)' + set: global-maybe-function + # If a class/struct/enum followed by a name that is not a macro or declspec + # then this is likely a return type of a function. This is uncommon. + - match: |- + (?x: + ({{before_tag}}) + \s+ + (?= + (?![[:upper:][:digit:]_]+\b|__declspec|{{before_tag}}) + {{path_lookahead}} + (\s+{{identifier}}\s*\(|\s*[*&]) + ) + ) + captures: + 1: storage.type.c++ + set: + - include: identifiers + - match: '' + set: global-maybe-function + # The previous match handles return types of struct/enum/etc from a func, + # there this one exits the context to allow matching an actual struct/class + - match: '(?=\b({{before_tag}})\b)' + set: data-structures + - match: '(?=\b({{casts}})\b\s*<)' + pop: true + - match: '{{non_angle_brackets}}' + pop: true + - include: angle-brackets + - include: types + # Allow a macro call + - match: '({{identifier}})\s*(\()(?=[^\)]+\))' + captures: + 1: variable.function.c++ + 2: meta.group.c++ punctuation.section.group.begin.c++ + push: + - meta_scope: meta.function-call.c++ + - meta_content_scope: meta.group.c++ + - match: '\)' + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + - match: '(?={{path_lookahead}}\s*\()' + set: + - include: function-call + - match: '' + pop: true + - include: variables + - include: constants + - include: identifiers + - match: (?=\W) + pop: true + + global-maybe-function: + - include: comments + # Consume pointer info, macros and any type info that was offset by macros + - match: \*|& + scope: keyword.operator.c++ + - match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}})\b)' + pop: true + - match: '\b({{type_qualifier}})\b' + scope: storage.modifier.c++ + - match: '{{non_angle_brackets}}' + pop: true + - include: angle-brackets + - include: types + - include: modifiers-parens + - include: modifiers + # All uppercase identifier just before a newline is most likely a macro + - match: '[[:upper:][:digit:]_]+\s*$' + # Operator overloading + - match: '(?=({{path_lookahead}}\s*(?:{{generic_lookahead}})?::\s*)?{{operator_method_name}}\s*(\(|$))' + set: + - meta_content_scope: meta.function.c++ meta.toc-list.full-identifier.c++ + - include: identifier-path-generic + - match: '(?:(::)\s*)?({{operator_method_name}})(?=\s*\()' + captures: + 1: punctuation.accessor.double-colon.c++ + 2: entity.name.function.c++ + - match: '(?=\s*(\(|$))' + set: function-definition-params + # Identifier that is not the function name - likely a macro or type + - match: '(?={{path_lookahead}}([ \t]+|[*&])(?!\s*(<|::|\(|$)))' + push: + - include: identifiers + - match: '' + pop: true + # Real function definition + - match: '(?={{path_lookahead}}({{generic_lookahead}}({{path_lookahead}})?)\s*(\(|$))' + set: [function-definition-params, global-function-identifier-generic] + - match: '(?={{path_lookahead}}\s*(\(|$))' + set: [function-definition-params, global-function-identifier] + - match: '(?={{path_lookahead}}\s*::\s*$)' + set: [function-definition-params, global-function-identifier] + - match: '(?=\S)' + pop: true + + global-function-identifier-generic: + - meta_content_scope: meta.toc-list.full-identifier.c++ + - include: identifier-path-generic + - match: '(?:(::)\s*)?({{identifier}})(?=\s*(<.*>)?\s*\()' + captures: + 1: punctuation.accessor.double-colon.c++ + 2: entity.name.function.c++ + - match: '(?=\()' + pop: true + + global-function-identifier: + - meta_content_scope: meta.toc-list.full-identifier.c++ + - match: '(?:(::)\s*)?({{identifier}})(?!\s*(::))' + captures: + 1: punctuation.accessor.double-colon.c++ + 2: entity.name.function.c++ + - include: identifiers + - match: '(?=\S)' + pop: true + + function-definition-params: + - meta_content_scope: meta.function.c++ + - include: comments + - match: '(?=\()' + set: + - match: \( + scope: meta.function.parameters.c++ meta.group.c++ punctuation.section.group.begin.c++ + set: + - meta_content_scope: meta.function.parameters.c++ meta.group.c++ + - match : \) + scope: punctuation.section.group.end.c++ + set: function-definition-continue + - match: '\bvoid\b' + scope: storage.type.c++ + - match: '{{identifier}}(?=\s*(\[|,|\)|=))' + scope: variable.parameter.c++ + - match: '=' + scope: keyword.operator.assignment.c++ + push: + - match: '(?=,|\))' + pop: true + - include: expressions-minus-generic-type + - include: scope:source.c#preprocessor-line-continuation + - include: expressions-minus-generic-type + - include: scope:source.c#preprocessor-line-continuation + - match: (?=\S) + pop: true + + function-definition-continue: + - meta_content_scope: meta.function.c++ + - include: comments + - match: '(?=;)' + pop: true + - match: '->' + scope: punctuation.separator.c++ + set: function-definition-trailing-return + - include: function-specifiers + - match: '=' + scope: keyword.operator.assignment.c++ + - match: '&' + scope: keyword.operator.c++ + - match: \b0\b + scope: constant.numeric.integer.decimal.c++ + - match: \b(default|delete)\b + scope: storage.modifier.c++ + - match: '(?=\{)' + set: function-definition-body + - match: '(?=\S)' + pop: true + + function-definition-trailing-return: + - include: comments + - match: '(?=;)' + pop: true + - match: '(?=\{)' + set: function-definition-body + - include: function-specifiers + - include: function-trailing-return-type + + function-definition-body: + - meta_content_scope: meta.function.c++ meta.block.c++ + - match: '\{' + scope: punctuation.section.block.begin.c++ + set: + - meta_content_scope: meta.function.c++ meta.block.c++ + - match: '\}' + scope: meta.function.c++ meta.block.c++ punctuation.section.block.end.c++ + pop: true + - match: (?=^\s*#\s*(elif|else|endif)\b) + pop: true + - match: '(?=({{before_tag}})([^(;]+$|.*\{))' + push: data-structures + - include: statements + + ## Data structures including classes, structs, unions and enums + + data-structures: + - match: '\bclass\b' + scope: storage.type.c++ + set: data-structures-class-definition + # Detect variable type definitions using struct/enum/union followed by a tag + - match: '\b({{before_tag}})(?=\s+{{path_lookahead}}\s+{{path_lookahead}}\s*[=;\[])' + scope: storage.type.c++ + - match: '\bstruct\b' + scope: storage.type.c++ + set: data-structures-struct-definition + - match: '\benum(\s+(class|struct))?\b' + scope: storage.type.c++ + set: data-structures-enum-definition + - match: '\bunion\b' + scope: storage.type.c++ + set: data-structures-union-definition + - match: '(?=\S)' + pop: true + + preprocessor-workaround-eat-macro-before-identifier: + # Handle macros so they aren't matched as the class name + - match: ({{macro_identifier}})(?=\s+~?{{identifier}}) + captures: + 1: meta.assumed-macro.c + + data-structures-class-definition: + - meta_scope: meta.class.c++ + - include: data-structures-definition-common-begin + - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' + scope: entity.name.class.forward-decl.c++ + set: data-structures-class-definition-after-identifier + - match: '(?={{path_lookahead}})' + set: + - meta_scope: meta.class.c++ + - match: '{{identifier}}(?!\s*::)' + scope: entity.name.class.c++ + set: data-structures-class-definition-after-identifier + - include: identifiers + - match: '(?=[^\w\s])' + set: data-structures-class-definition-after-identifier + - match: '(?=[:{])' + set: data-structures-class-definition-after-identifier + - match: '(?=;)' + pop: true + + data-structures-class-definition-after-identifier: + - meta_content_scope: meta.class.c++ + - include: data-structures-definition-common-begin + # No matching of identifiers since they should all be macros at this point + - include: data-structures-definition-common-end + - match: '\{' + scope: meta.block.c++ punctuation.section.block.begin.c++ + set: + - meta_content_scope: meta.class.c++ meta.block.c++ + - match: '\}' + scope: meta.class.c++ meta.block.c++ punctuation.section.block.end.c++ + pop: true + - include: data-structures-body + + data-structures-struct-definition: + - meta_scope: meta.struct.c++ + - include: data-structures-definition-common-begin + - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' + scope: entity.name.struct.forward-decl.c++ + set: data-structures-struct-definition-after-identifier + - match: '(?={{path_lookahead}})' + set: + - meta_scope: meta.struct.c++ + - match: '{{identifier}}(?!\s*::)' + scope: entity.name.struct.c++ + set: data-structures-struct-definition-after-identifier + - include: identifiers + - match: '(?=[^\w\s])' + set: data-structures-struct-definition-after-identifier + - match: '(?=[:{])' + set: data-structures-struct-definition-after-identifier + - match: '(?=;)' + pop: true + + data-structures-struct-definition-after-identifier: + - meta_content_scope: meta.struct.c++ + - include: data-structures-definition-common-begin + # No matching of identifiers since they should all be macros at this point + - include: data-structures-definition-common-end + - match: '\{' + scope: meta.block.c++ punctuation.section.block.begin.c++ + set: + - meta_content_scope: meta.struct.c++ meta.block.c++ + - match: '\}' + scope: meta.struct.c++ meta.block.c++ punctuation.section.block.end.c++ + pop: true + - include: data-structures-body + + data-structures-enum-definition: + - meta_scope: meta.enum.c++ + - include: data-structures-definition-common-begin + - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' + scope: entity.name.enum.forward-decl.c++ + set: data-structures-enum-definition-after-identifier + - match: '(?={{path_lookahead}})' + set: + - meta_scope: meta.enum.c++ + - match: '{{identifier}}(?!\s*::)' + scope: entity.name.enum.c++ + set: data-structures-enum-definition-after-identifier + - include: identifiers + - match: '(?=[^\w\s])' + set: data-structures-enum-definition-after-identifier + - match: '(?=[:{])' + set: data-structures-enum-definition-after-identifier + - match: '(?=;)' + pop: true + + data-structures-enum-definition-after-identifier: + - meta_content_scope: meta.enum.c++ + - include: data-structures-definition-common-begin + # No matching of identifiers since they should all be macros at this point + - include: data-structures-definition-common-end + - match: '\{' + scope: meta.block.c++ punctuation.section.block.begin.c++ + set: + - meta_content_scope: meta.enum.c++ meta.block.c++ + # Enums don't support methods so we have a simplified body + - match: '\}' + scope: meta.enum.c++ meta.block.c++ punctuation.section.block.end.c++ + pop: true + - include: statements + + data-structures-union-definition: + - meta_scope: meta.union.c++ + - include: data-structures-definition-common-begin + - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' + scope: entity.name.union.forward-decl.c++ + set: data-structures-union-definition-after-identifier + - match: '(?={{path_lookahead}})' + set: + - meta_scope: meta.union.c++ + - match: '{{identifier}}(?!\s*::)' + scope: entity.name.union.c++ + set: data-structures-union-definition-after-identifier + - include: identifiers + - match: '(?=[^\w\s])' + set: data-structures-union-definition-after-identifier + - match: '(?=[{])' + set: data-structures-union-definition-after-identifier + - match: '(?=;)' + pop: true + + data-structures-union-definition-after-identifier: + - meta_content_scope: meta.union.c++ + - include: data-structures-definition-common-begin + # No matching of identifiers since they should all be macros at this point + # Unions don't support base classes + - include: angle-brackets + - match: '\{' + scope: meta.block.c++ punctuation.section.block.begin.c++ + set: + - meta_content_scope: meta.union.c++ meta.block.c++ + - match: '\}' + scope: meta.union.c++ meta.block.c++ punctuation.section.block.end.c++ + pop: true + - include: data-structures-body + - match: '(?=;)' + pop: true + + data-structures-definition-common-begin: + - include: comments + - match: '(?=\b(?:{{before_tag}}|{{control_keywords}})\b)' + pop: true + - include: preprocessor-other + - include: modifiers-parens + - include: modifiers + - include: preprocessor-workaround-eat-macro-before-identifier + + data-structures-definition-common-end: + - include: angle-brackets + - match: \bfinal\b + scope: storage.modifier.c++ + - match: ':' + scope: punctuation.separator.c++ + push: + - include: comments + - include: preprocessor-other + - include: modifiers-parens + - include: modifiers + - match: '\b(virtual|{{visibility_modifiers}})\b' + scope: storage.modifier.c++ + - match: (?={{path_lookahead}}) + push: + - meta_scope: entity.other.inherited-class.c++ + - include: identifiers + - match: '' + pop: true + - include: angle-brackets + - match: ',' + scope: punctuation.separator.c++ + - match: (?=\{|;) + pop: true + - match: '(?=;)' + pop: true + + data-structures-body: + - include: preprocessor-data-structures + - match: '(?=\btemplate\b)' + push: + - include: template + - match: (?=\S) + set: data-structures-modifier + - include: using-namespace + - include: typedef + - include: using-alias + - match: \b({{visibility_modifiers}})\s*(:)(?!:) + captures: + 1: storage.modifier.c++ + 2: punctuation.section.class.c++ + - match: '^\s*(?=(?:~?\w+|::))' + push: data-structures-modifier + - include: expressions-minus-generic-type + + data-structures-modifier-friend: + - match: (?=;) + pop: true + - match: '\{' + scope: punctuation.section.block.begin.c++ + set: + - meta_scope: meta.block.c++ + - match: '\}' + scope: punctuation.section.block.end.c++ + pop: true + - include: statements + - include: expressions-minus-function-call + + data-structures-modifier: + - match: '\bfriend\b' + scope: storage.modifier.c++ + push: + - include: comments + - match: '\b({{before_tag}})\b' + scope: storage.type.c++ + set: data-structures-modifier-friend + - match: '(?=\S)(?=[^;]+;)' + set: data-structures-modifier-friend + - match: '(?=\S)' + pop: true + - include: comments + - include: modifiers-parens + - include: modifiers + - match: '\bstatic_assert(?=\s*\()' + scope: meta.static-assert.c++ keyword.operator.word.c++ + push: + - match: '\(' + scope: meta.group.c++ punctuation.section.group.begin.c++ + set: + - meta_content_scope: meta.function-call.c++ meta.group.c++ + - match: '\)' + scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + # Destructor + - match: '(?:{{identifier}}\s*(::)\s*)?~{{identifier}}(?=\s*(\(|$))' + scope: meta.method.destructor.c++ entity.name.function.destructor.c++ + captures: + 1: punctuation.accessor.c++ + set: method-definition-params + # It's a macro, not a constructor if there is no type in the first param + - match: '({{identifier}})\s*(\()(?=\s*(?!void){{identifier}}\s*[),])' + captures: + 1: variable.function.c++ + 2: meta.group.c++ punctuation.section.group.begin.c++ + push: + - meta_scope: meta.function-call.c++ + - meta_content_scope: meta.group.c++ + - match: '\)' + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + # Constructor + - include: preprocessor-workaround-eat-macro-before-identifier + - match: '((?!{{before_tag}}|template){{identifier}})(?=\s*\()' + scope: meta.method.constructor.c++ entity.name.function.constructor.c++ + set: method-definition-params + # Long form constructor + - match: '({{identifier}}\s*(::)\s*{{identifier}})(?=\s*\()' + captures: + 1: meta.method.constructor.c++ entity.name.function.constructor.c++ + 2: punctuation.accessor.c++ + push: method-definition-params + - match: '(?=\S)' + set: data-structures-type + + data-structures-type: + - include: comments + - match: \*|& + scope: keyword.operator.c++ + # Cast methods + - match: '(operator)\s+({{identifier}})(?=\s*(\(|$))' + captures: + 1: keyword.control.c++ + 2: meta.method.c++ entity.name.function.c++ + set: method-definition-params + - match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}}|operator)\b)' + pop: true + - match: '(?=\s)' + set: data-structures-maybe-method + # If a class/struct/enum followed by a name that is not a macro or declspec + # then this is likely a return type of a function. This is uncommon. + - match: |- + (?x: + ({{before_tag}}) + \s+ + (?= + (?![[:upper:][:digit:]_]+\b|__declspec|{{before_tag}}) + {{path_lookahead}} + (\s+{{identifier}}\s*\(|\s*[*&]) + ) + ) + captures: + 1: storage.type.c++ + set: + - include: identifiers + - match: '' + set: data-structures-maybe-method + # The previous match handles return types of struct/enum/etc from a func, + # there this one exits the context to allow matching an actual struct/class + - match: '(?=\b({{before_tag}})\b)' + set: data-structures + - match: '(?=\b({{casts}})\b\s*<)' + pop: true + - match: '{{non_angle_brackets}}' + pop: true + - include: angle-brackets + - include: types + - include: variables + - include: constants + - include: identifiers + - match: (?=[&*]) + set: data-structures-maybe-method + - match: (?=\W) + pop: true + + data-structures-maybe-method: + - include: comments + # Consume pointer info, macros and any type info that was offset by macros + - match: \*|& + scope: keyword.operator.c++ + - match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}})\b)' + pop: true + - match: '\b({{type_qualifier}})\b' + scope: storage.modifier.c++ + - match: '{{non_angle_brackets}}' + pop: true + - include: angle-brackets + - include: types + - include: modifiers-parens + - include: modifiers + # Operator overloading + - match: '{{operator_method_name}}(?=\s*(\(|$))' + scope: meta.method.c++ entity.name.function.c++ + set: method-definition-params + # Identifier that is not the function name - likely a macro or type + - match: '(?={{path_lookahead}}([ \t]+|[*&])(?!\s*(<|::|\()))' + push: + - include: identifiers + - match: '' + pop: true + # Real function definition + - match: '(?={{path_lookahead}}({{generic_lookahead}})\s*(\())' + set: [method-definition-params, data-structures-function-identifier-generic] + - match: '(?={{path_lookahead}}\s*(\())' + set: [method-definition-params, data-structures-function-identifier] + - match: '(?={{path_lookahead}}\s*::\s*$)' + set: [method-definition-params, data-structures-function-identifier] + - match: '(?=\S)' + pop: true + + data-structures-function-identifier-generic: + - include: angle-brackets + - match: '(?={{identifier}})' + push: + - meta_content_scope: entity.name.function.c++ + - include: identifiers + - match: '(?=<)' + pop: true + - match: '(?=\()' + pop: true + + data-structures-function-identifier: + - meta_content_scope: entity.name.function.c++ + - include: identifiers + - match: '(?=\S)' + pop: true + + method-definition-params: + - meta_content_scope: meta.method.c++ + - include: comments + - match: '(?=\()' + set: + - match: \( + scope: meta.method.parameters.c++ meta.group.c++ punctuation.section.group.begin.c++ + set: + - meta_content_scope: meta.method.parameters.c++ meta.group.c++ + - match : \) + scope: punctuation.section.group.end.c++ + set: method-definition-continue + - match: '\bvoid\b' + scope: storage.type.c++ + - match: '{{identifier}}(?=\s*(\[|,|\)|=))' + scope: variable.parameter.c++ + - match: '=' + scope: keyword.operator.assignment.c++ + push: + - match: '(?=,|\))' + pop: true + - include: expressions-minus-generic-type + - include: expressions-minus-generic-type + - match: '(?=\S)' + pop: true + + method-definition-continue: + - meta_content_scope: meta.method.c++ + - include: comments + - match: '(?=;)' + pop: true + - match: '->' + scope: punctuation.separator.c++ + set: method-definition-trailing-return + - include: function-specifiers + - match: '=' + scope: keyword.operator.assignment.c++ + - match: '&' + scope: keyword.operator.c++ + - match: \b0\b + scope: constant.numeric.integer.decimal.c++ + - match: \b(default|delete)\b + scope: storage.modifier.c++ + - match: '(?=:)' + set: + - match: ':' + scope: punctuation.separator.initializer-list.c++ + set: + - meta_scope: meta.method.constructor.initializer-list.c++ + - match: '{{identifier}}' + scope: variable.other.readwrite.member.c++ + push: + - match: \( + scope: meta.group.c++ punctuation.section.group.begin.c++ + set: + - meta_content_scope: meta.group.c++ + - match: \) + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + - match: \{ + scope: meta.group.c++ punctuation.section.group.begin.c++ + set: + - meta_content_scope: meta.group.c++ + - match: \} + scope: meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + - include: comments + - match: (?=\{|;) + set: method-definition-continue + - include: expressions + - match: '(?=\{)' + set: method-definition-body + - match: '(?=\S)' + pop: true + + method-definition-trailing-return: + - include: comments + - match: '(?=;)' + pop: true + - match: '(?=\{)' + set: method-definition-body + - include: function-specifiers + - include: function-trailing-return-type + + method-definition-body: + - meta_content_scope: meta.method.c++ meta.block.c++ + - match: '\{' + scope: punctuation.section.block.begin.c++ + set: + - meta_content_scope: meta.method.c++ meta.block.c++ + - match: '\}' + scope: meta.method.c++ meta.block.c++ punctuation.section.block.end.c++ + pop: true + - match: (?=^\s*#\s*(elif|else|endif)\b) + pop: true + - match: '(?=({{before_tag}})([^(;]+$|.*\{))' + push: data-structures + - include: statements + + ## Preprocessor for data-structures + + preprocessor-data-structures: + - include: preprocessor-rule-enabled-data-structures + - include: preprocessor-rule-disabled-data-structures + - include: preprocessor-practical-workarounds + + preprocessor-rule-disabled-data-structures: + - match: ^\s*((#if)\s+(0))\b + captures: + 1: meta.preprocessor.c++ + 2: keyword.control.import.c++ + 3: constant.numeric.integer.decimal.c++ + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.else.c++ + push: + - match: (?=^\s*#\s*endif\b) + pop: true + - include: negated-block + - include: data-structures-body + - match: "" + push: + - meta_scope: comment.block.preprocessor.if-branch.c++ + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: scope:source.c#preprocessor-disabled + + preprocessor-rule-enabled-data-structures: + - match: ^\s*((#if)\s+(0*1))\b + captures: + 1: meta.preprocessor.c++ + 2: keyword.control.import.c++ + 3: constant.numeric.integer.decimal.c++ + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.else.c++ + push: + - meta_content_scope: comment.block.preprocessor.else-branch.c++ + - match: (?=^\s*#\s*endif\b) + pop: true + - include: scope:source.c#preprocessor-disabled + - match: "" + push: + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: negated-block + - include: data-structures-body + + ## Preprocessor for global + + preprocessor-global: + - include: preprocessor-rule-enabled-global + - include: preprocessor-rule-disabled-global + - include: preprocessor-rule-other-global + + preprocessor-statements: + - include: preprocessor-rule-enabled-statements + - include: preprocessor-rule-disabled-statements + - include: preprocessor-rule-other-statements + + preprocessor-expressions: + - include: scope:source.c#incomplete-inc + - include: preprocessor-macro-define + - include: scope:source.c#pragma-mark + - include: preprocessor-other + + preprocessor-rule-disabled-global: + - match: ^\s*((#if)\s+(0))\b + captures: + 1: meta.preprocessor.c++ + 2: keyword.control.import.c++ + 3: constant.numeric.integer.decimal.c++ + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.else.c++ + push: + - match: (?=^\s*#\s*endif\b) + pop: true + - include: preprocessor-global + - include: negated-block + - include: global + - match: "" + push: + - meta_scope: comment.block.preprocessor.if-branch.c++ + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: scope:source.c#preprocessor-disabled + + preprocessor-rule-enabled-global: + - match: ^\s*((#if)\s+(0*1))\b + captures: + 1: meta.preprocessor.c++ + 2: keyword.control.import.c++ + 3: constant.numeric.integer.decimal.c++ + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.else.c++ + push: + - meta_content_scope: comment.block.preprocessor.else-branch.c++ + - match: (?=^\s*#\s*endif\b) + pop: true + - include: scope:source.c#preprocessor-disabled + - match: "" + push: + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: preprocessor-global + - include: negated-block + - include: global + + preprocessor-rule-other-global: + - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b + captures: + 1: keyword.control.import.c++ + push: + - meta_scope: meta.preprocessor.c++ + - include: scope:source.c#preprocessor-line-continuation + - 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. + - match: $\n + set: preprocessor-if-branch-global + + # These gymnastics here ensure that we are properly handling scope even + # when the preprocessor is used to create different scope beginnings, such + # as a different if/while condition + preprocessor-if-branch-global: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + pop: true + - match: (?=^\s*#\s*(elif|else)\b) + push: preprocessor-elif-else-branch-global + - match: \{ + scope: punctuation.section.block.begin.c++ + set: preprocessor-block-if-branch-global + - include: preprocessor-global + - include: negated-block + - include: global + + preprocessor-block-if-branch-global: + - meta_scope: meta.block.c++ + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + set: preprocessor-block-finish-global + - match: (?=^\s*#\s*(elif|else)\b) + push: preprocessor-elif-else-branch-global + - match: \} + scope: punctuation.section.block.end.c++ + set: preprocessor-if-branch-global + - include: statements + + preprocessor-block-finish-global: + - meta_scope: meta.block.c++ + - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + set: preprocessor-block-finish-if-branch-global + - match: \} + scope: punctuation.section.block.end.c++ + pop: true + - include: statements + + preprocessor-block-finish-if-branch-global: + - match: ^\s*(#\s*endif)\b + captures: + 1: keyword.control.import.c++ + pop: true + - match: \} + scope: punctuation.section.block.end.c++ + set: preprocessor-if-branch-global + - include: statements + + preprocessor-elif-else-branch-global: + - match: (?=^\s*#\s*(endif)\b) + pop: true + - include: preprocessor-global + - include: negated-block + - include: global + + ## Preprocessor for statements + + preprocessor-rule-disabled-statements: + - match: ^\s*((#if)\s+(0))\b + captures: + 1: meta.preprocessor.c++ + 2: keyword.control.import.c++ + 3: constant.numeric.integer.decimal.c++ + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.else.c++ + push: + - match: (?=^\s*#\s*endif\b) + pop: true + - include: negated-block + - include: statements + - match: "" + push: + - meta_scope: comment.block.preprocessor.if-branch.c++ + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: scope:source.c#preprocessor-disabled + + preprocessor-rule-enabled-statements: + - match: ^\s*((#if)\s+(0*1))\b + captures: + 1: meta.preprocessor.c++ + 2: keyword.control.import.c++ + 3: constant.numeric.integer.decimal.c++ + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.else.c++ + push: + - meta_content_scope: comment.block.preprocessor.else-branch.c++ + - match: (?=^\s*#\s*endif\b) + pop: true + - include: scope:source.c#preprocessor-disabled + - match: "" + push: + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: negated-block + - include: statements + + preprocessor-rule-other-statements: + - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b + captures: + 1: keyword.control.import.c++ + push: + - meta_scope: meta.preprocessor.c++ + - include: scope:source.c#preprocessor-line-continuation + - 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. + - match: $\n + set: preprocessor-if-branch-statements + + # These gymnastics here ensure that we are properly handling scope even + # when the preprocessor is used to create different scope beginnings, such + # as a different if/while condition + preprocessor-if-branch-statements: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + pop: true + - match: (?=^\s*#\s*(elif|else)\b) + push: preprocessor-elif-else-branch-statements + - match: \{ + scope: punctuation.section.block.begin.c++ + set: preprocessor-block-if-branch-statements + - match: (?=(?!{{non_func_keywords}}){{path_lookahead}}\s*\() + set: preprocessor-if-branch-function-call + - include: negated-block + - include: statements + + preprocessor-if-branch-function-call: + - meta_content_scope: meta.function-call.c++ + - include: scope:source.c#c99 + - match: '(?:(::)\s*)?{{identifier}}\s*(::)\s*' + scope: variable.function.c++ + captures: + 1: punctuation.accessor.c++ + 2: punctuation.accessor.c++ + - match: '(?:(::)\s*)?{{identifier}}' + scope: variable.function.c++ + captures: + 1: punctuation.accessor.c++ + - match: '\(' + scope: meta.group.c++ punctuation.section.group.begin.c++ + set: preprocessor-if-branch-function-call-arguments + + preprocessor-if-branch-function-call-arguments: + - meta_content_scope: meta.function-call.c++ meta.group.c++ + - 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 + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + set: preprocessor-if-branch-statements + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + set: preprocessor-if-branch-function-call-arguments-finish + - include: expressions + + preprocessor-if-branch-function-call-arguments-finish: + - meta_content_scope: meta.function-call.c++ meta.group.c++ + - match: \) + scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ + pop: true + - include: expressions + + preprocessor-block-if-branch-statements: + - meta_scope: meta.block.c++ + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + set: preprocessor-block-finish-statements + - match: (?=^\s*#\s*(elif|else)\b) + push: preprocessor-elif-else-branch-statements + - match: \} + scope: punctuation.section.block.end.c++ + set: preprocessor-if-branch-statements + - include: statements + + preprocessor-block-finish-statements: + - meta_scope: meta.block.c++ + - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + set: preprocessor-block-finish-if-branch-statements + - match: \} + scope: punctuation.section.block.end.c++ + pop: true + - include: statements + + preprocessor-block-finish-if-branch-statements: + - match: ^\s*(#\s*endif)\b + captures: + 1: keyword.control.import.c++ + pop: true + - match: \} + scope: meta.block.c++ punctuation.section.block.end.c++ + set: preprocessor-if-branch-statements + - include: statements + + preprocessor-elif-else-branch-statements: + - match: (?=^\s*#\s*endif\b) + pop: true + - include: negated-block + - include: statements + + ## Preprocessor other + + negated-block: + - match: '\}' + scope: punctuation.section.block.end.c++ + push: + - match: '\{' + scope: punctuation.section.block.begin.c++ + pop: true + - match: (?=^\s*#\s*(elif|else|endif)\b) + pop: true + - include: statements + + preprocessor-macro-define: + - match: ^\s*(\#\s*define)\b + captures: + 1: meta.preprocessor.macro.c++ keyword.control.import.define.c++ + push: + - meta_content_scope: meta.preprocessor.macro.c++ + - include: scope:source.c#preprocessor-line-continuation + - include: scope:source.c#preprocessor-line-ending + - include: scope:source.c#preprocessor-comments + - match: '({{identifier}})(?=\()' + scope: entity.name.function.preprocessor.c++ + set: + - match: '\(' + scope: punctuation.section.group.begin.c++ + set: preprocessor-macro-params + - match: '{{identifier}}' + scope: entity.name.constant.preprocessor.c++ + set: preprocessor-macro-definition + + preprocessor-macro-params: + - meta_scope: meta.preprocessor.macro.parameters.c++ meta.group.c++ + - match: '{{identifier}}' + scope: variable.parameter.c++ + - match: \) + scope: punctuation.section.group.end.c++ + set: preprocessor-macro-definition + - match: ',' + scope: punctuation.separator.c++ + push: + - match: '{{identifier}}' + scope: variable.parameter.c++ + pop: true + - include: scope:source.c#preprocessor-line-continuation + - include: scope:source.c#preprocessor-comments + - match: '\.\.\.' + scope: keyword.operator.variadic.c++ + - match: '(?=\))' + pop: true + - match: (/\*).*(\*/) + scope: comment.block.c++ + captures: + 1: punctuation.definition.comment.c++ + 2: punctuation.definition.comment.c++ + - match: '\S+' + scope: invalid.illegal.unexpected-character.c++ + - include: scope:source.c#preprocessor-line-continuation + - include: scope:source.c#preprocessor-comments + - match: '\.\.\.' + scope: keyword.operator.variadic.c++ + - match: (/\*).*(\*/) + scope: comment.block.c++ + captures: + 1: punctuation.definition.comment.c++ + 2: punctuation.definition.comment.c++ + - match: $\n + scope: invalid.illegal.unexpected-end-of-line.c++ + + preprocessor-macro-definition: + - meta_content_scope: meta.preprocessor.macro.c++ + - include: scope:source.c#preprocessor-line-continuation + - include: scope:source.c#preprocessor-line-ending + - include: scope:source.c#preprocessor-comments + # Don't define blocks in define statements + - match: '\{' + scope: punctuation.section.block.begin.c++ + - match: '\}' + scope: punctuation.section.block.end.c++ + # Captures the namespace macro idiom + - match: '\b(namespace)\s+(?={{path_lookahead}}\s*\{)' + scope: meta.namespace.c++ + captures: + 1: keyword.control.c++ + push: + - meta_content_scope: meta.namespace.c++ entity.name.namespace.c++ + - include: identifiers + - match: '(?=\S)' + pop: true + - include: expressions + + preprocessor-practical-workarounds: + - include: preprocessor-convention-ignore-uppercase-ident-lines + - include: scope:source.c#preprocessor-convention-ignore-uppercase-calls-without-semicolon + + preprocessor-convention-ignore-uppercase-ident-lines: + - match: ^(\s*{{macro_identifier}})+\s*$ + scope: meta.assumed-macro.c++ + push: + # It's possible that we are dealing with a function return type on its own line, and the + # name of the function is on the subsequent line. + - match: '(?={{path_lookahead}}({{generic_lookahead}}({{path_lookahead}})?)\s*\()' + set: [function-definition-params, global-function-identifier-generic] + - match: '(?={{path_lookahead}}\s*\()' + set: [function-definition-params, global-function-identifier] + - match: ^ + pop: true + + preprocessor-other: + - match: ^\s*(#\s*(?:if|ifdef|ifndef|elif|else|line|pragma|undef))\b + captures: + 1: keyword.control.import.c++ + push: + - meta_scope: meta.preprocessor.c++ + - include: scope:source.c#preprocessor-line-continuation + - include: scope:source.c#preprocessor-line-ending + - include: scope:source.c#preprocessor-comments + - match: \bdefined\b + scope: keyword.control.c++ + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c++ keyword.control.import.c++ + - match: ^\s*(#\s*(?:error|warning))\b + captures: + 1: keyword.control.import.error.c++ + push: + - meta_scope: meta.preprocessor.diagnostic.c++ + - include: scope:source.c#preprocessor-line-continuation + - include: scope:source.c#preprocessor-line-ending + - include: scope:source.c#preprocessor-comments + - include: strings + - match: '\S+' + scope: string.unquoted.c++ + - match: ^\s*(#\s*(?:include|include_next|import))\b + captures: + 1: keyword.control.import.include.c++ + push: + - meta_scope: meta.preprocessor.include.c++ + - include: scope:source.c#preprocessor-line-continuation + - include: scope:source.c#preprocessor-line-ending + - include: scope:source.c#preprocessor-comments + - match: '"' + scope: punctuation.definition.string.begin.c++ + push: + - meta_scope: string.quoted.double.include.c++ + - match: '"' + scope: punctuation.definition.string.end.c++ + pop: true + - match: < + scope: punctuation.definition.string.begin.c++ + push: + - meta_scope: string.quoted.other.lt-gt.include.c++ + - match: '>' + scope: punctuation.definition.string.end.c++ + pop: true + - include: preprocessor-practical-workarounds diff --git a/syntaxes/C++/C.sublime-syntax b/syntaxes/C++/C.sublime-syntax @@ -0,0 +1,1311 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: C +file_extensions: + - c + - h +first_line_match: "-[*]-( Mode:)? C -[*]-" +scope: source.c + +variables: + # number exponents + dec_exponent: '(?:[eE][-+]??\d+)' + hex_exponent: '(?:[pP][-+]??\d+)' + + # number suffixes + dec_suffix: '[a-zA-Z_][[:alnum:]_]*' + hex_suffix: '[g-zG-Z_][[:alnum:]_]*' + integer_suffix: '[lL]{1,2}[uU]?|[uU][lL]{0,2}' + + identifier: \b[[:alpha:]_][[:alnum:]_]*\b # upper and lowercase + macro_identifier: \b[[:upper:]_][[:upper:][:digit:]_]{2,}\b # only uppercase, at least 3 chars + control_keywords: 'break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while' + basic_types: 'asm|__asm__|auto|bool|_Bool|char|_Complex|double|float|_Imaginary|int|long|short|signed|unsigned|void' + before_tag: 'struct|union|enum' + microsoft_types: '__int8|__int16|__int32|__int64' + windows_types: 'APIENTRY|ATOM|BOOL|BOOLEAN|BYTE|CALLBACK|CCHAR|CHAR|COLORREF|CONST|DWORD|DWORDLONG|DWORD_PTR|DWORD32|DWORD64|FLOAT|HACCEL|HALF_PTR|HANDLE|HBITMAP|HBRUSH|HCOLORSPACE|HCONV|HCONVLIST|HCURSOR|HDC|HDDEDATA|HDESK|HDROP|HDWP|HENHMETAFILE|HFILE|HFONT|HGDIOBJ|HGLOBAL|HHOOK|HICON|HINSTANCE|HKEY|HKL|HLOCAL|HMENU|HMETAFILE|HMODULE|HMONITOR|HPALETTE|HPEN|HRESULT|HRGN|HRSRC|HSZ|HWINSTA|HWND|INT|INT_PTR|INT8|INT16|INT32|INT64|LANGID|LCID|LCTYPE|LGRPID|LONG|LONGLONG|LONG_PTR|LONG32|LONG64|LPARAM|LPBOOL|LPBYTE|LPCOLORREF|LPCSTR|LPCTSTR|LPCVOID|LPCWSTR|LPDWORD|LPHANDLE|LPINT|LPLONG|LPSTR|LPTSTR|LPVOID|LPWORD|LPWSTR|LRESULT|PBOOL|PBOOLEAN|PBYTE|PCHAR|PCSTR|PCTSTR|PCWSTR|PDWORD|PDWORDLONG|PDWORD_PTR|PDWORD32|PDWORD64|PFLOAT|PHALF_PTR|PHANDLE|PHKEY|PINT|PINT_PTR|PINT8|PINT16|PINT32|PINT64|PLCID|PLONG|PLONGLONG|PLONG_PTR|PLONG32|PLONG64|POINTER_32|POINTER_64|POINTER_SIGNED|POINTER_UNSIGNED|PSHORT|PSIZE_T|PSSIZE_T|PSTR|PTBYTE|PTCHAR|PTSTR|PUCHAR|PUHALF_PTR|PUINT|PUINT_PTR|PUINT8|PUINT16|PUINT32|PUINT64|PULONG|PULONGLONG|PULONG_PTR|PULONG32|PULONG64|PUSHORT|PVOID|PWCHAR|PWORD|PWSTR|QWORD|SC_HANDLE|SC_LOCK|SERVICE_STATUS_HANDLE|SHORT|SIZE_T|SSIZE_T|TBYTE|TCHAR|UCHAR|UHALF_PTR|UINT|UINT_PTR|UINT8|UINT16|UINT32|UINT64|ULONG|ULONGLONG|ULONG_PTR|ULONG32|ULONG64|UNICODE_STRING|USHORT|USN|VOID|WCHAR|WINAPI|WORD|WPARAM' + stdint: 'int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t' + declspec: '__declspec\(\s*\w+(?:\([^)]+\))?\s*\)' + storage_classes: 'static|extern|register|{{declspec}}' + type_qualifier: 'const|volatile' + compiler_directive: 'inline|restrict|__restrict__|__restrict' + modifiers: '{{storage_classes}}|{{type_qualifier}}|{{compiler_directive}}' + non_func_keywords: 'if|for|switch|while|decltype|sizeof|__declspec|__attribute__' + +contexts: + main: + - include: preprocessor-global + - include: global + + ############################################################################# + # Reusable contexts + # + # The follow contexts are currently constructed to be reused in the C++ + # syntax. They are specifically constructed to not push into sub-contexts, + # which ensures that C++ code isn't accidentally lexed as plain C. They also + # should not use the {{identifier}} variable since that is different for C++. + ############################################################################# + + comments: + - match: ^/\* =(\s*.*?)\s*= \*/$\n? + scope: comment.block.c + captures: + 1: meta.toc-list.banner.block.c + - match: /\* + scope: punctuation.definition.comment.c + push: + - meta_scope: comment.block.c + - match: \*/ + scope: punctuation.definition.comment.c + pop: true + - match: ^\s*(\*)(?!/) + captures: + 1: punctuation.definition.comment.c + - match: \*/(?!\*) + scope: invalid.illegal.stray-comment-end.c + - match: ^// =(\s*.*?)\s*=\s*$\n? + scope: comment.line.banner.c + captures: + 1: meta.toc-list.banner.line.c + - match: // + scope: punctuation.definition.comment.c + push: + - meta_scope: comment.line.double-slash.c + - match: '(\\)$\n' + captures: + 1: punctuation.separator.continuation.c + - match: \n + pop: true + + strings: + - match: '(L|u8|u|U)?(")' + captures: + 1: storage.type.string.c + 2: punctuation.definition.string.begin.c + push: + - meta_scope: string.quoted.double.c + - match: '"' + scope: punctuation.definition.string.end.c + pop: true + - include: string_escaped_char + - include: string_placeholder + - match: "(L|u8|u|U)?(')" + captures: + 1: storage.type.string.c + 2: punctuation.definition.string.begin.c + push: + - meta_scope: string.quoted.single.c + - match: "'" + scope: punctuation.definition.string.end.c + pop: true + - include: string_escaped_char + + string_escaped_char: + - match: '(\\)$\n' + captures: + 1: punctuation.separator.continuation.c + - match: \\(?:\\|[abefnrtv\'"?]|[0-3][0-9]{0,2}|[4-7][0-9]?|x[a-fA-F0-9]+|u[a-fA-F0-9]{4}|U[a-fA-F0-9]{8}) + scope: constant.character.escape.c + - match: \\. + scope: invalid.illegal.unknown-escape.c + + string_placeholder: + - match: |- + (?x)% + (\d+\$)? # field (argument #) + [#0\- +']* # flags + [,;:_]? # separator character (AltiVec) + ((-?\d+)|\*(-?\d+\$)?)? # minimum field width + (\.((-?\d+)|\*(-?\d+\$)?)?)? # precision + (hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)? # length modifier + (\[[^\]]+\]|[am]s|[diouxXDOUeEfFgGaACcSspn%]) # conversion type + scope: constant.other.placeholder.c + + keywords: + - match: \bbreak\b + scope: keyword.control.flow.break.c + - match: \bcontinue\b + scope: keyword.control.flow.continue.c + - match: \bgoto\b + scope: keyword.control.flow.goto.c + - match: \breturn\b + scope: keyword.control.flow.return.c + - match: \b({{control_keywords}})\b + scope: keyword.control.c + - match: \bsizeof\b + scope: keyword.operator.word.c + + modifiers: + - match: \b({{modifiers}})\b + scope: storage.modifier.c + + variables: + - match: '\bg[A-Z]\w*\b' + scope: variable.other.readwrite.global.mac-classic.c + - match: '\bs[A-Z]\w*\b' + scope: variable.other.readwrite.static.mac-classic.c + + constants: + - match: \b(__func__|NULL|true|false|TRUE|FALSE)\b + scope: constant.language.c + - match: \b(__FILE__|__FUNCTION__|__LINE__)\b + scope: support.constant.c + # common C constant naming idiom -- kConstantVariable + - match: '\bk[A-Z]\w*\b' + scope: constant.other.variable.mac-classic.c + - match: \b(noErr|kNilOptions|kInvalidID|kVariableLengthArray)\b + scope: support.constant.mac-classic.c + + c99: + - match: \b(hypot(f|l)?|s(scanf|ystem|nprintf|ca(nf|lb(n(f|l)?|ln(f|l)?))|i(n(h(f|l)?|f|l)?|gn(al|bit))|tr(s(tr|pn)|nc(py|at|mp)|c(spn|hr|oll|py|at|mp)|to(imax|d|u(l(l)?|max)|k|f|l(d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(jmp|vbuf|locale|buf)|qrt(f|l)?|w(scanf|printf)|rand)|n(e(arbyint(f|l)?|xt(toward(f|l)?|after(f|l)?))|an(f|l)?)|c(s(in(h(f|l)?|f|l)?|qrt(f|l)?)|cos(h(f)?|f|l)?|imag(f|l)?|t(ime|an(h(f|l)?|f|l)?)|o(s(h(f|l)?|f|l)?|nj(f|l)?|pysign(f|l)?)|p(ow(f|l)?|roj(f|l)?)|e(il(f|l)?|xp(f|l)?)|l(o(ck|g(f|l)?)|earerr)|a(sin(h(f|l)?|f|l)?|cos(h(f|l)?|f|l)?|tan(h(f|l)?|f|l)?|lloc|rg(f|l)?|bs(f|l)?)|real(f|l)?|brt(f|l)?)|t(ime|o(upper|lower)|an(h(f|l)?|f|l)?|runc(f|l)?|gamma(f|l)?|mp(nam|file))|i(s(space|n(ormal|an)|cntrl|inf|digit|u(nordered|pper)|p(unct|rint)|finite|w(space|c(ntrl|type)|digit|upper|p(unct|rint)|lower|al(num|pha)|graph|xdigit|blank)|l(ower|ess(equal|greater)?)|al(num|pha)|gr(eater(equal)?|aph)|xdigit|blank)|logb(f|l)?|max(div|abs))|di(v|fftime)|_Exit|unget(c|wc)|p(ow(f|l)?|ut(s|c(har)?|wc(har)?)|error|rintf)|e(rf(c(f|l)?|f|l)?|x(it|p(2(f|l)?|f|l|m1(f|l)?)?))|v(s(scanf|nprintf|canf|printf|w(scanf|printf))|printf|f(scanf|printf|w(scanf|printf))|w(scanf|printf)|a_(start|copy|end|arg))|qsort|f(s(canf|e(tpos|ek))|close|tell|open|dim(f|l)?|p(classify|ut(s|c|w(s|c))|rintf)|e(holdexcept|set(e(nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(aiseexcept|ror)|get(e(nv|xceptflag)|round))|flush|w(scanf|ide|printf|rite)|loor(f|l)?|abs(f|l)?|get(s|c|pos|w(s|c))|re(open|e|ad|xp(f|l)?)|m(in(f|l)?|od(f|l)?|a(f|l|x(f|l)?)?))|l(d(iv|exp(f|l)?)|o(ngjmp|cal(time|econv)|g(1(p(f|l)?|0(f|l)?)|2(f|l)?|f|l|b(f|l)?)?)|abs|l(div|abs|r(int(f|l)?|ound(f|l)?))|r(int(f|l)?|ound(f|l)?)|gamma(f|l)?)|w(scanf|c(s(s(tr|pn)|nc(py|at|mp)|c(spn|hr|oll|py|at|mp)|to(imax|d|u(l(l)?|max)|k|f|l(d|l)?|mbs)|pbrk|ftime|len|r(chr|tombs)|xfrm)|to(b|mb)|rtomb)|printf|mem(set|c(hr|py|mp)|move))|a(s(sert|ctime|in(h(f|l)?|f|l)?)|cos(h(f|l)?|f|l)?|t(o(i|f|l(l)?)|exit|an(h(f|l)?|2(f|l)?|f|l)?)|b(s|ort))|g(et(s|c(har)?|env|wc(har)?)|mtime)|r(int(f|l)?|ound(f|l)?|e(name|alloc|wind|m(ove|quo(f|l)?|ainder(f|l)?))|a(nd|ise))|b(search|towc)|m(odf(f|l)?|em(set|c(hr|py|mp)|move)|ktime|alloc|b(s(init|towcs|rtowcs)|towc|len|r(towc|len))))\b + scope: support.function.C99.c + + types: + - match: \b({{basic_types}}|{{before_tag}})\b + scope: storage.type.c + - match: \b(u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t|ptrdiff_t)\b + scope: support.type.sys-types.c + - match: \b(pthread_attr_t|pthread_cond_t|pthread_condattr_t|pthread_mutex_t|pthread_mutexattr_t|pthread_once_t|pthread_rwlock_t|pthread_rwlockattr_t|pthread_t|pthread_key_t)\b + scope: support.type.pthread.c + - match: \b({{stdint}})\b + scope: support.type.stdint.c + - match: '\b({{microsoft_types}})\b' + scope: support.type.microsoft.c + - match: '\b({{windows_types}})\b' + scope: support.type.windows.c + - match: \b(AbsoluteTime|Boolean|Byte|ByteCount|ByteOffset|BytePtr|CompTimeValue|ConstLogicalAddress|ConstStrFileNameParam|ConstStringPtr|Duration|Fixed|FixedPtr|Float32|Float32Point|Float64|Float80|Float96|FourCharCode|Fract|FractPtr|Handle|ItemCount|LogicalAddress|OptionBits|OSErr|OSStatus|OSType|OSTypePtr|PhysicalAddress|ProcessSerialNumber|ProcessSerialNumberPtr|ProcHandle|Ptr|ResType|ResTypePtr|ShortFixed|ShortFixedPtr|SignedByte|SInt16|SInt32|SInt64|SInt8|Size|StrFileName|StringHandle|StringPtr|TimeBase|TimeRecord|TimeScale|TimeValue|TimeValue64|UInt16|UInt32|UInt64|UInt8|UniChar|UniCharCount|UniCharCountPtr|UniCharPtr|UnicodeScalarValue|UniversalProcHandle|UniversalProcPtr|UnsignedFixed|UnsignedFixedPtr|UnsignedWide|UTF16Char|UTF32Char|UTF8Char)\b + scope: support.type.mac-classic.c + + numbers: + # https://en.cppreference.com/w/c/language/floating_constant + + # decimal floats + - match: |- + (?x: + \b\d+ + (?: + (?: (\.) (?: \d+ {{dec_exponent}}? | {{dec_exponent}} | (?=[^.])) | {{dec_exponent}} ) + (?: ([fFlL])\b | ({{dec_suffix}})? ) | ([fF])\b + ) + | (\.) \d+ {{dec_exponent}}? (?: ([fFlL])\b | ({{dec_suffix}})? ) + ) + scope: constant.numeric.float.decimal.c + captures: + 1: punctuation.separator.decimal.c + 2: storage.type.numeric.c + 3: invalid.illegal.numeric.suffix.c + 4: storage.type.numeric.c + 5: punctuation.separator.decimal.c + 6: storage.type.numeric.c + 7: invalid.illegal.numeric.suffix.c + # hexadecimal float (C99) + - match: \b0[xX](?=[[:alnum:].]+?[pP]) + scope: punctuation.definition.numeric.base.c + push: + - meta_include_prototype: false + - meta_scope: constant.numeric.float.hexadecimal.c + - match: '{{hex_exponent}}\b' + pop: true + - match: \. + scope: punctuation.separator.decimal.c + - match: \H + scope: invalid.illegal.numeric.digit.c + + # https://en.cppreference.com/w/c/language/integer_constant + + # hexadecimal integer + - match: \b0[xX] + scope: punctuation.definition.numeric.base.c + push: + - meta_include_prototype: false + - meta_scope: constant.numeric.integer.hexadecimal.c + - include: hexadecimal-suffix + # octal integer + - match: \b0(?=\d) + scope: punctuation.definition.numeric.base.c + push: + - meta_include_prototype: false + - meta_scope: constant.numeric.integer.octal.c + - match: '[89]' + scope: invalid.illegal.numeric.digit.c + - include: decimal-suffix + # decimal integer + - match: \b\d+ + push: + - meta_include_prototype: false + - meta_scope: constant.numeric.integer.decimal.c + - include: decimal-suffix + + decimal-suffix: + - match: (?:{{integer_suffix}})?\b + scope: storage.type.numeric.c + pop: true + - match: '{{dec_suffix}}' + scope: invalid.illegal.numeric.suffix.c + pop: true + + hexadecimal-suffix: + - match: (?:{{integer_suffix}})?\b + scope: storage.type.numeric.c + pop: true + - match: '{{hex_suffix}}' + scope: invalid.illegal.numeric.suffix.c + pop: true + + operators: + - match: (?:\+\+|--) + scope: keyword.operator.arithmetic.c + - match: '->' + scope: punctuation.accessor.c + - match: \+\=|-\=|\*\=|/\=|%\=|&\=|\|\=|\^\=|>>\=|<<\= + scope: keyword.operator.assignment.augmented.c + - match: <<|>>|&&|\|\| + scope: keyword.operator.arithmetic.c + - match: <\=|>\=|\=\=|<|>|\!\= + scope: keyword.operator.comparison.c + - match: \+|\-|/|%|\||\^|~|! + scope: keyword.operator.arithmetic.c + # These two operator can be both arithmetic and pointer/address related + - match: \*|& + scope: keyword.operator.c + - match: \= + scope: keyword.operator.assignment.c + # Negative lookahead prevents match :: when included in C++ + - match: '\?|:(?!:)' + scope: keyword.operator.ternary.c + - match: '\.\.\.' + scope: keyword.operator.variadic.c + + access-illegal: + - match: \.\.(?!\.) + scope: invalid.illegal.syntax.c + + access: + - match: '(\.)({{identifier}})(?!\s*\()' + captures: + 1: punctuation.accessor.c + 2: variable.other.member.c + - include: access-illegal + - match: \.(?!\.) + scope: punctuation.accessor.c + + label: + - match: '^\s*((?!default){{identifier}})(:)(?!:)' + captures: + 1: entity.name.label.c + 2: punctuation.separator.c + + preprocessor-disabled: + - match: ^\s*(#\s*if(n?def)?)\b + captures: + 1: meta.preprocessor.c + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c + pop: true + - include: preprocessor-disabled + - include: pragma-mark + - include: pragma-mark + + preprocessor-line-continuation: + - match: '(\\)$\n' + captures: + 1: punctuation.separator.continuation.c + - match: \\(\s+?)$ + captures: + 1: invalid.illegal.space-after-continuation.c + + preprocessor-line-ending: + - match: $\n + pop: true + + # Comment handling in preprocessor directives are complicated by the fact + # that a single-line comment will normally consume the newline to prevent + # completions from being presented to the user. Additionally, a multi-line + # comment without a line continuation ends at the newline. + preprocessor-comments: + - match: /\* + scope: punctuation.definition.comment.c + push: + - meta_scope: comment.block.c + - match: '\\$\n' + scope: punctuation.separator.continuation.c + - match: \*/ + scope: punctuation.definition.comment.c + pop: true + - match: // + scope: punctuation.definition.comment.c + push: + - meta_scope: comment.line.double-slash.c + - match: '(\\)$\n' + captures: + 1: punctuation.separator.continuation.c + pop: true + - match: (?=\n) + pop: true + + pragma-mark: + - match: ^\s*((#\s*pragma\s+mark)\s+(.*)) + scope: meta.section.c + captures: + 1: meta.preprocessor.c + 2: keyword.control.import.pragma.c + 3: meta.toc-list.pragma-mark.c + + # Used by "inc" snippets to prevent double ##include + incomplete-inc: + - match: '^\s*(#i(nc?)?)\b\s*' + scope: meta.preprocessor.incomplete.c + + ############################################################################# + # The following are C-specific scopes that should not be reused. This is + # because they push into subcontexts and use variables that are C-specific. + ############################################################################# + + global: + - include: early-expressions + - match: '^\s*(?=\w+)' + push: global-modifier + - include: late-expressions + + statements: + - include: preprocessor-statements + - include: label + - include: expressions + + expressions: + - include: early-expressions + - include: late-expressions + + early-expressions: + - include: preprocessor-expressions + - include: comments + - include: case-default + - include: typedef + - include: keywords-parens + - include: keywords + - include: numbers + - include: operators + - include: strings + - include: parens + - include: brackets + - include: block + - include: variables + - include: constants + - include: access + - match: ',' + scope: punctuation.separator.c + - match: '\)|\}' + scope: invalid.illegal.stray-bracket-end.c + + late-expressions: + - include: modifiers-parens + - include: modifiers + - include: types + - include: function-call + - match: ';' + scope: punctuation.terminator.c + + ## C-specific contexts + + global-modifier: + - include: comments + - include: modifiers-parens + - include: modifiers + - match: '(?=\S)' + set: global-type + + global-type: + - include: comments + - match: \* + scope: keyword.operator.c + - match: |- + (?x: + ({{before_tag}}) + \s+ + (?= + {{identifier}} + (\s+{{identifier}}(?!\s*[{=;])|\s*\*+) + ) + ) + captures: + 1: storage.type.c + set: global-maybe-function + # The previous match handles return types of struct/enum/etc from a func, + # there this one exits the context to allow matching an actual struct/union + - match: '(?=\b({{before_tag}})\b)' + set: data-structures + - match: '(?=\b({{control_keywords}})\b)' + pop: true + - match: '(?=\s)' + set: global-maybe-function + # Allow a macro call + - match: '({{identifier}})\s*(\()(?=[^\)]+\))' + captures: + 1: variable.function.c + 2: meta.group.c punctuation.section.group.begin.c + push: + - meta_scope: meta.function-call.c + - meta_content_scope: meta.group.c + - match: '\)' + scope: meta.group.c punctuation.section.group.end.c + pop: true + - include: expressions + - match: (?={{identifier}}\s*\() + set: + - include: function-call + - match: '' + pop: true + - include: types + - match: '{{identifier}}' + - match: (?=\W) + pop: true + + global-maybe-function: + - include: comments + # Consume pointer info, macros and any type info that was offset by macros + - match: \* + scope: keyword.operator.c + - include: types + - include: modifiers-parens + - include: modifiers + # All uppercase identifier just before a newline is most likely a macro + - match: '[[:upper:][:digit:]_]+\s*$' + # Identifier that is not the function name - likely a macro + - match: '{{identifier}}(?!\s*(\(|$))' + # Real function definition + - match: '{{identifier}}(?=\s*(\(|$))' + scope: meta.function.c entity.name.function.c + set: function-definition-params + - match: '(?=\S)' + pop: true + + function-definition-params: + - meta_content_scope: meta.function.c + - include: comments + - match: '(?=\()' + set: + - match: \( + scope: meta.function.parameters.c meta.group.c punctuation.section.group.begin.c + set: + - meta_content_scope: meta.function.parameters.c meta.group.c + - match : \) + scope: punctuation.section.group.end.c + set: function-definition-continue + - match: '\bvoid\b' + scope: storage.type.c + - match: '{{identifier}}(?=\s*(\[|,|\)))' + scope: variable.parameter.c + - include: expressions + - include: preprocessor-line-continuation + - match: (?=\S) + pop: true + + function-definition-continue: + - meta_content_scope: meta.function.c + - include: comments + - match: '(?=;)' + pop: true + - match: \b(const|final|noexcept|override)\b + scope: storage.modifier.c + - match: '(?=\{)' + set: function-definition-body + - match: '(?=\S)' + pop: true + + function-definition-body: + - meta_content_scope: meta.function.c + - match: '\{' + scope: meta.block.c punctuation.section.block.begin.c + set: + - meta_content_scope: meta.function.c meta.block.c + - match: '\}' + scope: meta.function.c meta.block.c punctuation.section.block.end.c + pop: true + - match: (?=^\s*#\s*(elif|else|endif)\b) + pop: true + - match: '(?=({{before_tag}})([^(;]+$|.*\{))' + push: data-structures + - include: statements + + data-structures: + # Detect variable type definitions using struct/enum/union followed by a tag + - match: '\b({{before_tag}})(?=\s+{{identifier}}\s+{{identifier}}\s*[=;\[])' + scope: storage.type.c + - match: '\bstruct\b' + scope: storage.type.c + set: data-structures-struct-definition + - match: '\benum\b' + scope: storage.type.c + set: data-structures-enum-definition + - match: '\bunion\b' + scope: storage.type.c + set: data-structures-union-definition + - match: '(?=\S)' + pop: true + + data-structures-struct-definition: + - meta_scope: meta.struct.c + - include: data-structures-definition-common-begin + - include: data-structures-definition-common-macro + - match: '{{identifier}}(?=\s*;)' + scope: entity.name.struct.forward-decl.c + - match: '{{identifier}}' + scope: entity.name.struct.c + set: data-structures-struct-definition-after-name + - include: data-structures-struct-definition-block-start + - match: '(?=;)' + pop: true + + data-structures-struct-definition-after-name: + - meta_scope: meta.struct.c + - include: data-structures-definition-common-begin + - match: '(?=;)' + pop: true + - include: data-structures-struct-definition-block-start + + data-structures-struct-definition-block-start: + - match: '\{' + scope: meta.block.c punctuation.section.block.begin.c + set: + - meta_content_scope: meta.struct.c meta.block.c + - match: '\}' + scope: meta.struct.c meta.block.c punctuation.section.block.end.c + pop: true + - include: data-structures-body + + data-structures-enum-definition: + - meta_scope: meta.enum.c + - include: data-structures-definition-common-begin + - include: data-structures-definition-common-macro + - match: '{{identifier}}(?=\s*;)' + scope: entity.name.enum.forward-decl.c + - match: '{{identifier}}' + scope: entity.name.enum.c + set: data-structures-enum-definition-after-name + - include: data-structures-enum-definition-block-start + - match: '(?=;)' + pop: true + + data-structures-enum-definition-after-name: + - meta_scope: meta.enum.c + - include: data-structures-definition-common-begin + - match: '(?=;)' + pop: true + - include: data-structures-enum-definition-block-start + + data-structures-enum-definition-block-start: + - match: '\{' + scope: meta.block.c punctuation.section.block.begin.c + set: + - meta_content_scope: meta.enum.c meta.block.c + # Enums don't support methods so we have a simplified body + - match: '\}' + scope: meta.enum.c meta.block.c punctuation.section.block.end.c + pop: true + - include: data-structures-body + + data-structures-union-definition: + - meta_scope: meta.union.c + - include: data-structures-definition-common-begin + - include: data-structures-definition-common-macro + - match: '{{identifier}}(?=\s*;)' + scope: entity.name.union.forward-decl.c + - match: '{{identifier}}' + scope: entity.name.union.c + set: data-structures-union-definition-after-name + - include: data-structures-union-definition-block-start + - match: '(?=;)' + pop: true + + data-structures-union-definition-after-name: + - meta_scope: meta.union.c + - include: data-structures-definition-common-begin + - match: '(?=;)' + pop: true + - include: data-structures-union-definition-block-start + + data-structures-union-definition-block-start: + - match: '\{' + scope: meta.block.c punctuation.section.block.begin.c + set: + - meta_content_scope: meta.union.c meta.block.c + - match: '\}' + scope: meta.union.c meta.block.c punctuation.section.block.end.c + pop: true + - include: data-structures-body + + data-structures-definition-common-begin: + - include: comments + - match: '(?=\b(?:{{before_tag}}|{{control_keywords}})\b)' + pop: true + - include: modifiers-parens + - include: modifiers + + data-structures-definition-common-macro: + # Handle macros so they aren't matched as the class name + - match: '\b[[:upper:][:digit:]_]+\b(?!\s*($|\{))' + + data-structures-definition-common-end: + - match: '(?=;)' + pop: true + + data-structures-body: + - include: preprocessor-data-structures + - match: '(?={{before_tag}})' + push: data-structures + - include: expressions + + block: + - match: '\{' + scope: punctuation.section.block.begin.c + push: + - meta_scope: meta.block.c + - match: (?=^\s*#\s*(elif|else|endif)\b) + pop: true + - match: '\}' + scope: punctuation.section.block.end.c + pop: true + - include: statements + + parens: + - match: \( + scope: punctuation.section.group.begin.c + push: + - meta_scope: meta.group.c + - match: \) + scope: punctuation.section.group.end.c + pop: true + - include: expressions + + brackets: + - match: \[ + scope: punctuation.section.brackets.begin.c + push: + - meta_scope: meta.brackets.c + - match: \] + scope: punctuation.section.brackets.end.c + pop: true + - include: expressions + + case-default: + - match: '\b(default|case)\b' + scope: keyword.control.c + push: + - match: ':' + scope: punctuation.separator.c + pop: true + - include: expressions + + modifiers-parens: + - match: \b(__attribute__)\s*(\(\() + captures: + 1: storage.modifier.c + 2: meta.group.c punctuation.section.group.begin.c + push : + - meta_scope: meta.attribute.c + - meta_content_scope: meta.group.c + - include: parens + - include: strings + - match: \)\) + scope: meta.group.c punctuation.section.group.end.c + pop: true + - match: \b(__declspec)(\() + captures: + 1: storage.modifier.c + 2: meta.group.c punctuation.section.group.begin.c + push: + - meta_content_scope: meta.group.c + - match: '\)' + scope: meta.group.c punctuation.section.group.end.c + pop: true + - match: '\b(align|allocate|code_seg|deprecated|property|uuid)\b\s*(\()' + captures: + 1: storage.modifier.c + 2: meta.group.c punctuation.section.group.begin.c + push: + - meta_content_scope: meta.group.c + - match: '\)' + scope: meta.group.c punctuation.section.group.end.c + pop: true + - include: numbers + - include: strings + - match: \b(get|put)\b + scope: variable.parameter.c + - match: ',' + scope: punctuation.separator.c + - match: '=' + scope: keyword.operator.assignment.c + - match: '\b(appdomain|deprecated|dllimport|dllexport|jintrinsic|naked|noalias|noinline|noreturn|nothrow|novtable|process|restrict|safebuffers|selectany|thread)\b' + scope: constant.other.c + + keywords-parens: + - match: '\b(sizeof)\b\s*(\()' + captures: + 1: keyword.operator.word.c + 2: meta.group.c punctuation.section.group.begin.c + push: + - meta_content_scope: meta.group.c + - match: '\)' + scope: meta.group.c punctuation.section.group.end.c + pop: true + - include: expressions + + typedef: + - match: \btypedef\b + scope: storage.type.c + push: + - match: ({{identifier}})?\s*(?=;) + captures: + 1: entity.name.type.typedef.c + pop: true + - match: \b(struct)\s+({{identifier}}) + captures: + 1: storage.type.c + - include: expressions + + function-call: + - match: (?={{identifier}}\s*\() + push: + - meta_content_scope: meta.function-call.c + - include: c99 + - match: '{{identifier}}' + scope: variable.function.c + - match: '\(' + scope: meta.group.c punctuation.section.group.begin.c + set: + - meta_content_scope: meta.function-call.c meta.group.c + - match : \) + scope: meta.function-call.c meta.group.c punctuation.section.group.end.c + pop: true + - include: expressions + + ## Preprocessor for data-structures + + preprocessor-data-structures: + - include: preprocessor-rule-enabled-data-structures + - include: preprocessor-rule-disabled-data-structures + + preprocessor-rule-disabled-data-structures: + - match: ^\s*((#if)\s+(0))\b + captures: + 1: meta.preprocessor.c + 2: keyword.control.import.c + 3: constant.numeric.integer.decimal.c + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c keyword.control.import.else.c + push: + - match: (?=^\s*#\s*endif\b) + pop: true + - include: negated-block + - include: data-structures-body + - match: "" + push: + - meta_scope: comment.block.preprocessor.if-branch.c + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: preprocessor-disabled + + preprocessor-rule-enabled-data-structures: + - match: ^\s*((#if)\s+(0*1))\b + captures: + 1: meta.preprocessor.c + 2: keyword.control.import.c + 3: constant.numeric.integer.decimal.c + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c keyword.control.import.else.c + push: + - meta_content_scope: comment.block.preprocessor.else-branch.c + - match: (?=^\s*#\s*endif\b) + pop: true + - include: preprocessor-disabled + - match: "" + push: + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: negated-block + - include: data-structures-body + + ## Preprocessor for global + + preprocessor-global: + - include: preprocessor-rule-enabled-global + - include: preprocessor-rule-disabled-global + - include: preprocessor-rule-other-global + + preprocessor-statements: + - include: preprocessor-rule-enabled-statements + - include: preprocessor-rule-disabled-statements + - include: preprocessor-rule-other-statements + + preprocessor-expressions: + - include: incomplete-inc + - include: preprocessor-macro-define + - include: pragma-mark + - include: preprocessor-other + + preprocessor-rule-disabled-global: + - match: ^\s*((#if)\s+(0))\b + captures: + 1: meta.preprocessor.c + 2: keyword.control.import.c + 3: constant.numeric.integer.decimal.c + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c keyword.control.import.else.c + push: + - match: (?=^\s*#\s*endif\b) + pop: true + - include: preprocessor-global + - include: negated-block + - include: global + - match: "" + push: + - meta_scope: comment.block.preprocessor.if-branch.c + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: preprocessor-disabled + + preprocessor-rule-enabled-global: + - match: ^\s*((#if)\s+(0*1))\b + captures: + 1: meta.preprocessor.c + 2: keyword.control.import.c + 3: constant.numeric.integer.decimal.c + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c keyword.control.import.else.c + push: + - meta_content_scope: comment.block.preprocessor.else-branch.c + - match: (?=^\s*#\s*endif\b) + pop: true + - include: preprocessor-disabled + - match: "" + push: + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: preprocessor-global + - include: negated-block + - include: global + + preprocessor-rule-other-global: + - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b + captures: + 1: keyword.control.import.c + push: + - meta_scope: meta.preprocessor.c + - include: preprocessor-line-continuation + - 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. + - match: $\n + set: preprocessor-if-branch-global + + # These gymnastics here ensure that we are properly handling scope even + # when the preprocessor is used to create different scope beginnings, such + # as a different if/while condition + preprocessor-if-branch-global: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + pop: true + - match: (?=^\s*#\s*(elif|else)\b) + push: preprocessor-elif-else-branch-global + - match: \{ + scope: punctuation.section.block.begin.c + set: preprocessor-block-if-branch-global + - include: preprocessor-global + - include: negated-block + - include: global + + preprocessor-block-if-branch-global: + - meta_scope: meta.block.c + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + set: preprocessor-block-finish-global + - match: (?=^\s*#\s*(elif|else)\b) + push: preprocessor-elif-else-branch-global + - match: \} + scope: punctuation.section.block.end.c + set: preprocessor-if-branch-global + - include: statements + + preprocessor-block-finish-global: + - meta_scope: meta.block.c + - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + set: preprocessor-block-finish-if-branch-global + - match: \} + scope: punctuation.section.block.end.c + pop: true + - include: statements + + preprocessor-block-finish-if-branch-global: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + pop: true + - match: \} + scope: punctuation.section.block.end.c + set: preprocessor-if-branch-global + - include: statements + + preprocessor-elif-else-branch-global: + - match: (?=^\s*#\s*endif\b) + pop: true + - include: negated-block + - include: preprocessor-global + - include: global + + ## Preprocessor for statements + + preprocessor-rule-disabled-statements: + - match: ^\s*((#if)\s+(0))\b + captures: + 1: meta.preprocessor.c + 2: keyword.control.import.c + 3: constant.numeric.integer.decimal.c + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c keyword.control.import.else.c + push: + - match: (?=^\s*#\s*endif\b) + pop: true + - include: negated-block + - include: statements + - match: "" + push: + - meta_scope: comment.block.preprocessor.if-branch.c + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: preprocessor-disabled + + preprocessor-rule-enabled-statements: + - match: ^\s*((#if)\s+(0*1))\b + captures: + 1: meta.preprocessor.c + 2: keyword.control.import.c + 3: constant.numeric.integer.decimal.c + push: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + pop: true + - match: ^\s*(#\s*else)\b + captures: + 1: meta.preprocessor.c keyword.control.import.else.c + push: + - meta_content_scope: comment.block.preprocessor.else-branch.c + - match: (?=^\s*#\s*endif\b) + pop: true + - include: preprocessor-disabled + - match: "" + push: + - match: (?=^\s*#\s*(else|endif)\b) + pop: true + - include: negated-block + - include: statements + + preprocessor-rule-other-statements: + - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b + captures: + 1: keyword.control.import.c + push: + - meta_scope: meta.preprocessor.c + - include: preprocessor-line-continuation + - 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. + - match: $\n + set: preprocessor-if-branch-statements + + # These gymnastics here ensure that we are properly handling scope even + # when the preprocessor is used to create different scope beginnings, such + # as a different if/while condition + preprocessor-if-branch-statements: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + pop: true + - match: (?=^\s*#\s*(elif|else)\b) + push: preprocessor-elif-else-branch-statements + - match: \{ + scope: punctuation.section.block.begin.c + set: preprocessor-block-if-branch-statements + - match: (?=(?!{{non_func_keywords}}){{identifier}}\s*\() + set: preprocessor-if-branch-function-call + - include: negated-block + - include: statements + + preprocessor-if-branch-function-call: + - meta_content_scope: meta.function-call.c + - include: c99 + - match: '{{identifier}}' + scope: variable.function.c + - match: '\(' + scope: meta.group.c punctuation.section.group.begin.c + set: preprocessor-if-branch-function-call-arguments + + preprocessor-if-branch-function-call-arguments: + - meta_content_scope: meta.function-call.c meta.group.c + - 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 + captures: + 1: meta.preprocessor.c keyword.control.import.c + set: preprocessor-if-branch-statements + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + set: preprocessor-if-branch-function-call-arguments-finish + - include: expressions + + preprocessor-if-branch-function-call-arguments-finish: + - meta_content_scope: meta.function-call.c meta.group.c + - match: \) + scope: meta.function-call.c meta.group.c punctuation.section.group.end.c + pop: true + - include: expressions + + preprocessor-block-if-branch-statements: + - meta_scope: meta.block.c + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + set: preprocessor-block-finish-statements + - match: (?=^\s*#\s*(elif|else)\b) + push: preprocessor-elif-else-branch-statements + - match: \} + scope: punctuation.section.block.end.c + set: preprocessor-if-branch-statements + - include: statements + + preprocessor-block-finish-statements: + - meta_scope: meta.block.c + - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + set: preprocessor-block-finish-if-branch-statements + - match: \} + scope: punctuation.section.block.end.c + pop: true + - include: statements + + preprocessor-block-finish-if-branch-statements: + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + pop: true + - match: \} + scope: punctuation.section.block.end.c + set: preprocessor-if-branch-statements + - include: statements + + preprocessor-elif-else-branch-statements: + - match: (?=^\s*#\s*endif\b) + pop: true + - include: negated-block + - include: statements + + ## Preprocessor other + + negated-block: + - match: '\}' + scope: punctuation.section.block.end.c + push: + - match: '\{' + scope: punctuation.section.block.begin.c + pop: true + - match: (?=^\s*#\s*(elif|else|endif)\b) + pop: true + - include: statements + + preprocessor-macro-define: + - match: ^\s*(#\s*define)\b + captures: + 1: meta.preprocessor.macro.c keyword.control.import.define.c + push: + - meta_content_scope: meta.preprocessor.macro.c + - include: preprocessor-line-continuation + - include: preprocessor-line-ending + - include: preprocessor-comments + - match: '({{identifier}})(?=\()' + scope: entity.name.function.preprocessor.c + set: + - match: '\(' + scope: punctuation.section.group.begin.c + set: preprocessor-macro-params + - match: '{{identifier}}' + scope: entity.name.constant.preprocessor.c + set: preprocessor-macro-definition + + preprocessor-macro-params: + - meta_scope: meta.preprocessor.macro.parameters.c meta.group.c + - match: '{{identifier}}' + scope: variable.parameter.c + - match: \) + scope: punctuation.section.group.end.c + set: preprocessor-macro-definition + - match: ',' + scope: punctuation.separator.c + push: + - match: '{{identifier}}' + scope: variable.parameter.c + pop: true + - include: preprocessor-line-continuation + - include: preprocessor-comments + - match: '\.\.\.' + scope: keyword.operator.variadic.c + - match: '(?=\))' + pop: true + - match: (/\*).*(\*/) + scope: comment.block.c + captures: + 1: punctuation.definition.comment.c + 2: punctuation.definition.comment.c + - match: '\S+' + scope: invalid.illegal.unexpected-character.c + - include: preprocessor-line-continuation + - include: preprocessor-comments + - match: '\.\.\.' + scope: keyword.operator.variadic.c + - match: (/\*).*(\*/) + scope: comment.block.c + captures: + 1: punctuation.definition.comment.c + 2: punctuation.definition.comment.c + - match: $\n + scope: invalid.illegal.unexpected-end-of-line.c + + preprocessor-macro-definition: + - meta_content_scope: meta.preprocessor.macro.c + - include: preprocessor-line-continuation + - include: preprocessor-line-ending + - include: preprocessor-comments + # Don't define blocks in define statements + - match: '\{' + scope: punctuation.section.block.begin.c + - match: '\}' + scope: punctuation.section.block.end.c + - include: expressions + + preprocessor-practical-workarounds: + - include: preprocessor-convention-ignore-uppercase-ident-lines + - include: preprocessor-convention-ignore-uppercase-calls-without-semicolon + + preprocessor-convention-ignore-uppercase-ident-lines: + - match: ^(\s*{{macro_identifier}})+\s*$ + scope: meta.assumed-macro.c + push: + # It's possible that we are dealing with a function return type on its own line, and the + # name of the function is on the subsequent line. + - match: \s*({{identifier}})(?=\s*\() + captures: + 1: meta.function.c entity.name.function.c + set: function-definition-params + - match: ^ + pop: true + + + preprocessor-convention-ignore-uppercase-calls-without-semicolon: + - match: ^\s*({{macro_identifier}})\s*(\()(?=[^)]*\)\s*$) + captures: + 1: variable.function.assumed-macro.c + 2: punctuation.section.group.begin.c + push: + - meta_scope: meta.assumed-macro.c + - match: \) + scope: punctuation.section.group.end.c + pop: true + - include: expressions + + preprocessor-other: + - match: ^\s*(#\s*(?:if|ifdef|ifndef|elif|else|line|pragma|undef))\b + captures: + 1: keyword.control.import.c + push: + - meta_scope: meta.preprocessor.c + - include: preprocessor-line-continuation + - include: preprocessor-line-ending + - include: preprocessor-comments + - match: \bdefined\b + scope: keyword.control.c + - match: ^\s*(#\s*endif)\b + captures: + 1: meta.preprocessor.c keyword.control.import.c + - match: ^\s*(#\s*(?:error|warning))\b + captures: + 1: keyword.control.import.error.c + push: + - meta_scope: meta.preprocessor.diagnostic.c + - include: preprocessor-line-continuation + - include: preprocessor-line-ending + - include: preprocessor-comments + - include: strings + - match: '\S+' + scope: string.unquoted.c + - match: ^\s*(#\s*(?:include|include_next|import))\b + captures: + 1: keyword.control.import.include.c + push: + - meta_scope: meta.preprocessor.include.c + - include: preprocessor-line-continuation + - include: preprocessor-line-ending + - include: preprocessor-comments + - match: '"' + scope: punctuation.definition.string.begin.c + push: + - meta_scope: string.quoted.double.include.c + - match: '"' + scope: punctuation.definition.string.end.c + pop: true + - match: < + scope: punctuation.definition.string.begin.c + push: + - meta_scope: string.quoted.other.lt-gt.include.c + - match: ">" + scope: punctuation.definition.string.end.c + pop: true + - include: preprocessor-practical-workarounds diff --git a/syntaxes/C++/Comments (C++).tmPreferences b/syntaxes/C++/Comments (C++).tmPreferences @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Comments</string> + <key>scope</key> + <string>source.c, source.c++, source.objc, source.objc++</string> + <key>settings</key> + <dict> + <key>shellVariables</key> + <array> + <dict> + <key>name</key> + <string>TM_COMMENT_START</string> + <key>value</key> + <string>// </string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_START_2</string> + <key>value</key> + <string>/*</string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_END_2</string> + <key>value</key> + <string>*/</string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_DISABLE_INDENT_2</string> + <key>value</key> + <string>yes</string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_START_3</string> + <key>value</key> + <string>/// </string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_START_4</string> + <key>value</key> + <string>//! </string> + </dict> + </array> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/Completion Rules.tmPreferences b/syntaxes/C++/Completion Rules.tmPreferences @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>scope</key> + <string>source.c, source.c++, source.objc, source.objc++</string> + <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> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/Default.sublime-keymap b/syntaxes/C++/Default.sublime-keymap @@ -0,0 +1,41 @@ +[ + // Auto-pair less-than and greater-than symbols in include statements + { "keys": ["<"], "command": "insert_snippet", "args": {"contents": "<$0>"}, "context": + [ + { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, + { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }, + { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |\\)|]|\\}|>|$)", "match_all": true }, + { "key": "preceding_text", "operator": "not_regex_contains", "operand": "[\"a-zA-Z0-9_]$", "match_all": true }, + { "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.other - punctuation.definition.string.end", "match_all": true }, + { "key": "selector", "operator": "equal", "operand": "(source.c | source.c++) & meta.preprocessor.include" } + ] + }, + { "keys": ["<"], "command": "insert_snippet", "args": {"contents": "<${0:$SELECTION}>"}, "context": + [ + { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, + { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }, + { "key": "selector", "operator": "equal", "operand": "(source.c | source.c++) & meta.preprocessor.include" } + ] + }, + { "keys": [">"], "command": "move", "args": {"by": "characters", "forward": true}, "context": + [ + { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, + { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }, + { "key": "following_text", "operator": "regex_contains", "operand": "^>", "match_all": true }, + { "key": "selector", "operator": "not_equal", "operand": "punctuation.definition.string.begin", "match_all": true }, + { "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.other - punctuation.definition.string.end", "match_all": true }, + { "key": "selector", "operator": "equal", "operand": "(source.c | source.c++) & meta.preprocessor.include" } + ] + }, + { "keys": ["backspace"], "command": "run_macro_file", "args": {"file": "res://Packages/Default/Delete Left Right.sublime-macro"}, "context": + [ + { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, + { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }, + { "key": "preceding_text", "operator": "regex_contains", "operand": "<$", "match_all": true }, + { "key": "following_text", "operator": "regex_contains", "operand": "^>", "match_all": true }, + { "key": "selector", "operator": "not_equal", "operand": "punctuation.definition.string.begin", "match_all": true }, + { "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.other - punctuation.definition.string.end", "match_all": true }, + { "key": "selector", "operator": "equal", "operand": "(source.c | source.c++) & meta.preprocessor.include" } + ] + }, +] diff --git a/syntaxes/C++/Indentation Rules Comments.tmPreferences b/syntaxes/C++/Indentation Rules Comments.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Indentation Rules</string> + <key>scope</key> + <string><![CDATA[(source.c | source.c++ | source.objc | source.objc++) & comment.block]]></string> + <key>settings</key> + <dict> + <key>unIndentedLinePattern</key> + <string>.</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/Indentation Rules.tmPreferences b/syntaxes/C++/Indentation Rules.tmPreferences @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Indentation Rules</string> + <key>scope</key> + <string>source.c, source.c++, source.objc, source.objc++</string> + <key>settings</key> + <dict> + <key>decreaseIndentPattern</key> + <string>(?x) + ^ (.*\*/)? \s* \} .* $ + | ^ \s* (public|private|protected): \s* $ + | ^ \s* @(public|private|protected) \s* $ + </string> + <key>increaseIndentPattern</key> + <string>(?x) + ^ .* \{ [^}"']* $ + | ^ \s* (public|private|protected): \s* $ + | ^ \s* @(public|private|protected) \s* $ + </string> + + <key>bracketIndentNextLinePattern</key> + <string>(?x) + ^ \s* \b(if|while|else)\b [^;]* $ + | ^ \s* \b(for)\b .* $ + </string> + + <key>unIndentedLinePattern</key> + <string><![CDATA[^\s*((/\*|.*\*/|//|#|template\b.*?>(?!\(.*\))|@protocol|@interface(?!.*\{)|@implementation|@end).*)?$]]></string> + + <key>indentSquareBrackets</key> + <true/> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/Snippets/#ifndef-#define-#endif.sublime-snippet b/syntaxes/C++/Snippets/#ifndef-#define-#endif.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <description>#ifndef … #define … #endif</description> + <content><![CDATA[#ifndef ${1/([A-Za-z0-9_]+).*/$1/} +#define ${1:SYMBOL} ${2:value} +#endif]]></content> + <tabTrigger>def</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/#include-(#inc angle).sublime-snippet b/syntaxes/C++/Snippets/#include-(#inc angle).sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <description>#include &lt;…&gt;</description> + <content><![CDATA[include <${1:.h}>]]></content> + <tabTrigger>inc</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) &amp; meta.preprocessor.incomplete - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/#include-(#inc).sublime-snippet b/syntaxes/C++/Snippets/#include-(#inc).sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <description>#include "…"</description> + <content><![CDATA[include "${1:${TM_FILENAME/\..+$/.h/}}"]]></content> + <tabTrigger>inc</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) &amp; meta.preprocessor.incomplete - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/#include-(inc angle).sublime-snippet b/syntaxes/C++/Snippets/#include-(inc angle).sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <description>#include &lt;…&gt;</description> + <content><![CDATA[#include <${1:.h}>]]></content> + <tabTrigger>Inc</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - meta.preprocessor.incomplete - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/#include-(inc).sublime-snippet b/syntaxes/C++/Snippets/#include-(inc).sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <description>#include "…"</description> + <content><![CDATA[#include "${1:${TM_FILENAME/\..+$/.h/}}"]]></content> + <tabTrigger>inc</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - meta.preprocessor.incomplete - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/$1.begin()-$1.end()-(beginend).sublime-snippet b/syntaxes/C++/Snippets/$1.begin()-$1.end()-(beginend).sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <description>$1.begin(), $1.end()</description> + <content><![CDATA[${1:v}${1/^.*?(-)?(>)?$/(?2::(?1:>:.))/}begin(), ${1:v}${1/^.*?(-)?(>)?$/(?2::(?1:>:.))/}end()]]></content> + <tabTrigger>beginend</tabTrigger> + <scope>(source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/030-for-int-loop-(fori).sublime-snippet b/syntaxes/C++/Snippets/030-for-int-loop-(fori).sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <description>For Loop</description> + <content><![CDATA[for (int ${2:i} = 0; $2 < ${1:count}; ${3:++$2}) +{ + ${0:/* code */} +}]]></content> + <tabTrigger>for</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/Enumeration.sublime-snippet b/syntaxes/C++/Snippets/Enumeration.sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <description>Enumeration</description> + <content><![CDATA[enum ${1:name} +{ + $0 +};]]></content> + <tabTrigger>enum</tabTrigger> + <scope>(source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/Typedef.sublime-snippet b/syntaxes/C++/Snippets/Typedef.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <description>Typedef</description> + <content><![CDATA[typedef ${1:int} ${2:MyCustomType};]]></content> + <tabTrigger>td</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/class-..-(class).sublime-snippet b/syntaxes/C++/Snippets/class-..-(class).sublime-snippet @@ -0,0 +1,11 @@ +<snippet> + <content><![CDATA[class ${1:${TM_FILENAME/(.+)\..+|.*/$1/:name}} +{ +public: + ${1/(\w+).*/$1/}($2); + ~${1/(\w+).*/$1/}(); + $0 +};]]></content> + <tabTrigger>class</tabTrigger> + <scope>(source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/do...while-loop-(do).sublime-snippet b/syntaxes/C++/Snippets/do...while-loop-(do).sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <description>Do While Loop</description> + <content><![CDATA[do +{ + ${0:/* code */} +} while (${1:/* condition */});]]></content> + <tabTrigger>do</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/forv.sublime-snippet b/syntaxes/C++/Snippets/forv.sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <description>Vector For Loop</description> + <content><![CDATA[for (std::vector<$1>::iterator ${3:i} = $2.begin(); $3 != $2.end(); ++$3) +{ + $0 +}]]></content> + <tabTrigger>forv</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/fprintf.sublime-snippet b/syntaxes/C++/Snippets/fprintf.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <description>fprintf …</description> + <content><![CDATA[fprintf(${1:stderr}, "${2:%s}\\n"${2/([^%]|%%)*(%.)?.*/(?2:, :\);)/}$3${2/([^%]|%%)*(%.)?.*/(?2:\);)/}]]></content> + <tabTrigger>fprintf</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/if-..-(if).sublime-snippet b/syntaxes/C++/Snippets/if-..-(if).sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <description>If Condition</description> + <content><![CDATA[if (${1:/* condition */}) +{ + ${0:/* code */} +}]]></content> + <tabTrigger>if</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/main()-(int main).sublime-snippet b/syntaxes/C++/Snippets/main()-(int main).sublime-snippet @@ -0,0 +1,10 @@ +<snippet> + <description>main()</description> + <content><![CDATA[main(int argc, char const${TM_C_POINTER: *}argv[]) +{ + ${0:/* code */} + return 0; +}]]></content> + <tabTrigger>main</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) &amp; entity.name.function - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/main()-(main).sublime-snippet b/syntaxes/C++/Snippets/main()-(main).sublime-snippet @@ -0,0 +1,10 @@ +<snippet> + <description>main()</description> + <content><![CDATA[int main(int argc, char const${TM_C_POINTER: *}argv[]) +{ + ${0:/* code */} + return 0; +}]]></content> + <tabTrigger>main</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - entity.name.function - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/namespace-..-(namespace).sublime-snippet b/syntaxes/C++/Snippets/namespace-..-(namespace).sublime-snippet @@ -0,0 +1,10 @@ +<snippet> + <description>Namespace</description> + <content><![CDATA[namespace${1/.+/ /m}${1:${TM_FILENAME/^((.*?)\..*)?$/$2/:mine}} +{ + $0 +} +]]></content> + <tabTrigger>ns</tabTrigger> + <scope>(source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/printf-..-(printf).sublime-snippet b/syntaxes/C++/Snippets/printf-..-(printf).sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <description>printf …</description> + <content><![CDATA[printf("${1:%s}\\n"${1/([^%]|%%)*(%.)?.*/(?2:, :\);)/}$2${1/([^%]|%%)*(%.)?.*/(?2:\);)/}]]></content> + <tabTrigger>printf</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/read-file-(readF).sublime-snippet b/syntaxes/C++/Snippets/read-file-(readF).sublime-snippet @@ -0,0 +1,13 @@ +<snippet> + <description>Read File Into Vector</description> + <content><![CDATA[std::vector<char> v; +if (FILE${TM_C_POINTER: *}fp = fopen(${1:"filename"}, "r")) +{ + char buf[1024]; + while (size_t len = fread(buf, 1, sizeof(buf), fp)) + v.insert(v.end(), buf, buf + len); + fclose(fp); +}]]></content> + <tabTrigger>readfile</tabTrigger> + <scope>(source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/std-map-(map).sublime-snippet b/syntaxes/C++/Snippets/std-map-(map).sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <description>std::map</description> + <content><![CDATA[std::map<${1:key}, ${2:value}> map$0;]]></content> + <tabTrigger>map</tabTrigger> + <scope>(source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/std-vector-(v).sublime-snippet b/syntaxes/C++/Snippets/std-vector-(v).sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <description>std::vector</description> + <content><![CDATA[std::vector<${1:char}> v$0;]]></content> + <tabTrigger>vector</tabTrigger> + <scope>(source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/struct.sublime-snippet b/syntaxes/C++/Snippets/struct.sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <name>Struct</name> + <content><![CDATA[struct ${1:${TM_FILENAME/(.+)\..+|.*/$1/:name}} +{ + $0 +};]]></content> + <tabTrigger>struct</tabTrigger> + <scope>(source.c | source.objc | source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Snippets/template-typename-..-(template).sublime-snippet b/syntaxes/C++/Snippets/template-typename-..-(template).sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <description>template &lt;typename ${1:_InputIter}&gt;</description> + <content><![CDATA[template <typename ${1:_InputIter}>]]></content> + <tabTrigger>tp</tabTrigger> + <scope>(source.c++ | source.objc++) - meta.preprocessor.include - comment - string</scope> +</snippet> diff --git a/syntaxes/C++/Symbol Index Hide Ctors.tmPreferences b/syntaxes/C++/Symbol Index Hide Ctors.tmPreferences @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>scope</key> + <string><![CDATA[(source.c++ | source.objc++) & (meta.class | meta.struct | meta.union) & meta.block entity.name.function.constructor]]></string> + <key>settings</key> + <dict> + <key>showInIndexedSymbolList</key> + <integer>0</integer> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/Symbol Index Include Constants.tmPreferences b/syntaxes/C++/Symbol Index Include Constants.tmPreferences @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>scope</key> + <string><![CDATA[(source.c | source.objc | source.c++ | source.objc++) & entity.name.constant]]></string> + <key>settings</key> + <dict> + <key>showInIndexedSymbolList</key> + <integer>1</integer> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/Symbol Index.tmPreferences b/syntaxes/C++/Symbol Index.tmPreferences @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>scope</key> + <string>source.c++, source.objc++</string> + <key>settings</key> + <dict> + <key>symbolIndexTransformation</key> + <string>/.*::\s*([A-Za-z0-9_~]+)/$1/;</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/Symbol List - Indent Class Methods.tmPreferences b/syntaxes/C++/Symbol List - Indent Class Methods.tmPreferences @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>bundleUUID</key> + <string>4675A940-6227-11D9-BFB1-000D93589AF6</string> + <key>name</key> + <string>Symbol List: Indent Class Methods</string> + <key>scope</key> + <string><![CDATA[(source.c++ | source.objc++) & (meta.class | meta.struct | meta.union) & meta.block entity.name]]></string> + <key>settings</key> + <dict> + <key>symbolTransformation</key> + <string>s/^\s*/ /; # pad</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/Symbol List - Namespace Spacing.tmPreferences b/syntaxes/C++/Symbol List - Namespace Spacing.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List</string> + <key>scope</key> + <string><![CDATA[(source.c++ | source.objc++) & (entity.name|meta.function.local-symbol)]]></string> + <key>settings</key> + <dict> + <key>symbolTransformation</key> + <string>s/\s*::\s*/::/; # consistent spacing around ns separator</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/Symbol List - Prefix Banner Items.tmPreferences b/syntaxes/C++/Symbol List - Prefix Banner Items.tmPreferences @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List: Prefix Banner Items</string> + <key>scope</key> + <string>meta.toc-list.banner</string> + <key>settings</key> + <dict> + <key>symbolTransformation</key> + <string> + s/^\s+/# /; + s/^=+$/-/; + </string> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/Symbol List Hide Forward Decls.tmPreferences b/syntaxes/C++/Symbol List Hide Forward Decls.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>scope</key> + <string><![CDATA[(source.c | source.c++ | source.objc | source.objc++) & (entity.name.class.forward-decl | entity.name.struct.forward-decl | entity.name.enum.forward-decl | entity.name.union.forward-decl)]]></string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>0</integer> + <key>showInIndexedSymbolList</key> + <integer>0</integer> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/Symbol List.tmPreferences b/syntaxes/C++/Symbol List.tmPreferences @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List</string> + <key>scope</key> + <string><![CDATA[(source.c | source.c++ | source.objc | source.objc++) & (entity.name.class | entity.name.struct | entity.name.union | entity.name.enum)]]></string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>1</integer> + <key>showInIndexedSymbolList</key> + <integer>1</integer> + </dict> +</dict> +</plist> diff --git a/syntaxes/C++/syntax_test_accessor.c b/syntaxes/C++/syntax_test_accessor.c @@ -0,0 +1,35 @@ +// SYNTAX TEST "Packages/C++/C.sublime-syntax" + +typedef struct _X +{ + int a; + int b; +} X; + +int main() +{ + X x; + x. +// ^ punctuation.accessor +} + +int main() +{ + X x; + x.. +// ^^ invalid.illegal - punctuation.accessor +} + +int main() +{ + X x; + x... +// ^^^ keyword - punctuation.accessor +} + +int main() +{ + X* x = malloc(sizeof(X)); + x-> +// ^^ punctuation.accessor +} diff --git a/syntaxes/C++/syntax_test_accessor.cpp b/syntaxes/C++/syntax_test_accessor.cpp @@ -0,0 +1,68 @@ +// SYNTAX TEST "Packages/C++/C++.sublime-syntax" + +namespace N { + +class X +{ + public: + int a; + int b; +}; + +class Y : public X +{ + public: + int c; +} + +} // namespace N + +int main() +{ + N:: +// ^^ punctuation.accessor +} + +int main() +{ + N::X x; + x. +// ^ punctuation.accessor +} + +int main() +{ + N::X x; + x.. +// ^^ - punctuation.accessor +} + +int main() +{ + N::X x; + x... +// ^^^ keyword - punctuation.accessor +} + +int main() +{ + N::X* x = new X(); + x-> +// ^^ punctuation.accessor +} + +int main() +{ + N::Y y; + y.X:: +// ^ punctuation.accessor +// ^^ punctuation.accessor +} + +int main() +{ + N::Y* y = new Y(); + y->X:: +// ^^ punctuation.accessor +// ^^ punctuation.accessor +} diff --git a/syntaxes/C++/syntax_test_c.c b/syntaxes/C++/syntax_test_c.c @@ -0,0 +1,939 @@ +/* SYNTAX TEST "Packages/C++/C.sublime-syntax" */ + +int main(){ + int a=5,b=0; + while(a-->0)++b; + /* ^^ keyword.operator.arithmetic */ + /* ^ keyword.operator.comparison */ + /* ^ constant.numeric */ + /* ^^ keyword.operator.arithmetic */ +} + +enum Foo { kFoo, kBar }; +#define FOO Foo +enum FOO do_the_foo(void); +/* ^ entity.name.function */ +/* ^ storage.type */ + +#define APIC_CAPABILITY TheEnum +enum TheEnum { kFoo, kBar }; +static enum APIC_CAPABILITY apic_capabilities(void) { return kFoo; }; +/* ^ entity.name.function */ +/* ^ storage.type */ + +struct __declspec(dllimport) X {}; +/* ^ storage.modifier */ +/* ^ entity.name.struct */ + +struct __declspec(dllimport) baz X {}; +/* ^ storage.modifier */ +/* ^ entity.name.struct */ + +struct foo { +/* ^ entity.name.struct */ + union { +/* ^ storage.type */ + struct { +/* ^ storage.type */ + int a; +/* ^ storage.type */ + int b; +/* ^ storage.type */ + } + } +} + +#define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS /* comment block */ * sizeof(struct ptp_extts_event)) // comment line +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.macro */ +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group */ +/* ^^^^^^^^^^^^^^^^^^^^^^^^ meta.group meta.group */ +/* <- keyword.control.import.define */ +/* ^ entity.name.constant.preprocessor */ +/* ^ comment.block */ +/* ^ keyword.operator.word */ +/* ^ storage.type */ +/* ^ comment.line */ + +#pragma foo(bar, \ +"baz") +/*^^^^ meta.preprocessor */ + +#define MY_MACRO(a, b) +/*^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.macro */ +/* ^^^^^^ meta.preprocessor.macro.parameters */ +/* ^^^^^^^^ entity.name.function.preprocessor */ +/* ^ punctuation.section.group.end */ + +#define max(a, b, \ +/*^^^^^^^^^^^^^^^^^ meta.preprocessor.macro */ \ +/* ^^^^^^^^ meta.preprocessor.macro.parameters */ \ +/* <- keyword.control.import.define */ \ +/* ^ entity.name.function.preprocessor */ \ +/* ^ punctuation.section.group.begin */ \ +/* ^ variable.parameter */ \ +/* ^ punctuation.separator */ \ +/* */ \ +/* <- comment.block */ \ + c) ((a>b) ? (a>c?a:c) : (b>c?b:c)) + /* <- meta.preprocessor.macro meta.group variable.parameter */ + /* <- meta.preprocessor.macro meta.group punctuation.section.group.end */ + /* ^ keyword.operator.ternary */ + /* ^ keyword.operator.ternary */ + +#define PACKED __attribute__((aligned(1),packed)) +/* ^ entity.name.constant */ +/* ^ storage.modifier */ + +int i; +/* <- storage.type */ + +// The following example ensures that comments at the end of preprocessor +// directives don't mess with context transitions +int func() { +/* ^^^^^^^^ meta.function */ +/* ^^ meta.function.parameters */ +/* ^ meta.block punctuation.section.block.begin */ +/* ^ entity.name.function */ + #if( EXTAL == 40000 ) /* 40 MHz */ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function meta.block */ +/* ^ keyword.control.import */ + #define PLL_RFD_PHI1 10 // PLL0_PH1 = 40MHz +/* ^ keyword.control.import */ +/* ^^ constant.numeric */ +/* ^ comment.line */ + #endif +/* ^ keyword.control.import */ +} +/* <- meta.function meta.block punctuation.section.block.end */ + /* <- - meta.function meta.block */ + +int f(int x, \ + /* ^ punctuation.separator.continuation */ + int y); + +#define CONST0 16 // Comment +#define CONST1 8 +/* <- keyword.control.import.define */ +/* ^ entity.name.constant */ + +#if defined(VARIABLE) | // comment_line \ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor */ \ + defined(VAR2) +/*^^^^^^^^^^^^^^^ meta.preprocessor */ +/* ^ keyword.control */ +# error This is a long error message that need to \ +/* <- keyword.control.import */ \ +/* ^ string.unquoted */ \ + be splitted into two lines to prevent large lines. // comment +#error "Eplicitly quoted string wrapped, \ + ensuring that the string quoting stops at some point \ + " +#warning This is a short warning +/* <- keyword.control.import */ +#endif + /* <- keyword.control.import */ + +#define MACRO_WITH_CURLY_BRACE { +/* <- keyword.control.import.define */ +/* ^ entity.name.constant */ + +#define MACRO_WITH_CURLY_BRACE_2 } +/* <- keyword.control.import.define */ +/* ^ entity.name.constant */ + +bool still_C_code_here = true; +/* <- storage.type */ +/* ^ constant.language */ + +FOOBAR +hello() { + /* <- meta.function entity.name.function */ + return 0; +} + +EFIAPI +UserStructCompare ( + /* <- meta.function entity.name.function */ + IN CONST VOID *UserStruct1, + IN CONST VOID *UserStruct2 + ) +{ + const USER_STRUCT *CmpStruct1; + /* <- meta.block storage.modifier */ + + CmpStruct1 = UserStruct1; + return KeyCompare (&CmpStruct1->Key, UserStruct2); + /* <- meta.block keyword.control */ + /* ^ meta.block meta.function-call variable.function */ +} + +LIB_RESULT +foo() +/* <- meta.function entity.name.function */ +{ + return LIB_SUCCESS; +} + +LIB_RESULT bar() +/* ^ meta.function entity.name.function */ +{ + return LIB_SUCCESS; +} + +THIS_IS_REALLY_JUST_A_MACRO_AND_NOT_A_RETURN_TYPE +/* <- meta.assumed-macro */ + +int main() { +/* <- storage.type */ + /* ^ meta.function entity.name.function */ + return 0; +} + +#if 0 +#ifdef moo +/* <- - keyword.control */ +#endif +/* <- - keyword.control */ +#endif + +#if 0 +/* ^ constant.numeric */ +int disabled_func() { +/* ^ comment.block */ +} +#endif + +#if 1 +/* ^ constant.numeric */ +int enabled_func() {} +/* ^ entity.name.function */ +#else +int disabled_func() { +/* ^ comment.block */ +} +#endif + +#if 1 + int a = 1; + #if 0 +/* ^ constant.numeric */ + int b = 2; +/* ^ comment.block */ + #else + int c = 3; + #endif +#else + int d = 4; +/* ^ comment.block */ +#endif + +FOO +/* <- meta.assumed-macro */ +FOO; +/* <- - meta.assumed-macro */ +foo +/* <- - meta.assumed-macro */ +; // fix highlighting +/* <- punctuation.terminator */ +FOO() +/* <- meta.assumed-macro variable.function.assumed-macro */ +FOO(); +/* <- - meta.assumed-macro */ +foo() +/* <- - meta.assumed-macro */ +; // fix highlighting +/* <- punctuation.terminator */ + +struct X +{ + ENABLED("reason") + /* <- meta.assumed-macro variable.function.assumed-macro */ + int foo; + /* <- storage.type */ + + DISABLED("reason") + /* <- meta.assumed-macro variable.function.assumed-macro */ + float bar; + /* <- storage.type */ +}; + +/** + * +/* ^ comment.block.c punctuation.definition.comment.c */ + +///////////////////////////////////////////// +// Preprocessor branches starting blocks +///////////////////////////////////////////// + +#ifdef FOO +if (1) { +#elif BAR +if (2) { +# elif BAZ +if (3) { +# else +if (4) { +#endif + int bar = 1; +} +/* <- meta.block punctuation.section.block.end */ + /* <- - meta.block */ + +///////////////////////////////////////////// +// Typedefs +///////////////////////////////////////////// + +typedef int myint; +/* <- storage.type */ +/* ^ entity.name.type */ + +typedef struct mystruct { +/* <- storage.type */ +/* ^ - entity */ +} mystruct; +/* ^ entity.name.type */ + +///////////////////////////////////////////// +// Data structures and return values +///////////////////////////////////////////// + +struct point +/* ^ storage.type */ +/* ^ entity.name.struct */ +{ + int x; + int y; +} + +struct point2 { +/* ^ storage.type */ +/* ^ entity.name.struct */ + int x; + int y; +} + +int main(void) { +/* ^^^^ entity.name.function */ +/* ^^^^ storage.type */ +} + +struct point get_point() {} +/* ^^^^^^^^^^^^^^ meta.function */ +/* ^^ meta.function.parameters */ +/* ^^ meta.block */ +/* ^ punctuation.section.block.begin +/* ^ punctuation.section.block.end +/* ^ storage.type */ +/* ^ - entity.name.struct */ +/* ^ entity.name.function */ + +struct point **alloc_points(); +/* ^ storage.type */ +/* ^ - entity.name.struct */ +/* ^^ keyword.operator */ +/* ^ entity.name.function */ + +struct point* alloc_point(); +/* ^ entity.name.function - variable.function */ + +struct point FOO_API *alloc_point3(); +/* ^ entity.name.function - variable.function */ + +int main(void) +{ + struct UI_BoundingBox decorativeBox = {10, titleHeight-3, width-20, height-10}; +/* ^ - entity.name */ +/* ^ - entity.name */ +} + +struct foo MACRO { +/* ^ entity.name.struct */ +/* ^ - entity.name */ +} + +// Partially-typed +struct foo +/* ^ entity.name */ + +struct UI_MenuBoxData +/* <- storage.type */ +/* ^ entity.name.struct */ +{ + struct UI_BoundingBox position; +/* ^ - entity.name */ +/* ^ - entity.name */ + enum UI_BoxCharType borderType; +/* ^ - entity.name */ +/* ^ - entity.name */ + unsigned int paddingX; + unsigned int paddingY; + struct UI_ScrollBoxText boxContents[]; +/* ^ - entity.name */ +/* ^ - entity.name */ +}; + +///////////////////////////////////////////// +// Test preprocessor branching and C blocks +///////////////////////////////////////////// + +int foo(int val, float val2[]) +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function */ +/* ^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^^^ variable.parameter */ +/* ^ punctuation.separator */ +/* ^^^^ variable.parameter */ +/* ^^ meta.brackets */ +/* ^ punctuation.section.brackets.begin */ +/* ^ punctuation.section.brackets.end */ +{ +/* <- meta.function meta.block */ + myClass *result; + result->kk = func(val); +/* ^^ punctuation.accessor */ + if (result != 0) { +/* ^^ keyword.operator.comparison.c */ + return 0; +#if CROSS_SCOPE_MACRO + /* <- keyword.control.import */ + } else if (result > 0) { + return 1; +#endif + /* <- keyword.control.import */ + } +/* ^ meta.block meta.block punctuation.section.block.end */ +/* ^ - meta.block meta.block */ + +#ifdef FOO + /* <- keyword.control.import */ + int foobar +/* ^^^^^^ - entity.name.function */ + ; + + if (val == -1) { +/* ^^ keyword.control */ +/* ^ meta.block meta.block punctuation.section.block.begin */ +#else + /* <- keyword.control.import */ + if (val == -2) { +/* ^ meta.block meta.block punctuation.section.block.begin */ +#endif + /* <- keyword.control.import */ + val += 1; + } +/* ^ meta.block meta.block punctuation.section.block.end */ +/* ^ - meta.block meta.block */ + + return -1; +} +/* <- meta.function punctuation.section.block.end */ + /* <- - meta.function */ + +BOOL +GetTextMetrics( + HDC hdc, + LPTEXTMETRIC lptm + ) +{ +#ifdef UNICODE +/* <- keyword.control.import */ + return GetTextMetricsW( +/* ^ variable.function */ +#else +/* <- keyword.control.import */ + return GetTextMetricsA( +/* ^ variable.function */ +#endif +/* <- keyword.control.import */ + hdc, + lptm + ); +/* ^ meta.function-call */ +/* ^ - meta.function-call */ +} + /* <- - meta.function */ + /* <- - meta.block */ + +///////////////////////////////////////////// +// Matching various function definitions +///////////////////////////////////////////// + +const int foo = 1; +/* ^ - entity.name.function */ +int a; +/* ^ - entity.name.function */ + +int /* comment */ * myfunc +/* <- storage.type */ +/* ^ comment.block */ +/* ^ keyword.operator */ +/* ^^^^^^ meta.function entity.name.function */ +(int * a) +/*^^^^^^^ meta.function.parameters meta.group */ +/* <- punctuation.section.group.begin */ +/* ^ keyword.operator */ +/* ^ variable.parameter */ +/* ^ punctuation.section.group.end */ +{ +/* <- meta.function meta.block punctuation.section.block.begin */ +} + +MACRO1 +RETURN_TYPE +/* <- - entity.name.function */ +func_name() { +/* < entity.name.function */ +} + +MACRO1 void * MACRO2 myfuncname () { +/* ^^^^^^^^^^^^^^^ meta.function */ +/* ^^ meta.function.parameters */ +/* ^ meta.block punctuation.section.block.begin +/* ^ storage.type */ +/* ^ keyword.operator */ +/* ^ entity.name.function */ + + label: +/* ^ entity.name.label */ +/* ^ punctuation.separator */ + do { + break; + } while(true); + + switch (a) { + case 1: break; +/* ^ punctuation.separator */ + case 100 - 10: break; +/* ^ punctuation.separator */ + default: break; +/* ^ punctuation.separator */ + } + + struct Args { +/* ^ storage.type */ +/* ^ entity.name.struct */ + void* hello; + void* foobar; + }; + + struct Args args; +/* ^ storage.type */ +/* ^ - entity */ + +} + +static const uint32_t * const MACRO funcname(); +/* ^^^^^^^^^^ meta.function */ +/* ^^ meta.function.parameters */ +/* ^ storage.modifier */ +/* ^ storage.modifier */ +/* ^ support.type */ +/* ^ keyword.operator */ +/* ^ storage.modifier */ +/* ^ entity.name.function */ + +MACRO int +/* ^ storage.type */ +funcname2 +/* ^ entity.name.function */ +() +{ + int a[5]; +/* ^^^ meta.brackets */ +/* ^ punctuation.section.brackets.begin */ +/* ^ punctuation.section.brackets.end */ +} + +MACRO_CALL(int) macro_prefixed_func(){} +/*^^^^^^^^^^^^^ meta.function-call */ +/* ^^^^^ meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^ entity.name.function */ + +int* return_type_pointer_no_space(){} +/* ^ entity.name.function */ + +// Make sure there isn't an incorrect match here since this is not a valid +// function definition +int32 +/* <- - entity.name.function */ +() {} + +_declspec(deprecated("bla")) void func2(int) {} +/* <- meta.function-call variable.function */ +/* ^ entity.name.function */ +__declspec(deprecated("bla")) void func2(int) {} +/* <- storage.modifier - variable.function */ +/* ^ storage.modifier - variable.function */ +/* ^ string.quoted.double punctuation */ +/* ^ string.quoted.double - punctuation */ +/* ^ string.quoted.double - punctuation */ +/* ^ string.quoted.double punctuation */ +/* ^^ punctuation - invalid */ +/* ^ entity.name.function */ +__notdeclspec(deprecated("bla")) void func2(int) {} +/* <- meta.function-call variable.function */ +/* ^ entity.name.function */ + +///////////////////////////////////////////// +// Test function call in function parameters +///////////////////////////////////////////// + +static string foo(bar() + ';'); +/* ^^^^^^^^^^^^^^^^ meta.function */ +/* ^^^^^^^^^^^^^ meta.function.parameters */ +/* ^^^ entity.name.function */ +/* ^^^^^ meta.function-call */ +/* ^^^ variable.function */ +/* ^^^ string */ +/* ^ -string */ + +func_call(foo +/*^^^^^^^^^^^ meta.function-call */ +/* ^^^^ meta.group */ +/* ^ punctuation.section.group.begin */ +); +/* <- meta.function-call meta.group punctuation.section.group.end */ + +///////////////////////////////////////////// +// Invalid +///////////////////////////////////////////// +) +/* <- invalid.illegal.stray-bracket-end */ +} +/* <- invalid.illegal.stray-bracket-end */ + +///////////////////////////////////////////// +// Includes +///////////////////////////////////////////// + +#include "foobar.h" +/* <- keyword.control.import.include */ +/* ^ punctuation.definition.string.begin */ +/* ^^^^^^^^ string.quoted.double.include */ +/* ^ punctuation.definition.string.end */ + +#include <cstdlib> +/* <- keyword.control.import.include */ +/* ^ punctuation.definition.string.begin */ +/* ^^^^^^^ string.quoted.other.lt-gt.include */ +/* ^ punctuation.definition.string.end */ + +#ifdef _GLIBCXX_INCLUDE_NEXT_C_HEADERS +#include_next <math.h> +/* <- keyword.control.import.include */ +/* ^ punctuation.definition.string.begin */ +/* ^^^^^^ string.quoted.other.lt-gt.include */ +/* ^ punctuation.definition.string.end */ +#endif + +#include<iostream> +/* <- keyword.control.import.include */ +/* ^ punctuation.definition.string.begin */ +/* ^^^^^^^^ string.quoted.other.lt-gt.include */ +/* ^ punctuation.definition.string.end */ + +///////////////////////////////////////////// +// Numeric Constants +///////////////////////////////////////////// + +dec0 = 0; +/* ^ constant.numeric.integer.decimal */ +/* ^ punctuation.terminator - constant */ +dec1 = 1234567890; +/* ^^^^^^^^^^ constant.numeric.integer.decimal */ +/* ^ punctuation.terminator - constant */ + +dec2 = 1234567890f; +/* ^^^^^^^^^^^ constant.numeric.float.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +dec3 = 1234567890L; +/* ^^^^^^^^^^^ constant.numeric.integer.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +dec4 = 1234567890ul; +/* ^^^^^^^^^^^^ constant.numeric.integer.decimal */ +/* ^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +dec5 = 1234567890Lu; +/* ^^^^^^^^^^^^ constant.numeric.integer.decimal */ +/* ^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +dec6 = 1234567890LLU; +/* ^^^^^^^^^^^^^ constant.numeric.integer.decimal */ +/* ^^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +dec7 = 1234567890uLL; +/* ^^^^^^^^^^^^^ constant.numeric.integer.decimal */ +/* ^^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +dec8 = 1'234_567'890s0f; +/* ^ constant.numeric.integer.decimal */ +/* ^^^^^^^^^ string.quoted.single */ +/* ^^^^^^ constant.numeric.integer.decimal */ +/* ^^^ invalid.illegal.numeric.suffix */ +/* ^ punctuation.terminator - constant */ + +oct1 = 01234567; +/* ^^^^^^^^ constant.numeric.integer.octal */ +/* ^ punctuation.definition.numeric.base */ +/* ^ punctuation.terminator - constant */ + +oct2 = 01234567L; +/* ^^^^^^^^ constant.numeric.integer.octal */ +/* ^ punctuation.definition.numeric.base */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +oct3 = 01234567LL; +/* ^^^^^^^^^^ constant.numeric.integer.octal */ +/* ^ punctuation.definition.numeric.base */ +/* ^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +oct4 = 01234567ulL; +/* ^^^^^^^^^^^ constant.numeric.integer.octal */ +/* ^ punctuation.definition.numeric.base */ +/* ^^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +oct2 = 01284967Z0L; +/* ^^^^^^^^^^^ constant.numeric.integer.octal */ +/* ^ punctuation.definition.numeric.base */ +/* ^ invalid.illegal.numeric.digit */ +/* ^ invalid.illegal.numeric.digit */ +/* ^^^ invalid.illegal.numeric.suffix */ +/* ^ punctuation.terminator - constant */ + +hex1 = 0x0+0xFL+0xaull+0xallu+0xfu+0x'f'12_4uz; +/* ^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ storage.type.numeric */ +/* ^^^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^^^ storage.type.numeric */ +/* ^^^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^^^ storage.type.numeric */ +/* ^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ storage.type.numeric */ +/* ^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^^^ string.quoted.single */ +/* ^^^^^^ constant.numeric.integer.decimal */ +/* ^^^^ invalid.illegal.numeric.suffix */ +/* ^ punctuation.terminator - constant */ + +hex2 = 0xc1.01AbFp-1; +/* ^^^^^^^^^^^^^ constant.numeric.float.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ punctuation.separator.decimal */ +/* ^ punctuation.terminator - constant */ + +f = 1.1+1.1e1+1.1e-1+1.1f+1.1e1f+1.1e-1f+1.1L+1.1e1L+1.1e-1L; +/* ^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +f = 1.e1+1.e-1+1.e1f+1.e-1f+1.e1L+1.e-1L; +/* ^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +f = 1.+1.f+1.L+1..; +/* ^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^ constant.numeric.integer.decimal */ +/* ^^ invalid.illegal.syntax */ +/* ^ punctuation.terminator - constant */ + +f = 1e1+1e1f+1e1L; +/* ^^^ constant.numeric.float.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^ constant.numeric.float.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^ constant.numeric.float.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +f = .1+.1e1+.1e-1+.1f+.1e1f+.1e-1f+.1L+.1e1L+.1e-1L; +/* ^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +f = 1.0suff+1.suff*.0suff/{1suff} +/* ^^^ constant.numeric.float.decimal - invalid */ +/* ^^^^ constant.numeric.float.decimal invalid.illegal.numeric.suffix */ +/* ^ keyword.operator.arithmetic */ +/* ^^ constant.numeric.float.decimal - invalid */ +/* ^^^^ constant.numeric.float.decimal invalid.illegal.numeric.suffix */ +/* ^ keyword.operator */ +/* ^^ constant.numeric.float.decimal - invalid */ +/* ^^^^ constant.numeric.float.decimal invalid.illegal.numeric.suffix */ +/* ^ keyword.operator.arithmetic */ +/* ^ punctuation.section.block.begin */ +/* ^ constant.numeric.integer.decimal - invalid */ +/* ^^^^ constant.numeric.integer.decimal invalid.illegal.numeric.suffix */ +/* ^ punctuation.section.block.end */ + +scanf("%ms %as %*[, ]", &buf); +/* ^^^ constant.other.placeholder */ +/* ^^^ constant.other.placeholder */ +/* ^^^^^^ constant.other.placeholder */ + +"foo % baz" +/* ^ - invalid */ + + +///////////////////////////////////////////// +// Control Keywords +///////////////////////////////////////////// + +int control_keywords() +{ + if (x < 5) + /* <- keyword.control */ + {} + else + /* <- keyword.control */ + {} + + switch (x) + /* <- keyword.control */ + { + case 1: + /* <- keyword.control */ + break; + /* <- keyword.control.flow.break */ + default: + /* <- keyword.control */ + break; + /* <- keyword.control.flow.break */ + } + + do + /* <- keyword.control */ + { + if (y == 3) + continue; + /* <- keyword.control.flow.continue */ + } while (y < x); + /*^ keyword.control */ + + switch (a) { + case 1: break; + /* ^ punctuation.separator */ + case 100 - 10: break; + /* ^ punctuation.separator */ + default: break; + /* ^ punctuation.separator */ + } + + goto label; + /* <- keyword.control.flow.goto */ + +label: + + return 123; + /* <- keyword.control.flow.return */ +} diff --git a/syntaxes/C++/syntax_test_cpp.cpp b/syntaxes/C++/syntax_test_cpp.cpp @@ -0,0 +1,2636 @@ +/* SYNTAX TEST "Packages/C++/C++.sublime-syntax" */ + +int main(){ + int a=5,b=0; + while(a-->0)++b; + /* ^^ keyword.operator.arithmetic */ + /* ^ keyword.operator.comparison */ + /* ^ constant.numeric */ + /* ^^ keyword.operator.arithmetic */ +} + +///////////////////////////////////////////// +// Preprocessor +///////////////////////////////////////////// + +#ifndef IGUARD_ + /* <- keyword.control.import */ +#define IGUARD_ + /* <- keyword.control.import.define */ +struct foo* alloc_foo(); +/* <- storage.type */ + /* <- - entity.name.type */ + /* <- entity.name.function */ +#endif + /* <- keyword.control.import */ + +// The following example ensures that comments at the end of preprocessor +// directives don't mess with context transitions +int func() { +/* ^ entity.name.function */ + #if( EXTAL == 40000 ) /* 40 MHz */ +/* ^ keyword.control.import */ + #define PLL_RFD_PHI1 10 // PLL0_PH1 = 40MHz +/* ^ keyword.control.import */ +/* ^^ constant.numeric */ +/* ^ comment.line */ + #endif +/* ^ keyword.control.import */ +} +/* <- meta.function meta.block punctuation.section.block.end */ + /* <- - meta.function meta.block */ + +int f(int x, \ + /* ^ punctuation.separator.continuation */ + int y); + +int g(int x = 5 \ + /* ^ punctuation.separator.continuation */ + , int y); + +#define MACRO_WITH_CURLY_BRACE { +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.macro */ +/* <- keyword.control.import.define */ +/* ^ entity.name.constant */ + +#define MACRO_WITH_CURLY_BRACE_2 } +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.macro */ +/* <- keyword.control.import.define */ +/* ^ entity.name.constant */ + +FOOBAR +hello() { + /* <- meta.function entity.name.function */ + return 0; +} + +EFIAPI +UserStructCompare ( + /* <- meta.function entity.name.function */ + IN CONST VOID *UserStruct1, + IN CONST VOID *UserStruct2 + ) +{ + const USER_STRUCT *CmpStruct1; + /* <- meta.block storage.modifier */ + + CmpStruct1 = UserStruct1; + return KeyCompare (&CmpStruct1->Key, UserStruct2); + /* <- meta.block keyword.control */ + /* ^ meta.block meta.function-call variable.function */ +} + +LIB_RESULT +foo() +/* <- meta.function entity.name.function */ +{ + return LIB_SUCCESS; +} + +LIB_RESULT bar() +/* ^ meta.function entity.name.function */ +{ + return LIB_SUCCESS; +} + +THIS_IS_REALLY_JUST_A_MACRO_AND_NOT_A_RETURN_TYPE +/* <- meta.assumed-macro */ + +int main() { +/* <- storage.type */ + /* ^ meta.function entity.name.function */ + return 0; +} + +// This is a method/function with the return type on a separate line and so should not be a +// constructor. +FOOLIB_RESULT +some_namespace::some_function(int a_parameter, double another_parameter) { + /* <- meta.function meta.toc-list.full-identifier */ + /* ^ entity.name.function - entity.name.function.constructor */ + return FOOLIB_SUCCESS; +} + +#pragma foo(bar, \ +"baz", \ +1) +/* <- meta.preprocessor */ + +#define MY_MACRO(a, b) +/*^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.macro */ +/* ^^^^^^ meta.preprocessor.macro.parameters */ +/* ^^^^^^^^ entity.name.function.preprocessor */ +/* ^ punctuation.section.group.end */ + +#define max(a, b, \ +/*^^^^^^^^^^^^^^^^^ meta.preprocessor.macro */ \ +/* ^^^^^^^^ meta.preprocessor.macro.parameters */ \ +/* <- keyword.control.import.define */ \ +/* ^ entity.name.function.preprocessor */ \ +/* ^ punctuation.section.group.begin */ \ +/* ^ variable.parameter */ \ +/* ^ punctuation.separator */ \ +/* */ \ +/* <- comment.block */ \ + c) ((a>b) ? (a>c?a:c) : (b>c?b:c)) + /* <- meta.preprocessor.macro meta.group variable.parameter */ + /* <- meta.preprocessor.macro meta.group punctuation.section.group.end */ + /* ^ keyword.operator.ternary */ + /* ^ keyword.operator.ternary */ + +#if 0 +#ifdef moo +/* <- - keyword.control */ +#endif +/* <- - keyword.control */ +#endif + +FOO() +/* <- meta.assumed-macro variable.function.assumed-macro */ +FOO +/* <- meta.assumed-macro */ + +struct FOO1 FOO2 FOO3 Test { + /* ^ meta.struct meta.assumed-macro */ + /* ^ meta.struct meta.assumed-macro */ + /* ^ meta.struct meta.assumed-macro */ + Test(); + Test() noexcept; + Test() final; + Test() noexcept final; + ~Test(); + ~Test() noexcept; + ~Test() override noexcept; + virtual ~Test(); + virtual ~Test() noexcept; + virtual ~Test() override noexcept; + DLL_API Test(); + /* <- meta.assumed-macro */ + /* ^ meta.method.constructor */ + DLL_API Test() noexcept; + /* <- meta.assumed-macro */ + /* ^ meta.method.constructor */ + /* ^ storage.modifier */ + DLL_API Test() final; + /* <- meta.assumed-macro */ + /* ^ meta.method.constructor */ + /* ^ storage.modifier */ + DLL_API Test() noexcept final; + /* <- meta.assumed-macro */ + /* ^ meta.method.constructor */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ + DLL_API ~Test(); + /* <- meta.assumed-macro */ + /* ^ meta.method.destructor */ + DLL_API ~Test() noexcept; + /* <- meta.assumed-macro */ + /* ^ meta.method.destructor */ + /* ^ storage.modifier */ + DLL_API ~Test() override noexcept; + /* <- meta.assumed-macro */ + /* ^ meta.method.destructor */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ + DLL_API virtual ~Test(); + /* <- meta.assumed-macro */ + /* ^ storage.modifier */ + /* ^ meta.method.destructor */ + DLL_API virtual ~Test() noexcept; + /* <- meta.assumed-macro */ + /* ^ storage.modifier */ + /* ^ meta.method.destructor */ + /* ^ storage.modifier */ + DLL_API virtual ~Test() override noexcept; + /* <- meta.assumed-macro */ + /* ^ storage.modifier */ + /* ^ meta.method.destructor */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ +} + +struct X { + X(); + /* <- meta.group */ + /*^ meta.group - meta.group meta.group */ +}; + +#define DEPRECATED(msg) [[deprecated(msg)]] + +struct Test { + DEPRECATED("bla") + /* <- meta.assumed-macro variable.function.assumed-macro */ + bool foo (bool run=true) {} + /* ^ entity.name.function */ +}; + +namespace Test { + DEPRECATED("bla") + /* <- meta.assumed-macro variable.function.assumed-macro */ + bool foo (bool run=true) {} + /* ^ entity.name.function */ +} + +struct Test { +DEPRECATED("bla") +/* <- meta.assumed-macro variable.function.assumed-macro */ +bool foo (bool run=true) {} +/* ^ entity.name.function */ +}; + +///////////////////////////////////////////// +// Strings +///////////////////////////////////////////// + +char str1[] = "abc"; +/* ^ punctuation.definition.string.begin */ +/* ^ string.quoted.double */ +/* ^ punctuation.definition.string.end */ + +char str2[] = u8"abc"; +/* ^ storage.type.string */ +/* ^ punctuation.definition.string.begin */ +/* ^ string.quoted.double */ + +char16_t str3[] = u"abc"; +/* ^ storage.type.string */ +/* ^ punctuation.definition.string.begin */ +/* ^ string.quoted.double */ + +char32_t str4[] = U"abc"; +/* ^ storage.type.string */ +/* ^ punctuation.definition.string.begin */ +/* ^ string.quoted.double */ + +wchar_t str5[] = L"abc"; +/* ^ storage.type.string */ +/* ^ punctuation.definition.string.begin */ +/* ^ string.quoted.double */ + +char str6[] = "\a|\b|\e|\f|\n|\r|\t|\v|\'|\"|\?"; +/* ^^ constant.character.escape */ +/* ^^ constant.character.escape */ +/* ^^ constant.character.escape */ +/* ^^ constant.character.escape */ +/* ^^ constant.character.escape */ +/* ^^ constant.character.escape */ +/* ^^ constant.character.escape */ +/* ^^ constant.character.escape */ +/* ^^ constant.character.escape */ +/* ^^ constant.character.escape */ +/* ^^ constant.character.escape */ + +char str7[] = "\0|\012"; +/* ^^ constant.character.escape */ +/* ^^^^ constant.character.escape */ + +char str8[] = "\x0a|\x41|\xA|\x000065"; +/* ^^^^ constant.character.escape */ +/* ^^^^ constant.character.escape */ +/* ^^^ constant.character.escape */ +/* ^^^^^^^^ constant.character.escape */ + +char16_t str9[] = u"\u0063"; +/* ^^^^^^ constant.character.escape */ + +char32_t str10[] = U"\U00000063"; +/* ^^^^^^^^^^ constant.character.escape */ + +char str11[] = "\q"; +/* ^^ invalid.illegal.unknown-escape */ + +scanf("%ms %as %*[, ]", &buf); +/* ^^^ constant.other.placeholder */ +/* ^^^ constant.other.placeholder */ +/* ^^^^^^ constant.other.placeholder */ + +"foo % baz" +/* ^ - invalid */ + +char rawStr1[] = R"("This is a raw string")"; +/* ^ storage.type.string */ +/* ^ punctuation.definition.string.begin */ +/* ^ string.quoted.double */ +/* ^ punctuation.definition.string.end */ + +char rawStr2[] = R"A*!34( )" )A*!34"; +/* ^ storage.type.string */ +/* ^ punctuation.definition.string.begin */ +/* ^ punctuation.definition.string.begin */ +/* ^ string.quoted.double */ +/* ^ punctuation.definition.string.end */ +/* ^ punctuation.definition.string.end */ + +const char IncludeRegexPattern[] = + R"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))"; +/* ^ storage.type.string */ +/* ^ punctuation.definition.string.begin */ +/* ^^ - invalid */ +/* ^^ - invalid */ +/* ^ punctuation.definition.string.end */ + +foo.f<5> /* foo */ (); + +///////////////////////////////////////////// +// Storage Types +///////////////////////////////////////////// + +void* ptr; +/* <- storage.type */ + +bool b; +/* <- storage.type */ + +char ch; +/* <- storage.type */ + +char16_t ch16; +/* <- storage.type */ + +char32_t ch32; +/* <- storage.type */ + +wchar_t wch; +/* <- storage.type */ + +unsigned int ui; +/* <- storage.type */ +/* ^ storage.type */ + +signed long l; +/* <- storage.type */ +/* ^ storage.type */ + +short s; +/* <- storage.type */ + +auto a = 2; +/* <- storage.type */ + +decltype(s) dt; +/* <- storage.type */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ + +float f; +/* <- storage.type */ + +double d; +/* <- storage.type */ + +typedef int my_int; +/* <- storage.type */ +/* ^ entity.name.type */ + +typedef struct Books { +/* ^ storage.type */ +/* ^ - entity.name.type */ + char title[50]; + int book_id; +} Book; +/*^ entity.name.type */ + +using Alias = Foo; +/* <- keyword.control */ +/* ^^^^^ entity.name.type.using */ + +using Alias + = NewLineFoo; +/*^ - entity.name */ + +template <typename T> +using TemplateAlias = Foo<T>; +/* ^^^^^^^^^^^^^ entity.name.type.using */ + +using std::cout; +/* <- keyword.control */ +/* ^ - entity.name */ + +using std:: + cout; +/*^ - entity.name */ + +class MyClass : public SuperClass +{ + using This = MyClass; +/* ^ keyword.control */ +/* ^^^^ entity.name.type.using */ + + using MyInt +/* ^ keyword.control */ + = int32_t; + + using SuperClass::SuperClass; +/* ^ keyword.control */ +/* ^ - entity.name */ +}; + +class MyClass : public CrtpClass<MyClass> +{ + using typename CrtpClass<MyClass>::PointerType; +/* ^ keyword.control */ +/* ^ storage.modifier */ + using CrtpClass< +/* ^ keyword.control */ + MyClass>::method; +}; + +typedef struct Books Book; +/* ^ - entity.name.type.struct */ +/* ^ entity.name.type.typedef */ + +template class MyStack<int, 6>; +/* <- storage.type.template */ +/* ^ punctuation.section.generic */ +/* ^ storage.type */ +/* ^ constant.numeric */ +/* ^ punctuation.section.generic */ + +template<class typeId, int N> class tupleTmpl; +/* <- storage.type.template */ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.template */ +/* ^ punctuation.section.generic.begin */ +/* ^ storage.type */ +/* ^ storage.type */ +/* ^ punctuation.section.generic.end */ + +template<typename First = U<V>, typename... Rest> class tupleVariadic; +/* <- storage.type.template */ +/* ^ punctuation.section.generic.begin */ +/* ^ storage.type */ +/* ^ punctuation.section.generic.begin */ +/* ^ punctuation.section.generic.end */ +/* ^ punctuation.separator */ +/* ^^^ keyword.operator.variadic */ +/* ^ punctuation.section.generic.end */ + +template<typename T...> void SomeClass<T...>::function(); +/* ^^^ keyword.operator.variadic */ +/* ^^^^^^^^ entity.name.function */ + +template<typename Foo> inline struct Foo* baz() +/* ^^^^^^ storage.modifier */ +/* ^ - entity.name */ +/* ^^^ meta.function entity.name.function */ +{} + +template<typename A, typename B> +void classname<A, B>::methodName() { +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function */ +/* ^ punctuation.section.generic.begin */ +/* ^ punctuation.section.generic.end */ +/* ^^ punctuation.accessor */ +/* ^^^^^^^^^^ entity.name.function */ +} + +template<typename C> +void funcName<C>() { +/* ^^^^^^^^^^^^^^^ meta.function */ +/* ^^^^^^^^ entity.name.function */ +/* ^ punctuation.section.generic.begin */ +/* ^ punctuation.section.generic.end */ +} +bool A::operator<(const A& a) { return false; } +/* ^ storage.type */ +/* ^^^^^^^^^ meta.function meta.toc-list.full-identifier */ +/* ^^^^^^^^^ entity.name.function */ +/* ^ meta.function.parameters punctuation.section.group.begin */ +template <class T> bool A<T>::operator<(const A& a) { return false; } +/* ^ storage.type.template */ +/* ^ punctuation.section.generic.begin */ +/* ^ punctuation.section.generic.end */ +/* ^^^^^^^^^^^^^^^ meta.function meta.toc-list.full-identifier */ +/* ^^^^^^^^^ entity.name.function */ +/* ^ meta.function.parameters meta.group punctuation.section.group.begin */ +template <typename Foo> +SomeType<OtherType> A<Foo>::foobar(YetAnotherType&& asRValue) {} +/* ^^^^^^^^^^^^^^ meta.function meta.toc-list.full-identifier */ +/* ^^^^^^ entity.name.function */ +template <typename Foo> SomeType<OtherType> A<Foo>::foobar(YetAnotherType&& asRValue) {} +/* ^^^^^^^^^^^^^^ meta.function meta.toc-list.full-identifier */ +/* ^^^^^^ entity.name.function */ + +template <typename Foo> A<Foo>::A(YetAnotherType&& asRValue) {} +/* ^^^^^^^^^ meta.function meta.toc-list.full-identifier */ +/* ^ entity.name.function */ + +template <typename Foo> A<Foo>::A(YetAnotherType&& asRValue) {} +/* ^^^^^^^^^ meta.function meta.toc-list.full-identifier */ +/* ^ entity.name.function.constructor */ + +template <typename Foo> A<Foo>::~A(YetAnotherType&& asRValue) {} +/* ^^^^^^^^^ meta.function meta.toc-list.full-identifier */ +/* ^ entity.name.function.destructor */ + +template <class T> +bool A<T>::operator > (const A& other) { return false; } +/* ^^^^^^^^^^^^^^^^^^ meta.function meta.toc-list.full-identifier */ +/* ^^^^^^^^^^^^ entity.name.function */ +template <class T> +bool A<T>::operator == (const A& other) { return false; } +/* ^^^^^^^^^^^^^^^^^^^^ meta.function meta.toc-list.full-identifier */ +/* ^^^^^^^^^^^^^^ entity.name.function */ + +typedef std :: vector<std::vector<int> > Table; +/* ^^ punctuation.accessor */ +/* ^ punctuation.section.generic.begin */ +/* ^ punctuation.section.generic.begin */ +/* ^ punctuation.section.generic.end */ +/* ^ punctuation.section.generic.end */ + +template <typename T = float, int a = 3, bool b = true> + /* ^ meta.template keyword.operator */ + /* ^ meta.template keyword.operator */ + /* ^ meta.template constant.numeric */ + /* ^ meta.template keyword.operator */ + /* ^ meta.template constant.language */ +struct Foo +{ + +/* <- meta.struct - meta.template */ + + void bar(int a = 3, bool b = true) {} + /* ^ - meta.template keyword.operator */ + /* ^ - meta.template constant.numeric */ + /* ^ - meta.template keyword.operator */ + /* ^ - meta.template constant.language */ +}; + +/* <- - meta.block - meta.struct - meta.template */ + +template <std::size_t Count = 128> +/* ^^ meta.template punctuation.accessor */ +/* ^ meta.template keyword.operator */ +/* ^ meta.template constant.numeric */ +class fixed_array : private std::array<int, Count> {}; + +constexpr std::size_t f() { return 128; } +template <std::size_t Count = f()> +/* ^^ meta.template punctuation.accessor */ +/* ^ meta.template keyword.operator */ +/* ^ meta.template variable.function */ +/* ^^ meta.template meta.function-call punctuation */ +/* ^ meta.template punctuation */ +class fixed_array : private std::array<int, Count> {}; + +template<class T> class A { /* ... */ }; +template<class T, class U = T> class B { /* ... */ }; +/* ^ meta.template keyword.operator */ +/* ^ meta.template */ +/* ^ meta.template punctuation */ +/* ^ - meta.template */ +template <class ...Types> class C { /* ... */ }; + +// templates inside templates... it's templates all the way down +template<template<class> class P> class X { /* ... */ }; +/* ^ meta.template punctuation */ +/* ^ meta.template meta.template punctuation */ +/* ^^^^^ meta.template meta.template storage.type */ +/* ^ meta.template meta.template punctuation */ +/* ^^^^^ meta.template storage.type */ +/* ^ meta.template punctuation */ + +X<A> xa; // OK +X<B> xb; // OK in C++14 after CWG 150 + // Error earlier: not an exact match +X<C> xc; // OK in C++14 after CWG 150 + +// template declarations spanning multiple lines +template +/* <- meta.template storage.type */ +< +/* <- meta.template punctuation.section.generic.begin */ + class T, + class U = T +> +class B +{ + /* ... */ +}; + +// template declarations spanning multiple lines +template +< +/* <- meta.template punctuation.section.generic.begin */ + std::size_t Count = f() +/* ^^ meta.template punctuation.accessor */ +/* ^ meta.template keyword.operator */ +/* ^ meta.template variable.function */ +/* ^^ meta.template meta.function-call punctuation */ +> +/* <- meta.template punctuation.section.generic.end */ +class fixed_array : private std::array<int, Count> {}; + +template <class T> +static bool decode(const Node& node, T& sequence) { + if (!node.IsSequence()) + return false; + sequence.clear(); + for (const auto& item : node) { + sequence.push_back(item.template as<typename T::value_type>()); + /* ^ punctuation.accessor */ + /* ^ storage.type - variable.other */ + /* ^ variable.function */ + /* ^ punctuation */ + /* ^^ punctuation.accessor */ + /* ^ punctuation */ + } + return true; +} + +#include <functional> +template <class T> struct A {}; +template <class T> struct B {}; +struct C {}; +A<B<C>> f(std::function<A<B<C>>()> g) { + /* ^ punctuation.section.group.begin */ + /* ^^ punctuation.accessor */ + /* ^ punctuation.section.generic.begin */ + /* ^ punctuation.section.generic.begin */ + /* ^ punctuation.section.generic.begin */ + /* ^^ punctuation.section.generic.end */ + /* ^ punctuation.section.group.begin */ + /* ^ punctuation.section.group.end */ + /* ^ punctuation.section.generic.end */ + /* ^ variable.parameter */ + /* ^ punctuation.section.group.end */ + /* ^ punctuation.section.block.begin */ + return g(); +} +int main() { + std::function<C()> foo1; + /* ^ - variabe.function */ + std::function<B<C>()> foo2; + /* ^ - variable.function */ + auto f = [](std::function<A<B<C>>()> g) { return g(); }; + /* ^ punctuation.section.group.begin */ + /* ^^ punctuation.accessor */ + /* ^ punctuation.section.generic.begin */ + /* ^ punctuation.section.generic.begin */ + /* ^ punctuation.section.generic.begin */ + /* ^^ punctuation.section.generic.end */ + /* ^ punctuation.section.group.begin */ + /* ^ punctuation.section.group.end */ + /* ^ punctuation.section.generic.end */ + /* ^ punctuation.section.group.end */ + /* ^ punctuation.section.block.begin */ + /* ^ punctuation.section.block.end */ + return 0; +} +/* <- - invalid.illegal */ + +// Example from section 14.2/4 of +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf +struct X +{ + template <std::size_t> + X* alloc(); + + template <std::size_t> + static X* adjust(); +}; +template <class T> +void f(T* p) +{ + // Be optimistic: scope it as a template member function call anyway. + T* p1 = p->alloc<200>(); // ill-formed: < means less than + + T* p2 = p->template alloc<200>(); // OK: < starts template argument list + /* ^ punctuation.accessor */ + /* ^ storage.type - variable.other */ + /* ^ variable.function */ + + // Be optimistic: scope it as a template member function call anyway. + T::adjust<100>(); // ill-formed: < means less than + + T::template adjust<100>(); // OK: < starts template argument list + /* <- - variable.function */ + /*^ punctuation.accessor */ + /* ^ storage.type - variable.other */ + /* ^^^^^^^^^^^^^^^^^^^^^^ meta.function-call */ + /* ^ variable.function */ +} + +struct X +{ + void template(); // <-- not allowed to be a function! + /* ^ - entity.name.function */ +}; + +void f() +{ + X x; + x.template(); // <-- should not be scoped as variable.function! + /* ^ - variable.function */ + + x /**/ . /**/ foo <5> /**/ () /**/ ; + /*^^^^ comment.block */ + /* ^ punctuation.accessor */ + /* ^^^ meta.method-call variable.function */ + /* ^ meta.method-call - variable.function */ + /* ^ meta.method-call punctuation.section.generic.begin */ + /* ^ meta.method-call punctuation.section.generic.end */ + /* ^ meta.method-call - punctuation - comment.block */ + /* ^^^^ meta.method-call comment.block */ + /* ^ meta.method-call - comment.block - punctuation */ + /* ^^ meta.method-call punctuation - comment.block */ + /* ^ - meta.method-call */ +}; + +template<typename T> C<T> f(T t) +{ + return C<T> { g<X<T>>(t) }; + /* ^ variable.function */ + /* ^ punctuation.section.group.begin */ +} + +template<typename T> C<X<T>> f(T t) +{ + return C<X<T>> { g<X<T>>(t) }; + /* ^ variable.function */ + /* ^ punctuation.section.group.begin */ +} + +struct A { int foo; }; +int main() { + A a, b; + a.foo = a.foo < 0 ? 1 : 2; + /* ^ - punctuation.section.generic */ + a.operator<(b); + /*^^^^^^^^^^^^ meta.method-call */ + /*^^^^^^^^^ variable.function.member */ + /* ^^^ meta.group */ + a.operator>(b); + /*^^^^^^^^^^^^ meta.method-call */ + /*^^^^^^^^^ variable.function.member */ + /* ^^^ meta.group */ + a.operator<=(b); + /*^^^^^^^^^^^^^ meta.method-call */ + /*^^^^^^^^^^ variable.function.member */ + /* ^^^ meta.group */ + a.operator>=(b); + /*^^^^^^^^^^^^^ meta.method-call */ + /*^^^^^^^^^^ variable.function.member */ + /* ^^^ meta.group */ + a.operator==(b); + /*^^^^^^^^^^^^^ meta.method-call */ + /*^^^^^^^^^^ variable.function.member */ + /* ^^^ meta.group */ + a.operator!=(b); + /*^^^^^^^^^^^^^ meta.method-call */ + /*^^^^^^^^^^ variable.function.member */ + /* ^^^ meta.group */ + a.operator->(); + /*^^^^^^^^^^^^ meta.method-call */ + /*^^^^^^^^^^ variable.function.member */ + /* ^^ meta.group */ +} +/* <- - invalid.illegal */ + +template <typename T> +struct A<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_type<T>::value>> { + using x = conditional_t<sizeof(T) <= sizeof(long), long, long long>; + /* ^^ keyword.operator */ +}; +/* <- - invalid.illegal */ + + +///////////////////////////////////////////// +// Storage Modifiers +///////////////////////////////////////////// + +alignas(16) char array[256]; +/* <- storage.modifier */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ + +const int XYZ = 2; +/* <- storage.modifier */ + +constexpr int ABC = 3 + 5; +/* <- storage.modifier */ + +thread_local int x; +/* <- storage.modifier */ + + +///////////////////////////////////////////// +// Control Keywords +///////////////////////////////////////////// + +static_assert(x >= 0); +/* <- keyword.operator */ + +noexcept(f()); +/* ^^^ meta.function-call */ +/* <- keyword.operator */ + +if (x < 5) +/* <- keyword.control */ +{} +else +/* <- keyword.control */ +{} + +switch (x) +/* <- keyword.control */ +{ +case 1: +/* <- keyword.control */ + break; + /* <- keyword.control.flow.break */ +default: +/* <- keyword.control */ + break; + /* <- keyword.control.flow.break */ +} + +do +/* <- keyword.control */ +{ + if (y == 3) + continue; + /* <- keyword.control.flow.continue */ +} while (y < x); +/*^ keyword.control */ + +switch (a) { + case 1: break; +/* ^ punctuation.separator */ + case 100 - 10: break; +/* ^ punctuation.separator */ + default: break; +/* ^ punctuation.separator */ +} + +goto label; +/* <- keyword.control.flow.goto */ + +try +/* <- keyword.control */ +{ + throw std :: string("xyz"); + /* <- keyword.control.flow.throw */ + /* ^^^^^^ variable.function */ + /* ^^ punctuation.accessor */ +} +catch (...) +/* <- keyword.control */ +{ +} + +int* ptr = new int(2); +/* ^ keyword.control */ + +delete ptr; +/* <- keyword.control */ + +return 123; +/* <- keyword.control.flow.return */ + + +///////////////////////////////////////////// +// Operator Keywords +///////////////////////////////////////////// + +int x = alignof(char); +/* ^ keyword.operator.word */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ + +int x = sizeof(char); +/* ^ keyword.operator.word */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ + + +///////////////////////////////////////////// +// Cast Keywords +///////////////////////////////////////////// + +const_cast<int>(2.0); +/* <- keyword.operator.word.cast */ +/* ^ punctuation.section.generic.begin */ +/* ^ storage.type */ +/* ^ punctuation.section.generic.end */ + +dynamic_cast<int>(2.0); +/* <- keyword.operator.word.cast */ + +reinterpret_cast<int>(2.0); +/* <- keyword.operator.word.cast */ + +static_cast<int>(2.0); +/* <- keyword.operator.word.cast */ + +auto var = *reinterpret_cast<std::vector<std::shared_ptr<AnyClass>>*>(v); +/* ^ keyword.operator.word.cast */ +/* ^ - variable.function */ + +///////////////////////////////////////////// +// Language Constants +///////////////////////////////////////////// + +bool t = true; +/* ^ constant.language */ + +bool f = false; +/* ^ constant.language */ + +int* p = nullptr; +/* ^ constant.language */ + +char ch[] = __func__; +/* ^ constant.language */ + + +///////////////////////////////////////////// +// Support Constants +///////////////////////////////////////////// + +std::cout << __FILE__ << '\n'; +/* ^ support.constant */ +/* ^^ punctuation.accessor */ + +std :: cout << __FUNCTION__ << '\n'; +/* ^^ punctuation.accessor */ +/* ^ support.constant */ + +std::cout << __LINE__ << '\n'; +/* ^ support.constant */ + + +///////////////////////////////////////////// +// Numeric Constants +///////////////////////////////////////////// + +dec1 = 1234567890; +/* ^^^^^^^^^^ constant.numeric.integer.decimal */ +/* ^ punctuation.terminator - constant */ + +dec2 = 1'924'013; +/* ^^^^^^^^^ constant.numeric.integer.decimal */ +/* ^ punctuation.terminator - constant */ + +dec3 = 124ul; +/* ^^^^^ constant.numeric.integer.decimal */ +/* ^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +dec4 = 9'204lu; +/* ^^^^^^^ constant.numeric.integer.decimal */ +/* ^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +dec5 = 2'354'202'076LL; +/* ^^^^^^^^^^^^^^^ constant.numeric.integer.decimal */ +/* ^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +oct1 = 0123_567; +/* ^^^^^^^^ constant.numeric.integer.octal */ +/* ^ punctuation.definition.numeric.base */ +/* ^^^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +oct2 = 014'70; +/* ^^^^^^ constant.numeric.integer.octal */ +/* ^ punctuation.definition.numeric.base */ +/* ^ punctuation.terminator - constant */ + +hex1 = 0x1234567890ABCDEF; +/* ^^^^^^^^^^^^^^^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ punctuation.terminator - constant */ + +hex2 = 0X1234567890ABCDEF; +/* ^^^^^^^^^^^^^^^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ punctuation.terminator - constant */ + +hex3 = 0x1234567890abcdef; +/* ^^^^^^^^^^^^^^^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ punctuation.terminator - constant */ + +hex4 = 0xA7'45'8C'38; +/* ^^^^^^^^^^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ punctuation.terminator - constant */ + +hex5 = 0x0+0xFL+0xaull+0xallu+0xfu+0xf'12_4_uz; +/* ^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ storage.type.numeric */ +/* ^^^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^^^ storage.type.numeric */ +/* ^^^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^^^ storage.type.numeric */ +/* ^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ storage.type.numeric */ +/* ^^^^^^^^^^ constant.numeric.integer.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^^^^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +hex2 = 0xc1.01AbFp-1; +/* ^^^^^^^^^^^^^ constant.numeric.float.hexadecimal */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ punctuation.separator.decimal */ +/* ^ punctuation.terminator - constant */ + +bin1 = 0b010110; +/* ^^^^^^^^ constant.numeric.integer.binary */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ punctuation.terminator - constant */ + +bin2 = 0B010010; +/* ^^^^^^^^ constant.numeric.integer.binary */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ punctuation.terminator - constant */ + +bin3 = 0b1001'1101'0010'1100; +/* ^^^^^^^^^^^^^^^^^^^^^ constant.numeric.integer.binary */ +/* ^^ punctuation.definition.numeric.base */ +/* ^ punctuation.terminator - constant */ + +f = 1.1+1.1e1+1.1e-1+1.1f+1.1e1f+1.1e-1f+1.1L+1.1e1L+1.1e-1L; +/* ^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +f = 1.e1+1.e-1+1.e1f+1.e-1f+1.e1L+1.e-1L; +/* ^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +f = 1.+1.f+1.L+1..; +/* ^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^ constant.numeric.integer.decimal */ +/* ^^ invalid.illegal.syntax */ +/* ^ punctuation.terminator - constant */ + +f = 1e1+1e1f+1e1L; +/* ^^^ constant.numeric.float.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^ constant.numeric.float.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^ constant.numeric.float.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +f = .1+.1e1+.1e-1+.1f+.1e1f+.1e-1f+.1L+.1e1L+.1e-1L; +/* ^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ keyword.operator.arithmetic */ +/* ^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ keyword.operator.arithmetic */ +/* ^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +f = 1'843'290.245'123; +/* ^^^^^^^^^^^^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ punctuation.terminator - constant */ + +f = 2'837e1'000; +/* ^^^^^^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.terminator - constant */ + +f = 23e-1'000; +/* ^^^^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.terminator - constant */ + +units1 = 134h + 123.45h; +/* ^^^^ constant.numeric.integer.decimal */ +/* ^ storage.type.numeric */ +/* ^^^ - constant */ +/* ^^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +units2 = 147min + 147.min; +/* ^^^^^^ constant.numeric.integer.decimal */ +/* ^^^ storage.type.numeric */ +/* ^^^ - constant */ +/* ^^^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +units3 = 357s + 34.7s; +/* ^^^^ constant.numeric.integer.decimal */ +/* ^ storage.type.numeric */ +/* ^^^ - constant */ +/* ^^^^^ constant.numeric.float.decimal */ +/* ^ punctuation.separator.decimal */ +/* ^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +units4 = 234_custom + 10e-1_custom; +/* ^^^^^^^^^^ constant.numeric.integer.decimal */ +/* ^^^^^^^ storage.type.numeric */ +/* ^^^ - constant */ +/* ^^^^^^^^^^^^ constant.numeric.float.decimal */ +/* ^^^^^^^ storage.type.numeric */ +/* ^ punctuation.terminator - constant */ + +///////////////////////////////////////////// +// Functions +///////////////////////////////////////////// + +// function prototype +void abcdWXYZ1234(); +/* ^^^^^^^^^^^^^^ meta.function */ +/* ^ entity.name.function */ +/* ^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ + +// function definition +void abcdWXYZ1234() +/* ^^^^^^^^^^^^^^ meta.function */ +/* ^ entity.name.function */ +/* ^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +{ +/* <- meta.function meta.block punctuation.section.block.begin */ +} +/* <- meta.function meta.block punctuation.section.block.end */ + +struct foo **alloc_foo(); +/* ^^^^^^^^^^^ meta.function */ +/* ^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^ storage.type */ +/* ^ - entity.name.struct */ +/* ^^ keyword.operator */ +/* ^ entity.name.function */ + +long func +/* ^^^^ meta.function entity.name.function */ +(int x, void *MYMACRO(y) ) { +/*^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function */ +/*^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters meta.group */ +/* <- meta.function.parameters meta.group punctuation.section.group.begin */ +/* ^ variable.parameter */ +/* ^ -entity.name.function */ +/* ^^^^^^^^^^ meta.function-call */ +/* ^^^ meta.group meta.function-call meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^ punctuation.section.group.end */ + // Ensure < and > aren't parsed as a generic + if (foo < bar && baz > bar ) { +/* ^ keyword.operator.comparison */ +/* ^ keyword.operator.comparison */ + + label: +/* ^ entity.name.label */ +/* ^ punctuation.separator */ + do { + break; + } while(true); + + } + if (version.major == 10 && version.minor < 11) +/* ^ keyword.operator.comparison */ + { + + } +} +/* <- meta.function meta.block punctuation.section.block.end */ + +MACRO1 +RETURN_TYPE +/* <- - entity.name.function */ +func_name() { +/* < entity.name.function */ +} + +MACRO1 void * MACRO2 myfuncname () { +/* ^ storage.type */ +/* ^ keyword.operator */ +/* ^ entity.name.function */ + + struct Args { +/* ^ storage.type */ +/* ^ entity.name.struct */ + void* hello; + void* foobar; + Args() +/* ^ entity.name.function.constructor */ + : hellp(nullptr), +/* ^ punctuation.separator.initializer-list */ + foobar(nullptr) + { + } + }; + + struct Args args2; +/* ^ storage.type */ +/* ^ - entity */ + + class LocalFoo MYMACRO +/* ^ storage.type */ +/* ^ entity.name.class */ +/* ^ - entity */ + { + LocalFoo() {} +/* ^ entity.name.function.constructor */ + } + + class LocalFoo test; +/* ^ storage.type */ +/* ^ - entity */ + +} + +static const uint32_t * const MACRO funcname(); +/* ^ storage.modifier */ +/* ^ storage.modifier */ +/* ^ support.type */ +/* ^ keyword.operator */ +/* ^ storage.modifier */ +/* ^ entity.name.function */ + +void FooBar :: baz(int a) +/* ^^^^^^^^^^^^^^^^^^^^ meta.function */ +/* ^^^^^^^^^^^^^ meta.toc-list.full-identifier */ +/* ^^^ entity.name.function */ +/* ^^ punctuation.accessor */ +/* ^^^^^^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ variable.parameter */ +/* ^ punctuation.section.group.end */ +{ +} +/* A comment. */ void FooBar :: baz(int a) +/* ^^^^^^^^^^^^^^^^^^^^ meta.function */ +/* ^^^^^^^^^^^^^ meta.toc-list.full-identifier */ +/* ^^^ entity.name.function */ +/* ^^ punctuation.accessor */ +/* ^^^^^^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ variable.parameter */ +/* ^ punctuation.section.group.end */ +{ +} +// prevent leading comment from function recognition +/**/ HRESULT A::b() +/* ^ meta.function */ +/* ^ entity.name.function */ +{ + return S_OK; +} +FooBar::FooBar(int a) +/*^^^^^^^^^^^^^^^^^^^ meta.function */ +/*^^^^^^^^^^^^ meta.toc-list.full-identifier */ +/* ^^^^^^ entity.name.function */ +/* ^^^^^^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^^^ storage.type */ +/* ^ punctuation.section.group.end */ +{ +} + +FooBar :: FooBar(int a) & = +/*^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function */ +/*^^^^^^^^^^^^^^ meta.toc-list.full-identifier */ +/* ^^^^^^ entity.name.function */ +/* ^^^^^^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^^^ storage.type */ +/* ^ variable.parameter */ +/* ^ punctuation.section.group.end */ +/* ^ keyword.operator */ +/* ^ keyword.operator.assignment */ +default; +/*^^^^^ meta.function storage.modifier */ + +FooBar::~FooBar +/*^^^^^^^^^^^^^ meta.function meta.toc-list.full-identifier */ +/* ^^^^^^^ entity.name.function */ +() { } +/* <- meta.function.parameters meta.group punctuation.section.group.begin */ + /* <- meta.function.parameters meta.group punctuation.section.group.end */ +/*^^^^ meta.function */ + +ThisIsAReallyReallyLongClassNameThatRequiresWrappingCodeInTheMiddleOfAPath:: + ThisIsAReallyReallyLongClassNameThatRequiresWrappingCodeInTheMiddleOfAPath() +/* <- meta.function meta.toc-list.full-identifier */ + : var_name(nullptr) { +} + +bool FooBar::operator==() {} +/* ^^^^^^^^^^^^^^^^^^^^^^^ meta.function */ +/* ^^^^^^^^^^^^^^^^^^ meta.toc-list.full-identifier */ +/* ^^^^^^^^^^ entity.name.function */ +/* ^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^^ meta.block */ +/* ^ punctuation.section.block.begin */ +/* ^ punctuation.section.block.end */ + + +myns::FooBar::~FooBar() { } +/*^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function */ +/*^^^^^^^^^^^^^^^^^^^ meta.toc-list.full-identifier */ +/* ^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^^^ meta.block */ +/* ^ punctuation.section.block.begin */ +/* ^ punctuation.section.block.end */ +/*^^^^^^^^^^^^^^^^^^^ meta.toc-list.full-identifier */ +/* ^^^^^^^ entity.name.function */ + + extern "C" void test_in_extern_c_block() +/* ^^^^^^^^^^^^^^^^^^^^^^^^ meta.function */ +/* ^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^ entity.name.function */ +{ +/* <- meta.function meta.block punctuation.section.block.begin */ +} +/* <- meta.function meta.block punctuation.section.block.end */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if 0 +void test_in_extern_c_block() +/* ^ comment.block */ +{ +} +#else + +/* temporary C++ preprocessor block */ +#ifdef __cplusplus +/* <- meta.preprocessor */ +/* <- keyword.control.import */ +# ifndef _Bool +/* <- meta.preprocessor */ +/* <- keyword.control.import */ + typedef bool _Bool; /* semi-hackish: C++ has no _Bool; bool is builtin */ +/* ^ storage.type */ +/* ^ entity.name.type.typedef */ +# endif +/* <- meta.preprocessor */ +/* <- keyword.control.import */ +#endif +/* <- meta.preprocessor */ +/* <- keyword.control.import */ + +void test_in_extern_c_block() +/* ^^^^^^^^^^^^^^^^^^^^^^^^ meta.function */ +/* ^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^ entity.name.function */ +{ +/* <- meta.function meta.block punctuation.section.block.begin */ +} +/* <- meta.function meta.block punctuation.section.block.end */ +#endif + +#ifdef __cplusplus +} +#endif +/* ^ - meta.extern-c */ + +gener<int> func_returning_generic(int a); +/* ^ entity.name.function */ + +std::vector<std::uint8_t> func_returning_path_generic(int a); +/* ^ punctuation.section.generic */ +/* ^ entity.name.function */ + +void f() +{ + static_assert(false, "oops"); + /* ^ keyword.operator.word */ +} + +long double operator "" _km (long double x); +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function */ +/* ^^^^^^^^^^^^^^^ meta.function.parameters */ +/* ^^^^^^^^^^^^^^^ entity.name.function */ + +///////////////////////////////////////////// +// Namespace +///////////////////////////////////////////// + +namespace myNameSpace {} +/* <- keyword.control */ +/* ^ entity.name.namespace */ + +namespace new_name = current_name; +/* <- keyword.control */ + +using namespace NAME __attribute__((visibility ("hidden"))); +/* <- keyword.control */ +/* ^ keyword.control */ +/* ^ storage.modifier */ +/* ^ string */ + +void func() { + using namespace NAME __attribute__((visibility ("hidden"))); +/* ^ keyword.control */ +/* ^ keyword.control */ +/* ^ storage.modifier */ +/* ^ string */ +} + +using namespace +/* <- keyword.control */ +/* ^ keyword.control */ + +using namespace myNameSpace; +/* <- keyword.control */ +/* ^ keyword.control */ + +namespace ns :: abc /* Neither this comment... */ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.namespace */ +/* ^^^^^^^^^ entity.name.namespace */ +/* ^^ punctuation.accessor */ +/* ^ comment.block */ +// ...nor this comment is highlighted +/* <- comment.line */ +{ +/* <- meta.namespace meta.block punctuation.section.block.begin */ + void nsfunc() { + /* ^ entity.name.function */ + } +} +/* <- meta.namespace meta.block punctuation.section.block.end */ + +namespace tl { +/*^^^^^^^^^^^^ meta.namespace */ +/* ^ keyword.control */ + namespace { +/* ^ keyword.control */ +/* ^^^^^^^^^^^ meta.namespace meta.namespace */ +/* ^ meta.block meta.block punctuation.section.block.begin */ + void nested_func(){} +/* ^ entity.name.function */ + } +} + +MACRONAME namespace ns3 {} +/* ^ keyword.control */ + +extern "C++" +// ^ storage.modifier +// ^^^^^ string.quoted.double +{ +namespace std _GLIBCXX_VISIBILITY(default) +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.namespace +// ^ keyword.control +// ^ entity.name.namespace +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call +// ^^^^^^^^^ meta.group +// ^ keyword.control +{} +} + +#define MY_NAMESPACE_BEGIN namespace greatapp { +#define MY_NAMESPACE_END } +MY_NAMESPACE_BEGIN +class X { +private: +/* <- storage.modifier */ + int a; +protected: +/* <- storage.modifier */ + int b; +public: +/* <- storage.modifier */ + int c; +}; +MY_NAMESPACE_END + +MY_NAMESPACE_BEGIN int foo(); MY_NAMESPACE_END +/* ^ storage.type */ +/* ^ meta.function entity.name.function */ +/* ^^^ punctuation */ + +// Uncomment this some day +// MY_NAMESPACE_BEGIN class X : public std::true_type {}; MY_NAMESPACE_END + +///////////////////////////////////////////// +// Classes, structs, unions and enums +///////////////////////////////////////////// + +class BaseClass; +/*^^^^^^^^^^^^^ meta.class */ +/* ^ - meta.class meta.class */ +/* ^^^^^^^^^ entity.name.class.forward-decl */ + +class BaseClass // comment +/* <- storage.type */ +/* ^ entity.name.class */ +{ +public : +/* <- storage.modifier */ + tupleTmpl<int,2> max(tupleGen<int,2> a, tupleGen<int,2> b); +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method */ +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ variable.parameter */ +/* ^ punctuation.separator */ +/* ^ variable.parameter */ +/* ^ punctuation.section.group.end */ +/* ^ punctuation.section.generic.begin */ +/* ^ storage.type */ +/* ^ punctuation.section.generic.end */ +/* ^ punctuation.section.generic.begin */ +/* ^ storage.type */ +/* ^ punctuation.section.generic.end */ +protected: +/* <- storage.modifier */ +private: +/* <- storage.modifier */ + + static int a = 1 << 4; + /* <- storage.modifier */ + /* ^^ keyword.operator.arithmetic */ + + static int x; + /* <- storage.modifier */ + + virtual void doSomething() const = 0; + /* ^^^^^^^^^^^^^^^^^^^^^^^ meta.method */ + /* ^ - meta.method meta.method */ + /* ^^ meta.method.parameters meta.group */ + /* ^ punctuation.section.group.begin */ + /* ^ punctuation.section.group.end */ + /* <- storage.modifier */ + /* ^ entity.name.function */ + /* ^ storage.modifier */ + /* ^ constant.numeric */ + + template<typename A> + void func(){} +/* ^^^^^^^^ meta.method */ +/* ^^ meta.method.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^^ meta.block */ +/* ^ punctuation.section.block.begin */ +/* ^ punctuation.section.block.end */ +/* ^^^^ entity.name.function */ + + template<typename A> + void func<A>(){} +/* ^^^^^^^^^^^ meta.method */ +/* ^^^^ entity.name.function */ +/* ^ punctuation.section.generic.begin */ +/* ^ punctuation.section.generic.end */ +/* ^^ meta.method.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^^ meta.block */ +/* ^ punctuation.section.block.begin */ +/* ^ punctuation.section.block.end */ + + template<typename A> + BaseClass(){} +/* ^^^^^^^^^^^^^ meta.method */ +/* ^^^^^^^^^ meta.method.constructor */ +/* ^^^^^^^^^ entity.name.function */ + + ~BaseClass() {} +/* ^^^^^^^^^^^^^^^ meta.method */ +/* ^^^^^^^^^^ meta.method.destructor */ +/* ^^^^^^^^^^ entity.name.function */ + + BaseClass operator [] () +/* ^^^^^^^^^^^^^^ meta.method */ +/* ^^ meta.method.parameters */ +/* ^^^^^^^^^^^ entity.name.function */ + {} + + BaseClass operator= +/* ^^^^^^^^^ meta.method */ +/* ^^^^^^^^^ entity.name.function */ + () {} +/* ^^^^^ meta.method */ +/* ^^ meta.method.parameters */ +/* ^^ meta.block */ +}; + +class DerivedClass : public ::BaseClass // Comment +/* ^ entity.other.inherited-class */ +/* ^ comment.line */ +{ + ~DerivedClass() override; + /* <- meta.method.destructor */ + /*^^^^^^^^^^^^^^^^^^^^^^ meta.method */ + /*^^^^^^^^^^^ meta.method.destructor */ + /* ^ storage.modifier */ + virtual void doSomething() const override final; + /* ^ storage.modifier */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ + protected: +/*^^^^^^^^ storage.modifier */ + DerivedClass() override +/*^^^^^^^^^^^^^^^^^^^^^^^ meta.method */ +/*^^^^^^^^^^^^ meta.method.constructor */ +/* ^ storage.modifier */ + : a(a), +/* ^^^^^^^ meta.method.constructor.initializer-list */ + base_id_(BaseClass::None().ToInt()), +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.constructor.initializer-list */ +/* ^ variable.other.readwrite.member */ +/* ^ punctuation.accessor */ +/* ^^^^^^^^^^^^^^^^^ meta.function-call */ +/* ^^^^ variable.function */ +/* ^ punctuation - meta.method-call */ +/* ^^^^^^^ meta.method-call */ +/* ^^^^^ variable.function */ +/* ^ punctuation.separator */ + bounds_(NULL), +/* ^^^^^^^^^^^^^^ meta.method.constructor.initializer-list */ + bit_field_(0) { +/* ^^^^^^^^^^^^^^^ meta.method */ +/* ^^^^^^^^^^^^^ meta.method.constructor.initializer-list */ + char * a = "sprintf"; + char * b = sprintf("Testing %s", a); +/* ^^^^^^^^^ meta.function-call */ +/* ^^^^^^^ support.function.C99 */ + + base_id_->foobar(1, "foo"); +/* ^^ punctuation.accessor - meta.method-call */ +/* ^^^^^^^^^^^^^^^^ meta.method-call */ +/* ^^^^^^ variable.function */ + + base_id_->~BaseClass(); +/* ^^ punctuation.accessor - meta.method-call */ +/* ^^^^^^^^^^^^ meta.method-call */ +/* ^^^^^^^^^^ variable.function */ + } +/* ^ meta.method meta.block punctuation.section.block.end */ + +/* <- - meta.class.constructor.initializer-list */ + + typedef std::vector<int> qux; +/* ^^^ entity.name.type.typedef */ +}; + + +template<typename A> +class class1<A> : class2<A> +/* ^^^^^^ entity.name.class */ +/* ^ punctuation.section.generic */ +/* ^ punctuation.section.generic */ +/* ^^^^^^ entity.other.inherited-class */ +/* ^ punctuation.section.generic */ +/* ^ punctuation.section.generic */ +{} + +class FooBar { +/* ^ meta.class meta.block punctuation.section.block.begin */ + explicit FooBar(int a); +/* ^^^^^^^^^^^^^ meta.method */ +/* ^^^^^^^^ storage.modifier */ +/* ^^^^^^ entity.name.function */ + FooBar() =default; +/* ^^^^^^ entity.name.function */ +/* ^ keyword.operator.assignment */ +/* ^^^^^^^ storage.modifier */ + FooBar(void) =default; +/* ^^^^^^ entity.name.function */ +/* ^^^^ storage.type */ +/* ^ keyword.operator.assignment */ +/* ^^^^^^^ storage.modifier */ + + // If a constructor name is on a line without the opening (, it is not + // highlighted as a method/constructor. This prevents a bunch of false + // positives, including data types as they are being typed into a struct. + FooBar +/* ^ - entity.name.function */ + (); + + virtual ~FooBar(); +/* ^^^^^^^ entity.name.function */ + +#ifndef DEBUG + ~FooBar(); +/* ^^^^^^^ entity.name.function */ +#endif + + void insert () {} +/* ^^^^^^ entity.name.function */ + + explicit operator bool +/* ^^^^ entity.name.function */ + () {} + + FooBar::~FooBar(); +/* ^^^^^^^^^^^^^^^ entity.name.function */ + + void FooBar:: + Baz() { + /* <- entity.name.function */ + } + + auto f(int a) -> decltype(a.begin()) override final; +/* ^^ punctuation.separator */ +/* ^ punctuation.accessor */ +/* ^^^^^ variable.function */ +/* ^ storage.modifier */ +/* ^ storage.modifier */ + + auto g() -> std::vector<int> override final { +/* ^^ punctuation.separator */ +/* ^^ punctuation.accessor */ +/* ^ storage.type */ +/* ^ storage.modifier */ +/* ^ storage.modifier */ + this->g(1); +/* ^ variable.language */ + } + +private: +/*^^^^^ storage.modifier */ + + VISIBILITY_MACRO +/* ^ - entity.name.function */ + myns::subns::MyDataType +/* ^ - entity.name.function */ + and_now_method_name(); +/* ^ entity.name.function */ + + VISIBILITY_MACRO +/* ^ - entity.name.function */ + std::shared_future<std::vector<myns::mysubns::MyDataType>> +/* ^ - entity.name.function */ +/* ^^ punctuation.accessor */ +/* ^ punctuation.section.generic.begin */ +/* ^^ punctuation.accessor */ +/* ^ punctuation.section.generic.begin */ +/* ^^ punctuation.accessor */ + and_now_method_name2(); +/* ^ entity.name.function */ + + enum +/* ^^^^ meta.enum storage.type */ + { +/* ^ meta.enum punctuation.section.block.begin */ + A = 1, + B = 20 / 5 + } +/* ^ meta.enum punctuation.section.block.end */ +/* ^ - meta.enum */ + + friend int func(int a, int b); +/* ^ storage.modifier */ +/* ^ storage.type */ +/* ^ - entity.name.function */ +/* ^ - meta.function-call */ + + friend int func(int a, int b) { +/* ^ storage.modifier */ +/* ^ storage.type */ +/* ^ entity.name.function */ +/* ^ - meta.function-call */ +/* ^ meta.class meta.block meta.method meta.block punctuation.section.block.begin */ + int a = 1; + } +/* ^ meta.class meta.block meta.block punctuation.section.block.end */ +/* ^ - meta.class meta.block meta.block */ + + friend class ::FooBar; +/* ^ storage.modifier */ +/* ^ storage.type +/* ^^ punctuation.accessor */ +/* ^ - entity */ + + friend bool operator != (const X& lhs, const X& rhs) { + /* ^^^^^^^^^^^ entity.name.function */ + int a = 1; + } +/* ^ meta.class meta.block meta.block punctuation.section.block.end */ +/* ^ - meta.class meta.block meta.block */ + + #if 0 + /* ^ constant.numeric */ + int disabled_func() { + /* ^ comment.block */ + } + #endif + + #if 1 + /* ^ constant.numeric */ + int enabled_func() {} + /* ^ entity.name.function */ + #else + int disabled_func() { + /* ^ comment.block */ + } + #endif + + MACRO_NOT_CONSTRUCTOR(FooBar); +/* ^ meta.function-call variable.function - entity.name.function */ + + MACRO_NOT_CONSTRUCTOR2(FooBar, +/* ^ meta.function-call variable.function - entity.name.function */ + FriendClass); +} +/* <- meta.class meta.block punctuation.section.block.end */ + /* <- - meta.class meta.block */ + +struct X { + Y f() override noexcept final; + /*^ entity.name.function */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ + ::Y g() override noexcept final; + /* <- punctuation.accessor */ + /* ^ entity.name.function */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ +}; + +class X { + public: + ::Y g() override noexcept final; + /* <- punctuation.accessor */ + /* ^ entity.name.function */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ +}; + +union Y { + ::Y g() override noexcept final; + /* <- punctuation.accessor */ + /* ^ entity.name.function */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ + /* ^ storage.modifier */ +}; + +class Child : public Parent { + ::anotherClass Func() override; + /* <- punctuation.accessor */ + /* ^ entity.name.function */ + /* ^ storage.modifier */ +} + +class Adapter2 : public Abstraction, private Scenario { +/* ^ punctuation.separator */ +} + +class Adapter : public Abstraction + #if defined ASPECTO_MACRO +/* ^^^ keyword.control.import */ + , public Scenario +/* ^ punctuation.separator */ +/* ^ storage.modifier */ +/* ^ entity.other.inherited-class */ + #endif +/* ^^^^^^ keyword.control.import */ +{ + +} + +struct Base {}; +class Derived final : Base {}; +/* ^ storage.modifier */ +struct Derived final : Base {}; +/* ^ storage.modifier */ + +/* C++11 "uniform initialization" in initializer lists */ +class Foo { +public: + Foo() : var1(1), var(2), var3{3}, var4(4) {} + /* ^ meta.method.constructor.initializer-list */ + /* ^ - meta.function-call - variable.function */ +private: + int var1, var2, var3, var4; +}; + +class X { + int a, b, i, j; +public: + const int& r; + X(int i) + : r(a) // initializes X::r to refer to X::a + /* ^ meta.method.constructor.initializer-list punctuation */ + /* ^ meta.method.constructor.initializer-list punctuation */ + , b{i} // initializes X::b to the value of the parameter i + /* ^ meta.method.constructor.initializer-list punctuation */ + /* ^ meta.method.constructor.initializer-list punctuation */ + , i(i) // initializes X::i to the value of the parameter i + /* ^ meta.method.constructor.initializer-list punctuation */ + /* ^ meta.method.constructor.initializer-list punctuation */ + , j(this->i) // initializes X::j to the value of X::i + /* ^ meta.method.constructor.initializer-list punctuation */ + /* ^ meta.method.constructor.initializer-list punctuation */ + , j + /*^ variable */ + (this->i) + /* <- meta.method.constructor.initializer-list punctuation */ + { } +/* ^ punctuation - meta.method.constructor.initializer-list */ +/* ^ punctuation - meta.method.constructor.initializer-list */ +}; + +struct A { + static_assert(0 < 1, ""); + /* ^ keyword.operator.word */ + /* ^ meta.function-call */ + /* ^ keyword.operator.comparison */ + + A(); +/*^ meta.method.constructor entity.name.function.constructor */ + + void f(); + /* ^ storage.type */ + /* ^ meta.method entity.name.function */ + /* ^ punctuation.terminator */ +}; +/* <- punctuation.section.block.end - invalid.illegal */ + +struct bar { +/*^^^^^^^^^^ meta.struct */ +/*^^^^ storage.type */ +/* ^^^ entity.name.struct */ +/* ^ meta.block punctuation.section.block.begin */ + bar() +/* ^^^^^ meta.method */ +/* ^^^ entity.name.function */ + {} +} +/* <- meta.struct meta.block punctuation.section.block.end */ + /* <- - meta.struct meta.block */ + +enum baz { +/*^^^^^^^^ meta.enum */ +/* <- meta.enum storage.type */ +/* ^^^ entity.name.enum */ +/* ^ meta.block punctuation.section.block.begin */ + FOO = 1, +/* ^ keyword.operator.assignment */ +/* ^ constant.numeric */ + BAR = 2, + BAZ = 3, +#if 0 +/* ^ constant.numeric */ + QUX = 4, +/* ^ comment.block */ +#endif +} +/* <- meta.enum meta.block punctuation.section.block.end */ + /* <- - meta.enum meta.block */ + +int main(void) +{ + struct UI_BoundingBox decorativeBox = {10, titleHeight-3, width-20, height-10}; +/* ^ - entity.name */ +/* ^ - entity.name */ +} + +struct foo MACRO { +/* ^ entity.name.struct */ +/* ^ - entity.name */ +} + +// Partially-typed +struct foo +/* ^ entity.name */ + +struct UI_MenuBoxData +/* <- storage.type */ +/* ^ entity.name.struct */ +{ + struct UI_BoundingBox position; +/* ^ - entity.name */ +/* ^ - entity.name */ + enum UI_BoxCharType borderType; +/* ^ - entity.name */ +/* ^ - entity.name */ + unsigned int paddingX; + unsigned int paddingY; + struct UI_ScrollBoxText boxContents[]; +/* ^ - entity.name */ +/* ^ - entity.name */ +}; + +enum class qux : std::uint8_t +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.enum */ +/*^^^^^^^^ storage.type */ +/* ^^^ entity.name.enum */ +/* ^ punctuation.separator */ +/* ^^^^^^^^^^^^ entity.other.inherited-class */ +{ +/* <- meta.block punctuation.section.block.begin */ + FOO = 1, + BAR = 2, +/* ^ keyword.operator.assignment */ +/* ^ constant.numeric */ + BAZ = 3 +} +/* <- meta.enum meta.block punctuation.section.block.end */ + /* <- - meta.enum meta.block */ + +enum LineEnding : uint32_t; +/*^^^^^^^^^^^^^^^^^^^^^^^^ meta.enum */ +/* ^^^^^^^^^^ entity.name.enum.forward-decl */ +/* ^ punctuation.separator */ +/* ^^^^^^^^ entity.other.inherited-class */ +/* ^ - meta.enum */ + +union foobaz { +/* <- meta.union storage.type */ +/* ^^^^^^ entity.name.union */ +/* ^ meta.block punctuation.section.block.begin */ +} +/* <- meta.union meta.block punctuation.section.block.end */ + /* <- - meta.union meta.block */ + +// Class name that looks like a possible macro +class SP {} +/* ^^ entity.name.class */ + +class MyClass MACRO MACRO2 +/* ^ storage.type */ +/* ^ entity.name.class */ +/* ^ - entity */ +/* ^ - entity */ +{} + +// Class using macro to handle __declspec() on Windows +class SK_API SkBitmap {} +/* ^ entity.name.class */ +class __declspec(property(get=foo)) SkBitmap {} +/* ^ storage.modifier */ +/* ^ variable.parameter */ +/* ^ entity.name.class */ +class __declspec(align(8)) SkBitmap {} +/* ^ storage.modifier */ +/* ^ constant.numeric */ +/* ^ entity.name.class */ +class __declspec(dllimport) SkBitmap {} +/* ^ constant.other */ +/* ^ entity.name.class */ + +// Make sure not to match macros that have "too few characters". +template <class T> class Sample { + public: + // The T here should not be consumed as a macro. + T operator() (const foo x) { + /* <- entity.name.function */ + /*^^^^^^^^ entity.name.function */ + return T; + } + int operator == (const int x) { + /*^^^^^^^^^^^ entity.name.function */ + return 0; + } + // The T here should not be consumed as a macro. + T operator()(int a) { + /* <- entity.name.function */ + /*^^^^^^^^ entity.name.function */ + return T; + } + // The T here should not be consumed as a macro. + T operator[](int a) { + /* <- entity.name.function */ + /*^^^^^^^^ entity.name.function */ + return T; + } +}; + +class Namespace::MyClass MACRO1 MACRO2 : public SuperClass +/* ^^^^^^^ entity.name.class */ +/* ^^ punctuation.accessor */ +/* ^ - entity.name */ +{ +}; + +struct Namespace::MyStruct +/* ^^^^^^^^ entity.name.struct */ +/* ^^ punctuation.accessor */ +{ +}; + +union Namespace::MyUnion +/* ^^^^^^^ entity.name.union */ +/* ^^ punctuation.accessor */ +{ +}; + +enum class Namespace::MyEnum +/* ^^^^^^ entity.name.enum */ +/* ^^ punctuation.accessor */ +{ +}; + +class Namespace:: +MyClass MACRO1 +/* <- entity.name.class */ +/* ^ - entity.name */ +{ +}; + +struct Namespace:: +MyStruct MACRO1 +/* <- entity.name.struct */ +/* ^ - entity.name */ +{ +}; + +union Namespace:: +MyUnion MACRO1 +/* <- entity.name.union */ +/* ^ - entity.name */ +{ +}; + +enum class Namespace:: +MyEnum MACRO1 +/* <- entity.name.enum */ +/* ^ - entity.name */ +{ +}; + + +///////////////////////////////////////////// +// Test preprocessor branching and C blocks +///////////////////////////////////////////// + +int foo(int val, float val2[], bool val3 = false) +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function */ +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^^^ variable.parameter */ +/* ^ punctuation.separator */ +/* ^^^^ variable.parameter */ +/* ^^ meta.brackets */ +/* ^ punctuation.section.brackets.begin */ +/* ^ punctuation.section.brackets.end */ +/* ^ punctuation.separator */ +/* ^^^^ storage.type */ +/* ^^^^ variable.parameter */ +/* ^ keyword.operator.assignment */ +/* ^^^^^ constant.language */ +{ + myClass *result; + result->kk = func(val); +/* ^^ punctuation.accessor */ + if (result == 0) { + return 0; +#if CROSS_SCOPE_MACRO + /* <- keyword.control.import */ + } else if (result > 0) { + return 1; +#endif + /* <- keyword.control.import */ + } +/* ^ meta.block meta.block punctuation.section.block.end */ +/* ^ - meta.block meta.block */ + +#ifndef DEBUG + if (check_debug()) { + val /= 2; +#endif + val += 1; +#ifndef DEBUG + } +/* ^ meta.function meta.block meta.block punctuation.section.block.end */ +/* ^ - meta.block meta.block */ +#endif + +#ifdef FOO + /* <- keyword.control.import */ + int foobar +/* ^^^^^^ - entity.name.function */ + ; + + if (val == -1) { +/* ^ meta.block meta.block punctuation.section.block.begin */ +#else + /* <- keyword.control.import */ + if (val == -2) { +/* ^ meta.block meta.block punctuation.section.block.begin */ +#endif + /* <- keyword.control.import */ + val += 1; + } +/* ^ meta.block punctuation.section.block.end */ +/* ^ - meta.block meta.block */ + + return -1; +} +/* <- meta.function punctuation.section.block.end */ + /* <- - meta.function */ + +#if 0 +/* ^ constant.numeric */ +int disabled_func() { +/* ^ comment.block */ +} +#endif + +#if 1 +/* ^ constant.numeric */ +int enabled_func() {} +/* ^ entity.name.function */ +#else +int disabled_func() { +/* ^ comment.block */ +} +#endif + +#if 1 + int a = 1; + #if 0 +/* ^ constant.numeric */ + int b = 2; +/* ^ comment.block */ + #else + int c = 3; + #endif +#else + int d = 4; +/* ^ comment.block */ +#endif + +BOOL +GetTextMetrics( + HDC hdc, + LPTEXTMETRIC lptm + ) +{ +#ifdef UNICODE +/* <- keyword.control.import */ + return GetTextMetricsW( +/* ^ variable.function */ +#else +/* <- keyword.control.import */ + return GetTextMetricsA( +/* ^ variable.function */ +#endif +/* <- keyword.control.import */ + hdc, + lptm + ); +/* ^ meta.function-call */ +/* ^ - meta.function-call */ +} + /* <- - meta.function */ + /* <- - meta.block */ + +///////////////////////////////////////////// +// Matching various function definitions +///////////////////////////////////////////// + +const int foo = 1; +/* ^ - entity.name.function */ +int a; +/* ^ - entity.name.function */ + +int /* comment */ * myfunc +/* <- storage.type */ +/* ^ comment.block */ +/* ^ keyword.operator */ +/* ^^^^^^ entity.name.function */ +(int * a) +/* <- punctuation.section.group.begin */ +/* ^ keyword.operator */ +/* ^ punctuation.section.group.end */ +{ + +} + +void MyClass3:: +foo() { +/* <- entity.name.function */ +} + +MyClass3:: +~MyClass3() { +/* <- entity.name.function */ +} + +struct A +{ + #ifdef X + static_assert(false, "asdf"); + /* ^ keyword.operator.word */ + #endif + + void f() + { + #ifdef X + static_assert(false, "asdf"); + /* ^ keyword.operator.word */ + #endif + } + + void f() + { + static_assert(false, "asdf"); + /* ^ keyword.operator.word */ + } +}; + +void f() +{ + static_assert(false, "asdf"); +/* ^ meta.function meta.block */ +/* ^ keyword.operator.word */ +} + +void f() +{ + #ifdef X + static_assert(false, "asdf"); +/* ^ meta.function meta.block */ +/* ^ keyword.operator.word */ + #endif +} + +Glib::ustring Node::_getDragTip(GdkEventMotion */*event*/); +/* ^^^^^^^^^ comment */ + +MACRO1 void * MACRO2 myfuncname () { +/* ^ storage.type */ +/* ^ keyword.operator */ +/* ^ entity.name.function */ + + label: +/* ^ entity.name.label */ +/* ^ punctuation.separator */ + do { + break; + } while(true); + + switch (a) { + case 1: break; +/* ^ punctuation.separator */ + case 100 - 10: break; +/* ^ punctuation.separator */ + default: break; +/* ^ punctuation.separator */ + } + +} + +static const uint32_t * const MACRO funcname(); +/* ^ storage.modifier */ +/* ^ storage.modifier */ +/* ^ support.type */ +/* ^ keyword.operator */ +/* ^ storage.modifier */ +/* ^ entity.name.function */ + +MACRO int +/* ^ storage.type */ +funcname2 +/* ^ entity.name.function */ +() +{ + +} + +MACRO_CALL(int) macro_prefixed_func(){} +/*^^^^^^^^^^^^^ meta.function-call */ +/* ^^^^^ meta.group */ +/* ^ punctuation.section.group.begin */ +/* ^ punctuation.section.group.end */ +/* ^ entity.name.function */ + +int* return_type_pointer_no_space(){} +/* ^ entity.name.function */ + +int& return_type_ref_no_space(){} +/* ^ entity.name.function */ + +// Make sure there isn't an incorrect match here since this is not a valid +// function definition +int32 +/* <- - entity.name.function */ +() {} + +_declspec(deprecated("bla")) void func2(int) {} +/* <- meta.function-call variable.function */ +/* ^ entity.name.function */ +__declspec(deprecated("bla")) void func2(int) {} +/* <- storage.modifier - variable.function */ +/* ^ storage.modifier - variable.function */ +/* ^ string.quoted.double punctuation */ +/* ^ string.quoted.double - punctuation */ +/* ^ string.quoted.double - punctuation */ +/* ^ string.quoted.double punctuation */ +/* ^^ punctuation - invalid */ +/* ^ entity.name.function */ +__notdeclspec(deprecated("bla")) void func2(int) {} +/* <- meta.function-call variable.function */ +/* ^ entity.name.function */ + +///////////////////////////////////////////// +// Paths/identifiers +///////////////////////////////////////////// + +void sayHi() +{ + std::cout << "Hi!\n"; +/* ^ punctuation.accessor */ + Print<int>(3); +/* ^ variable.function */ + func_call(foo +/* ^ meta.function-call */ + ); + + if (::std::foo()) {} +/* ^^^ variable.function */ +/* ^^ punctuation.accessor */ +/* ^^ punctuation.accessor */ + + foobaz<int>(); +/* ^^^^^^^^^^^^^ meta.function-call */ +/* ^^^^^^ variable.function */ +/* ^ punctuation.section.generic.begin */ +/* ^ punctuation.section.generic.end */ +/* ^^ meta.group */ + + foobaz<>(); +/* ^^^^^^^^^^ meta.function-call */ +/* ^^^^^^ variable.function */ +/* ^ punctuation.section.generic.begin */ +/* ^ punctuation.section.generic.end */ +/* ^^ meta.group */ + + foobaz<0>(); +/* ^^^^^^^^^^^ meta.function-call */ +/* ^^^^^^ variable.function */ +/* ^ punctuation.section.generic.begin */ +/* ^ constant.numeric */ +/* ^ punctuation.section.generic.end */ +/* ^^ meta.group */ + + ::myns::foo<int>(); +/* ^^ punctuation.accessor.double-colon */ +/* ^^ punctuation.accessor.double-colon */ +/* ^^^^^^^^^^^^^^^^^^ meta.function-call */ +/* ^^^ variable.function */ +/* ^^^ storage.type */ + + myns::FooClass{42}; +/* ^^ punctuation.accessor.double-colon */ +/* ^^^^^^^^^^^^^^^^^^ meta.function-call */ +/* ^^^^^^^^ variable.function */ + + ::myns::BarClass<int>{}; +/* ^^ punctuation.accessor.double-colon */ +/* ^^ punctuation.accessor.double-colon */ +/* ^^^^^^^^^^^^^^^^^^^^^ meta.function-call */ +/* ^^^^^^^^ variable.function */ +/* ^^^ storage.type */ + + int a[5]; +/* ^^^ meta.brackets */ +/* ^ punctuation.section.brackets.begin */ +/* ^ punctuation.section.brackets.end */ + + std::cout << ">> Hi!\n"; +/* ^^ keyword.operator.arithmetic.c */ +} + +///////////////////////////////////////////// +// Includes +///////////////////////////////////////////// + +#include "foobar.h" +/* <- keyword.control.import.include */ +/* ^ punctuation.definition.string.begin */ +/* ^^^^^^^^ string.quoted.double.include */ +/* ^ punctuation.definition.string.end */ + +#include <cstdlib> +/* <- keyword.control.import.include */ +/* ^ punctuation.definition.string.begin */ +/* ^^^^^^^ string.quoted.other.lt-gt.include */ +/* ^ punctuation.definition.string.end */ + +#ifdef _GLIBCXX_INCLUDE_NEXT_C_HEADERS +#include_next <math.h> +/* <- keyword.control.import.include */ +/* ^ punctuation.definition.string.begin */ +/* ^^^^^^ string.quoted.other.lt-gt.include */ +/* ^ punctuation.definition.string.end */ +#endif + +#include<iostream> +/* <- keyword.control.import.include */ +/* ^ punctuation.definition.string.begin */ +/* ^^^^^^^^ string.quoted.other.lt-gt.include */ +/* ^ punctuation.definition.string.end */ + +/** + * +/* ^ comment.block.c punctuation.definition.comment.c */ diff --git a/syntaxes/HTML/Comments.tmPreferences b/syntaxes/HTML/Comments.tmPreferences @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Comments</string> + <key>scope</key> + <string>text.html</string> + <key>settings</key> + <dict> + <key>shellVariables</key> + <array> + <dict> + <key>name</key> + <string>TM_COMMENT_START</string> + <key>value</key> + <string><![CDATA[<!-- ]]></string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_END</string> + <key>value</key> + <string><![CDATA[ -->]]></string> + </dict> + </array> + </dict> +</dict> +</plist> diff --git a/syntaxes/HTML/HTML.sublime-syntax b/syntaxes/HTML/HTML.sublime-syntax @@ -0,0 +1,732 @@ +%YAML 1.2 +--- +name: HTML +file_extensions: + - html + - htm + - shtml + - xhtml +first_line_match: (?i)<(!DOCTYPE\s*)?html +scope: text.html.basic + +variables: + ascii_space: '\t\n\f ' + + # https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attribute_name_char: '[{{ascii_space}}=/>]' + attribute_name_start: (?=[^{{attribute_name_char}}]) + attribute_name_break: (?={{attribute_name_char}}) + + # https://html.spec.whatwg.org/multipage/syntax.html#syntax-attribute-value + unquoted_attribute_start: (?=[^{{ascii_space}}=>]) + unquoted_attribute_break: (?=[{{ascii_space}}]|/?>) + + # https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state + tag_name_char: '[^{{ascii_space}}/<>]' + tag_name_break: (?=[^{{tag_name_char}}]) + tag_name: '[A-Za-z]{{tag_name_char}}*' + + block_tag_name: |- + (?ix: + address|applet|article|aside|blockquote|center|dd|dir|div|dl|dt|figcaption|figure|footer|frame|frameset|h1|h2|h3|h4|h5|h6|header|iframe|menu|nav|noframes|object|ol|p|pre|section|ul + ){{tag_name_break}} + + inline_tag_name: |- + (?ix: + abbr|acronym|area|audio|b|base|basefont|bdi|bdo|big|br|canvas|caption|cite|code|del|details|dfn|dialog|em|font|head|html|i|img|ins|isindex|kbd|li|link|map|mark|menu|menuitem|meta|noscript|param|picture|q|rp|rt|rtc|ruby|s|samp|script|small|source|span|strike|strong|style|sub|summary|sup|time|title|track|tt|u|var|video|wbr + ){{tag_name_break}} + + form_tag_name: |- + (?ix: + button|datalist|input|label|legend|meter|optgroup|option|output|progress|select|template|textarea + ){{tag_name_break}} + + javascript_mime_type: |- + (?ix: + # https://mimesniff.spec.whatwg.org/#javascript-mime-type + (?:application|text)/(?:x-)?(?:java|ecma)script + | text/javascript1\.[0-5] + | text/jscript + | text/livescript + ) + + custom_element_char: |- + (?x: + # https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-core-concepts + [-_a-z0-9\x{00B7}] + | \\\. + | [\x{00C0}-\x{00D6}] + | [\x{00D8}-\x{00F6}] + | [\x{00F8}-\x{02FF}] + | [\x{0300}-\x{037D}] + | [\x{037F}-\x{1FFF}] + | [\x{200C}-\x{200D}] + | [\x{203F}-\x{2040}] + | [\x{2070}-\x{218F}] + | [\x{2C00}-\x{2FEF}] + | [\x{3001}-\x{D7FF}] + | [\x{F900}-\x{FDCF}] + | [\x{FDF0}-\x{FFFD}] + | [\x{10000}-\x{EFFFF}] + ) + + script_close_lookahead: (?i:(?=(?:-->\s*)?</script)) + +contexts: + immediately-pop: + - match: '' + pop: true + + else-pop: + - match: (?=\S) + pop: true + + main: + - include: comment + - include: cdata + - include: doctype + - match: (<\?)(xml) + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.xml.html + push: + - meta_scope: meta.tag.preprocessor.xml.html + - match: '\?>' + scope: punctuation.definition.tag.end.html + pop: true + - include: tag-generic-attribute + - include: string-double-quoted + - include: string-single-quoted + - match: (<)((?i:style)){{tag_name_break}} + captures: + 0: meta.tag.style.begin.html + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.style.html + push: style-css + - match: '(<)((?i:script)){{tag_name_break}}' + captures: + 0: meta.tag.script.begin.html + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.script.html + push: script-javascript + - match: (</?)((?i:body|head|html){{tag_name_break}}) + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.structure.any.html + push: + - meta_scope: meta.tag.structure.any.html + - include: tag-end + - include: tag-attributes + - match: (</?)({{block_tag_name}}) + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.block.any.html + push: + - meta_scope: meta.tag.block.any.html + - include: tag-end + - include: tag-attributes + - match: (</?)((?i:hr){{tag_name_break}}) + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.block.any.html + push: + - meta_scope: meta.tag.block.any.html + - include: tag-end-maybe-self-closing + - include: tag-attributes + - match: (</?)((?i:form|fieldset){{tag_name_break}}) + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.block.form.html + push: + - meta_scope: meta.tag.block.form.html + - include: tag-end + - include: tag-attributes + - match: (</?)({{inline_tag_name}}) + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.inline.any.html + push: + - meta_scope: meta.tag.inline.any.html + - include: tag-end-maybe-self-closing + - include: tag-attributes + - match: (</?)({{form_tag_name}}) + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.inline.form.html + push: + - meta_scope: meta.tag.inline.form.html + - include: tag-end-maybe-self-closing + - include: tag-attributes + - match: (</?)((?i:a){{tag_name_break}}) + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.inline.a.html + push: + - meta_scope: meta.tag.inline.a.html + - include: tag-end-maybe-self-closing + - include: tag-attributes + - match: (</?)((?i:col|colgroup|table|tbody|td|tfoot|th|thead|tr){{tag_name_break}}) + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.inline.table.html + push: + - meta_scope: meta.tag.inline.table.html + - include: tag-end-maybe-self-closing + - include: tag-attributes + - match: </?(?=[A-Za-z]{{tag_name_char}}*?-) + scope: punctuation.definition.tag.begin.html + push: + - tag-custom-body + - tag-custom-name + - match: </?(?=[A-Za-z]) + scope: punctuation.definition.tag.begin.html + push: + - tag-other-body + - tag-other-name + - include: entities + - match: <> + scope: invalid.illegal.incomplete.html + + tag-custom-name: + - meta_content_scope: entity.name.tag.custom.html + - match: '{{tag_name_break}}' + pop: true + - match: '{{custom_element_char}}+' + # no scope + - match: '{{tag_name_char}}' + scope: invalid.illegal.custom-tag-name.html + + tag-custom-body: + - meta_scope: meta.tag.custom.html + - include: tag-end-maybe-self-closing + - include: tag-attributes + + tag-other-name: + - meta_content_scope: entity.name.tag.other.html + - match: '{{tag_name_break}}' + pop: true + + tag-other-body: + - meta_scope: meta.tag.other.html + - include: tag-end-maybe-self-closing + - include: tag-attributes + + entities: + - match: (&#[xX])\h+(;) + scope: constant.character.entity.hexadecimal.html + captures: + 1: punctuation.definition.entity.html + 2: punctuation.terminator.entity.html + - match: (&#)[0-9]+(;) + scope: constant.character.entity.decimal.html + captures: + 1: punctuation.definition.entity.html + 2: punctuation.terminator.entity.html + - match: (&)[a-zA-Z0-9]+(;) + scope: constant.character.entity.named.html + captures: + 1: punctuation.definition.entity.html + 2: punctuation.terminator.entity.html + + cdata: + - match: (<!\[)(CDATA)(\[) + captures: + 1: punctuation.definition.tag.begin.html + 2: keyword.declaration.cdata.html + 3: punctuation.definition.tag.begin.html + push: + - meta_scope: meta.tag.sgml.cdata.html + - meta_content_scope: string.unquoted.cdata.html + - match: ']]>' + scope: punctuation.definition.tag.end.html + pop: true + + comment: + - match: (<!--)(-?>)? + captures: + 1: punctuation.definition.comment.begin.html + 2: invalid.illegal.bad-comments-or-CDATA.html + push: + - meta_scope: comment.block.html + - match: '(<!-)?(--\s*>)' + captures: + 1: invalid.illegal.bad-comments-or-CDATA.html + 2: punctuation.definition.comment.end.html + pop: true + - match: '<!--(?!-?>)|--!>' + scope: invalid.illegal.bad-comments-or-CDATA.html + + doctype: + - match: (<!)(DOCTYPE) + captures: + 1: punctuation.definition.tag.begin.html + 2: keyword.declaration.doctype.html + push: + - doctype-meta + - doctype-content + - doctype-content-type + - doctype-name + + doctype-meta: + - meta_scope: meta.tag.sgml.doctype.html + - match: '>' + scope: punctuation.definition.tag.end.html + pop: true + + doctype-name: + - match: '{{tag_name}}' + scope: constant.language.doctype.html + pop: true + - include: else-pop + + doctype-content-type: + - match: (?:PUBLIC|SYSTEM)\b + scope: keyword.content.external.html + pop: true + - include: else-pop + + doctype-content: + - match: \[ + scope: punctuation.section.brackets.begin.html + set: + - meta_scope: meta.brackets.html meta.internal-subset.xml.html + - match: \] + scope: punctuation.section.brackets.end.html + pop: true + - include: comment + - include: string-double-quoted + - include: string-single-quoted + - include: else-pop + + style-css: + - meta_content_scope: meta.tag.style.begin.html + - include: style-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - include: style-close-tag + - match: (?=\S) + embed: scope:source.css + embed_scope: source.css.embedded.html + escape: (?i)(?=(?:-->\s*)?</style) + + style-other: + - meta_content_scope: meta.tag.style.begin.html + - include: style-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - include: style-close-tag + + style-close-tag: + - match: (?i)(</)(style)(>) + scope: meta.tag.style.end.html + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.style.html + 3: punctuation.definition.tag.end.html + pop: true + + style-common: + - include: style-type-attribute + - include: tag-attributes + - include: tag-end-self-closing + + style-type-attribute: + - match: (?i)\btype\b + scope: meta.attribute-with-value.html entity.other.attribute-name.html + set: + - meta_content_scope: meta.tag.style.begin.html meta.attribute-with-value.html + - match: = + scope: punctuation.separator.key-value.html + set: + - meta_content_scope: meta.tag.style.begin.html meta.attribute-with-value.html + - include: style-type-decider + - match: (?=\S) + set: style-css + + style-type-decider: + - match: (?i)(?=text/css{{unquoted_attribute_break}}|'text/css'|"text/css") + set: + - style-css + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?i)(?=>|''|"") + set: + - style-css + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?=\S) + set: + - style-other + - tag-generic-attribute-meta + - tag-generic-attribute-value + + script-javascript: + - meta_content_scope: meta.tag.script.begin.html + - include: script-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - include: script-close-tag + - match: (?=\S) + embed: scope:source.js + embed_scope: source.js.embedded.html + escape: '{{script_close_lookahead}}' + + script-html: + - meta_content_scope: meta.tag.script.begin.html + - include: script-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - meta_content_scope: text.html.embedded.html + - include: comment + - include: script-close-tag + - include: main + + script-other: + - meta_content_scope: meta.tag.script.begin.html + - include: script-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - include: script-close-tag + + script-close-tag: + - match: <!-- + scope: comment.block.html punctuation.definition.comment.begin.html + - match: '{{script_close_lookahead}}' + set: + - match: '-->' + scope: comment.block.html punctuation.definition.comment.end.html + - match: (?i:(</)(script)) + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.script.html + set: + - meta_scope: meta.tag.script.end.html + - include: tag-end + - include: tag-attributes + + script-common: + - include: script-type-attribute + - include: tag-attributes + - include: tag-end-self-closing + + script-type-attribute: + - match: (?i)\btype\b + scope: meta.attribute-with-value.html entity.other.attribute-name.html + set: + - meta_content_scope: meta.tag.script.begin.html meta.attribute-with-value.html + - match: = + scope: punctuation.separator.key-value.html + set: + - meta_content_scope: meta.tag.script.begin.html meta.attribute-with-value.html + - include: script-type-decider + - match: (?=\S) + set: script-javascript + + script-type-decider: + - match: (?i)(?={{javascript_mime_type}}{{unquoted_attribute_break}}|'{{javascript_mime_type}}'|"{{javascript_mime_type}}") + set: + - script-javascript + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?i)(?=module{{unquoted_attribute_break}}|'module'|"module") + set: + - script-javascript + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?i)(?=>|''|"") + set: + - script-javascript + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?i)(?=text/html{{unquoted_attribute_break}}|'text/html'|"text/html") + set: + - script-html + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?=\S) + set: + - script-other + - tag-generic-attribute-meta + - tag-generic-attribute-value + + string-double-quoted: + - match: '"' + scope: punctuation.definition.string.begin.html + push: + - meta_scope: string.quoted.double.html + - match: '"' + scope: punctuation.definition.string.end.html + pop: true + - include: entities + string-single-quoted: + - match: "'" + scope: punctuation.definition.string.begin.html + push: + - meta_scope: string.quoted.single.html + - match: "'" + scope: punctuation.definition.string.end.html + pop: true + - include: entities + + tag-generic-attribute: + - match: '{{attribute_name_start}}' + push: + - tag-generic-attribute-meta + - tag-generic-attribute-equals + - tag-generic-attribute-name + + tag-generic-attribute-name: + - meta_scope: entity.other.attribute-name.html + - match: '{{attribute_name_break}}' + pop: true + - match: '["''`<]' + scope: invalid.illegal.attribute-name.html + + tag-generic-attribute-meta: + - meta_scope: meta.attribute-with-value.html + - include: immediately-pop + + tag-generic-attribute-equals: + - match: '=' + scope: punctuation.separator.key-value.html + set: tag-generic-attribute-value + - include: else-pop + + tag-generic-attribute-value: + - match: '"' + scope: punctuation.definition.string.begin.html + set: + - meta_scope: string.quoted.double.html + - match: '"' + scope: punctuation.definition.string.end.html + pop: true + - include: entities + - match: "'" + scope: punctuation.definition.string.begin.html + set: + - meta_scope: string.quoted.single.html + - match: "'" + scope: punctuation.definition.string.end.html + pop: true + - include: entities + - match: '{{unquoted_attribute_start}}' + set: + - meta_scope: string.unquoted.html + - match: '{{unquoted_attribute_break}}' + pop: true + - match: '["''`<]' + scope: invalid.illegal.attribute-value.html + - include: entities + - include: else-pop + + tag-class-attribute: + - match: '\bclass\b' + scope: entity.other.attribute-name.class.html + push: + - tag-class-attribute-meta + - tag-class-attribute-equals + + tag-class-attribute-meta: + - meta_scope: meta.attribute-with-value.class.html + - include: immediately-pop + + tag-class-attribute-equals: + - match: '=' + scope: punctuation.separator.key-value.html + set: tag-class-attribute-value + - include: else-pop + + tag-class-attribute-value: + - match: '"' + scope: punctuation.definition.string.begin.html + set: + - meta_scope: string.quoted.double.html + - meta_content_scope: meta.class-name.html + - match: '"' + scope: punctuation.definition.string.end.html + pop: true + - include: tag-attribute-value-separator + - include: entities + - match: "'" + scope: punctuation.definition.string.begin.html + set: + - meta_scope: string.quoted.single.html + - meta_content_scope: meta.class-name.html + - match: "'" + scope: punctuation.definition.string.end.html + pop: true + - include: tag-attribute-value-separator + - include: entities + - match: '{{unquoted_attribute_start}}' + set: + - meta_scope: string.unquoted.html meta.class-name.html + - match: '{{unquoted_attribute_break}}' + pop: true + - match: '["''`<]' + scope: invalid.illegal.attribute-value.html + - include: entities + - include: else-pop + + tag-id-attribute: + - match: '\bid\b' + scope: entity.other.attribute-name.id.html + push: + - tag-id-attribute-meta + - tag-id-attribute-equals + + tag-id-attribute-meta: + - meta_scope: meta.attribute-with-value.id.html + - include: immediately-pop + + tag-id-attribute-equals: + - match: '=' + scope: punctuation.separator.key-value.html + set: tag-id-attribute-value + - include: else-pop + + tag-id-attribute-value: + - match: '"' + scope: punctuation.definition.string.begin.html + set: + - meta_scope: string.quoted.double.html + - meta_content_scope: meta.toc-list.id.html + - match: '"' + scope: punctuation.definition.string.end.html + pop: true + - include: tag-attribute-value-separator + - include: entities + - match: "'" + scope: punctuation.definition.string.begin.html + set: + - meta_scope: string.quoted.single.html + - meta_content_scope: meta.toc-list.id.html + - match: "'" + scope: punctuation.definition.string.end.html + pop: true + - include: tag-attribute-value-separator + - include: entities + - match: '{{unquoted_attribute_start}}' + set: + - meta_scope: string.unquoted.html meta.toc-list.id.html + - match: '{{unquoted_attribute_break}}' + pop: true + - match: '["''`<]' + scope: invalid.illegal.attribute-value.html + - include: entities + - include: else-pop + + tag-style-attribute: + - match: '\bstyle\b' + scope: entity.other.attribute-name.style.html + push: + - tag-style-attribute-meta + - tag-style-attribute-equals + + tag-style-attribute-meta: + - meta_scope: meta.attribute-with-value.style.html + - include: immediately-pop + + tag-style-attribute-equals: + - match: '=' + scope: punctuation.separator.key-value.html + set: tag-style-attribute-value + - include: else-pop + + tag-style-attribute-value: + - match: '"' + scope: string.quoted.double punctuation.definition.string.begin.html + embed: scope:source.css#rule-list-body + embed_scope: source.css + escape: '"' + escape_captures: + 0: string.quoted.double punctuation.definition.string.end.html + - match: "'" + scope: string.quoted.single punctuation.definition.string.begin.html + embed: scope:source.css#rule-list-body + embed_scope: source.css + escape: "'" + escape_captures: + 0: string.quoted.single punctuation.definition.string.end.html + - include: else-pop + + tag-event-attribute: + - match: |- + (?x)\bon( + abort|autocomplete|autocompleteerror|auxclick|blur|cancel|canplay + |canplaythrough|change|click|close|contextmenu|cuechange|dblclick|drag + |dragend|dragenter|dragexit|dragleave|dragover|dragstart|drop + |durationchange|emptied|ended|error|focus|input|invalid|keydown + |keypress|keyup|load|loadeddata|loadedmetadata|loadstart|mousedown + |mouseenter|mouseleave|mousemove|mouseout|mouseover|mouseup|mousewheel + |pause|play|playing|progress|ratechange|reset|resize|scroll|seeked + |seeking|select|show|sort|stalled|submit|suspend|timeupdate|toggle + |volumechange|waiting + )\b + scope: entity.other.attribute-name.event.html + push: + - tag-event-attribute-meta + - tag-event-attribute-equals + + tag-event-attribute-meta: + - meta_scope: meta.attribute-with-value.event.html + - include: immediately-pop + + tag-event-attribute-equals: + - match: '=' + scope: punctuation.separator.key-value.html + set: tag-event-attribute-value + - include: else-pop + + tag-event-attribute-value: + - match: '"' + scope: string.quoted.double punctuation.definition.string.begin.html + embed: scope:source.js + embed_scope: meta.attribute-with-value.event.html + escape: '"' + escape_captures: + 0: string.quoted.double punctuation.definition.string.end.html + - match: "'" + scope: string.quoted.single punctuation.definition.string.begin.html meta.attribute-with-value.event.html + embed: scope:source.js + embed_scope: meta.attribute-with-value.event.html + escape: "'" + escape_captures: + 0: string.quoted.single punctuation.definition.string.end.html + - include: else-pop + + # This is to prevent breaking syntaxes referencing the old context name + tag-stuff: + - include: tag-attributes + + tag-attributes: + - include: tag-id-attribute + - include: tag-class-attribute + - include: tag-style-attribute + - include: tag-event-attribute + - include: tag-generic-attribute + + tag-attribute-value-separator: + - match: (?=[{{ascii_space}}]) + push: + - clear_scopes: 1 # clear `meta.class-name` or `meta.toc-list.id` + - include: else-pop + + tag-end: + - match: '>' + scope: punctuation.definition.tag.end.html + pop: true + + tag-end-self-closing: + - match: '/>' + scope: punctuation.definition.tag.end.html + pop: true + + tag-end-maybe-self-closing: + - match: '/?>' + scope: punctuation.definition.tag.end.html + pop: true diff --git a/syntaxes/HTML/Indentation Rules.tmPreferences b/syntaxes/HTML/Indentation Rules.tmPreferences @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>scope</key> + <string>text.html</string> + <key>settings</key> + <dict> + <key>decreaseIndentPattern</key> + <string><![CDATA[(?x) + # the beginning of the line followed by any amount of whitespace + # a valid HTML close tag except "html" + ^[^<>]*+ </ (?!html[\t\n\f /<>])[^\t\n\f /<>]+ [^>]* > + | ^[\t\n\f ]*+ + ( + # closing comment punctuation, optionally preceded by an end "comment selector" + (<!\[ .*? \])?--> + # closing directive/section punctuation + | [?%]> + # closing curly brace + | \} + ) + ]]></string> + <key>increaseIndentPattern</key> + <string><![CDATA[(?x) + # the beginning of the line followed by any amount of whitespace + ^.* ( + # a valid non-self-closing HTML tag that doesn't close itself on the same line + <(?! + !-- # no comment + | [?%] # no section + | (?i:area|base|br|col|frame|hr|html|img|input|link|meta|param)[\t\n\f /<>] + )(?: + # tag name + (?<html_tag>[^\t\n\f /<>]+) + # not self closing + (?:(?!/>)[^>])* > + # not closing in the same line + (?! .* </\k<html_tag>) + ) + # comments that don't close themselves on the same line + | <!--(?!.*?-->) + # directives that don't close themselves on the same line + | <\?(?!.*?\?>) + # sections that don't close themselves on the same line + | <\%(?!.*?\%>) + # open curly braces that don't have close braces or string punctuation after them + | \{(?![}"']) + ) + ]]></string> + <key>bracketIndentNextLinePattern</key> + <string><![CDATA[<!DOCTYPE(?!.*>)]]></string> + </dict> +</dict> +</plist> diff --git a/syntaxes/HTML/Snippets/html (begin tag).sublime-snippet b/syntaxes/HTML/Snippets/html (begin tag).sublime-snippet @@ -0,0 +1,14 @@ +<snippet> + <description>html</description> + <content><![CDATA[!DOCTYPE html> +<html> +<head> + <title>$1</title> +</head> +<body> +$0 +</body> +</html>]]></content> + <tabTrigger>html</tabTrigger> + <scope>text.html entity.name.tag</scope> +</snippet> diff --git a/syntaxes/HTML/Snippets/html.sublime-snippet b/syntaxes/HTML/Snippets/html.sublime-snippet @@ -0,0 +1,13 @@ +<snippet> + <content><![CDATA[<!DOCTYPE html> +<html> +<head> + <title>$1</title> +</head> +<body> +$0 +</body> +</html>]]></content> + <tabTrigger>html</tabTrigger> + <scope>text.html &amp; (- meta.tag | punctuation.definition.tag.begin)</scope> +</snippet> diff --git a/syntaxes/HTML/Symbol List - ID.tmPreferences b/syntaxes/HTML/Symbol List - ID.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List: ID</string> + <key>scope</key> + <string>text.html meta.toc-list.id.html</string> + <key>settings</key> + <dict> + <key>symbolTransformation</key> + <string>s/^/ID: /</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/HTML/encode_html_entities.py b/syntaxes/HTML/encode_html_entities.py @@ -0,0 +1,25 @@ +import sublime +import sublime_plugin + +from html.entities import codepoint2name as cp2n + +class EncodeHtmlEntities(sublime_plugin.TextCommand): + def run(self, edit, **args): + view = self.view + + for sel in view.sel(): + buf = [] + + for pt in range(sel.begin(), sel.end()): + ch = view.substr(pt) + ch_ord = ord(ch) + + if (not view.match_selector(pt, ('meta.tag - string, constant.character.entity')) + and ch_ord in cp2n + and not (ch in ('"', "'") + and view.match_selector(pt, 'string'))): + ch = '&%s;' % cp2n[ch_ord] + + buf.append(ch) + + view.replace(edit, sel, ''.join(buf)) diff --git a/syntaxes/HTML/html_completions.py b/syntaxes/HTML/html_completions.py @@ -0,0 +1,504 @@ +import sublime, sublime_plugin +import re + + +def match(rex, str): + m = rex.match(str) + if m: + return m.group(0) + else: + return None + +def make_completion(tag): + # make it look like + # ("table\tTag", "table>$1</table>"), + return (tag + '\tTag', tag + '>$0</' + tag + '>') + +def get_tag_to_attributes(): + """ + Returns a dictionary with attributes accociated to tags + This assumes that all tags can have global attributes as per MDN: + https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes + """ + + # Map tags to specific attributes applicable for that tag + tag_dict = { + 'a' : ['charset', 'coords', 'download', 'href', 'hreflang', 'media', 'name', 'ping', 'rel', 'rev', 'shape', 'target', 'type'], + 'abbr' : ['title'], + 'address' : [], + 'applet' : ['align', 'alt', 'archive', 'code', 'codebase', 'height', 'hspace', 'name', 'object', 'vspace', 'width'], + 'area' : ['alt', 'coords', 'download', 'href', 'hreflang', 'media', 'nohref', 'rel', 'shape', 'target'], + 'article' : [], + 'aside' : [], + 'audio' : ['autoplay', 'buffered', 'controls', 'loop', 'muted', 'played', 'preload', 'src', 'volume'], + 'b' : [], + 'base' : ['href', 'target'], + 'basefont' : ['color', 'face', 'size'], + 'bdi' : [], + 'bdo' : [], + 'blockquote' : ['cite'], + 'body' : ['alink', 'background', 'bgcolor', 'link', 'onafterprint', 'onbeforeprint', 'onbeforeunload', 'onhashchange', 'onmessage', 'onoffline', 'ononline', 'onpopstate', 'onredo', 'onstorage', 'onundo', 'onunload', 'text', 'vlink'], + 'br' : ['clear'], + 'button' : ['autofocus', 'disabled', 'form', 'formaction', 'formenctype', 'formmethod', 'formnovalidate', 'formtarget', 'name', 'type', 'value'], + 'canvas' : ['height', 'width'], + 'caption' : ['align'], + 'cite' : [], + 'code' : [], + 'col' : ['align', 'char', 'charoff', 'span', 'valign', 'width'], + 'colgroup' : ['align', 'char', 'charoff', 'span', 'valign', 'width'], + 'content' : ['select'], + 'data' : ['value'], + 'datalist' : [], + 'dd' : [], + 'del' : ['cite', 'datetime'], + 'details' : ['open'], + 'dfn' : [], + 'dir' : ['compact'], + 'div' : ['align'], + 'dl' : ['compact'], + 'dt' : [], + 'element' : [], + 'em' : [], + 'embed' : ['height', 'src', 'type', 'width'], + 'fieldset' : ['disabled', 'form', 'name'], + 'figcaption' : [], + 'figure' : [], + 'font' : ['color', 'face', 'size'], + 'footer' : [], + 'form' : ['accept-charset', 'accept', 'action', 'autocomplete', 'enctype', 'method', 'name', 'novalidate', 'target'], + 'frame' : ['frameborder', 'longdesc', 'marginheight', 'marginwidth', 'name', 'noresize', 'scrolling', 'src'], + 'frameset' : ['cols', 'onunload', 'rows'], + 'h1' : ['align'], + 'h2' : ['align'], + 'h3' : ['align'], + 'h4' : ['align'], + 'h5' : ['align'], + 'h6' : ['align'], + 'head' : ['profile'], + 'header' : [], + 'hr' : ['align', 'noshade', 'size', 'width'], + 'html' : ['manifest', 'version', 'xmlns'], + 'i' : [], + 'iframe' : ['align', 'frameborder', 'height', 'longdesc', 'marginheight', 'marginwidth', 'name', 'sandbox', 'scrolling', 'seamless', 'src', 'srcdoc', 'width'], + 'img' : ['align', 'alt', 'border', 'crossorigin', 'height', 'hspace', 'ismap', 'longdesc', 'name', 'sizes', 'src', 'srcset', 'usemap', 'vspace', 'width'], + 'input' : ['accept', 'align', 'alt', 'autocomplete', 'autofocus', 'autosave', 'checked', 'disabled', 'form', 'formaction', 'formenctype', 'formmethod', 'formnovalidate', 'formtarget', 'height', 'inputmode', 'ismap', 'list', 'max', 'maxlength', 'min', 'minlength', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'selectionDirection', 'size', 'spellcheck', 'src', 'step', 'tabindex', 'type', 'usemap', 'value', 'width'], + 'ins' : ['cite', 'datetime'], + 'isindex' : ['prompt'], + 'kbd' : [], + 'keygen' : ['autofocus', 'challenge', 'disabled', 'form', 'keytype', 'name'], + 'label' : ['for', 'form'], + 'legend' : [], + 'li' : ['type', 'value'], + 'link' : ['charset', 'crossorigin', 'href', 'hreflang', 'media', 'rel', 'rev', 'sizes', 'target', 'type'], + 'main' : [], + 'map' : ['name'], + 'mark' : [], + 'menu' : ['compact'], + 'meta' : ['charset', 'content', 'http-equiv', 'name', 'scheme'], + 'meter' : ['value', 'min', 'max', 'low', 'high', 'optimum', 'form'], + 'nav' : [], + 'noframes' : [], + 'noscript' : [], + 'object' : ['align', 'archive', 'border', 'classid', 'codebase', 'codetype', 'data', 'declare', 'form', 'height', 'hspace', 'name', 'standby', 'type', 'typemustmatch', 'usemap', 'vspace', 'width'], + 'ol' : ['compact', 'reversed', 'start', 'type'], + 'optgroup' : ['disabled', 'label'], + 'option' : ['disabled', 'label', 'selected', 'value'], + 'output' : ['for', 'form', 'name'], + 'p' : ['align'], + 'param' : ['name', 'type', 'value', 'valuetype'], + 'picture' : [], + 'pre' : ['width'], + 'progress' : ['max', 'value'], + 'q' : ['cite'], + 'rp' : [], + 'rt' : [], + 'rtc' : [], + 's' : [], + 'samp' : [], + 'script' : ['async', 'charset', 'defer', 'language', 'src', 'type'], + 'section' : [], + 'select' : ['autofocus', 'disabled', 'form', 'multiple', 'name', 'required', 'size'], + 'shadow' : [], + 'small' : [], + 'source' : ['src', 'type'], + 'span' : [], + 'strong' : [], + 'style' : ['disabled', 'media', 'scoped', 'title', 'type'], + 'sub' : [], + 'summary': [], + 'sup' : [], + 'table' : ['align', 'bgcolor', 'border', 'cellpadding', 'cellspacing', 'frame', 'rules', 'summary', 'width'], + 'tbody' : ['align', 'char', 'charoff', 'valign'], + 'td' : ['abbr', 'align', 'axis', 'bgcolor', 'char', 'charoff', 'colspan', 'headers', 'height', 'nowrap', 'rowspan', 'scope', 'valign', 'width'], + 'template' : ['content'], + 'textarea' : ['autocomplete', 'autofocus', 'cols', 'disabled', 'form', 'maxlength', 'minlength', 'name', 'placeholder', 'readonly', 'required', 'rows', 'selectionDirection', 'selectionEnd', 'selectionStart', 'spellcheck', 'wrap'], + 'tfoot' : ['align', 'char', 'charoff', 'valign'], + 'th' : ['abbr', 'align', 'axis', 'bgcolor', 'char', 'charoff', 'colspan', 'headers', 'height', 'nowrap', 'rowspan', 'scope', 'valign', 'width'], + 'thead' : ['align', 'char', 'charoff', 'valign'], + 'time' : ['datetime'], + 'title' : [], + 'tr' : ['align', 'bgcolor', 'char', 'charoff', 'valign'], + 'track' : ['default', 'kind', 'label', 'src', 'srclang'], + 'u' : [], + 'ul' : ['compact', 'type'], + 'var' : [], + 'video' : ['autoplay', 'autobuffer', 'buffered', 'controls', 'crossorigin', 'height', 'loop', 'muted', 'played', 'preload', 'poster', 'src', 'width'], + 'wbr' : [] + } + + # Assume that global attributes are common to all HTML elements + global_attributes = [ + 'accesskey', 'class', 'contenteditable', 'contextmenu', 'dir', + 'hidden', 'id', 'lang', 'style', 'tabindex', 'title', 'translate' + ] + + # Extend `global_attributes` by the event handler attributes + global_attributes.extend([ + 'onabort', 'onautocomplete', 'onautocompleteerror', 'onauxclick', 'onblur', + 'oncancel', 'oncanplay', 'oncanplaythrough', 'onchange', 'onclick', + 'onclose', 'oncontextmenu', 'oncuechange', 'ondblclick', 'ondrag', + 'ondragend', 'ondragenter', 'ondragexit', 'ondragleave', 'ondragover', + 'ondragstart', 'ondrop', 'ondurationchange', 'onemptied', 'onended', + 'onerror', 'onfocus', 'oninput', 'oninvalid', 'onkeydown', + 'onkeypress', 'onkeyup', 'onload', 'onloadeddata', 'onloadedmetadata', + 'onloadstart', 'onmousedown', 'onmouseenter', 'onmouseleave', + 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', + 'onmousewheel', 'onpause', 'onplay', 'onplaying', 'onprogress', + 'onratechange', 'onreset', 'onresize', 'onscroll', 'onseeked', + 'onseeking', 'onselect', 'onshow', 'onsort', 'onstalled', 'onsubmit', + 'onsuspend', 'ontimeupdate', 'ontoggle', 'onvolumechange', 'onwaiting' + ]) + + for attributes in tag_dict.values(): + attributes.extend(global_attributes) + + # Remove `dir` attribute from `bdi` key, because it is *not* inherited + # from the global attributes + if 'bdi' in tag_dict: + tag_dict['bdi'] = [attr for attr in tag_dict['bdi'] if attr != 'dir'] + + return tag_dict + + +class HtmlTagCompletions(sublime_plugin.EventListener): + """ + Provide tag completions for HTML + It matches just after typing the first letter of a tag name + """ + def __init__(self): + completion_list = self.default_completion_list() + self.prefix_completion_dict = {} + # construct a dictionary where the key is first character of + # the completion list to the completion + for s in completion_list: + prefix = s[0][0] + self.prefix_completion_dict.setdefault(prefix, []).append(s) + + # construct a dictionary from (tag, attribute[0]) -> [attribute] + self.tag_to_attributes = get_tag_to_attributes() + + def on_query_completions(self, view, prefix, locations): + # Only trigger within HTML + if not view.match_selector(locations[0], "text.html - (source - source text.html)" + " - string.quoted - meta.tag.style.end punctuation.definition.tag.begin"): + return [] + + # check if we are inside a tag + is_inside_tag = view.match_selector(locations[0], + "text.html meta.tag - text.html punctuation.definition.tag.begin") + + return self.get_completions(view, prefix, locations, is_inside_tag) + + def get_completions(self, view, prefix, locations, is_inside_tag): + # see if it is in tag.attr or tag#attr format + if not is_inside_tag: + tag_attr_expr = self.expand_tag_attributes(view, locations) + if tag_attr_expr != []: + return (tag_attr_expr, sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS) + + pt = locations[0] - len(prefix) - 1 + ch = view.substr(sublime.Region(pt, pt + 1)) + + # print('prefix:', prefix) + # print('location0:', locations[0]) + # print('substr:', view.substr(sublime.Region(locations[0], locations[0] + 3)), '!end!') + # print('is_inside_tag', is_inside_tag) + # print('ch:', ch) + + completion_list = [] + if is_inside_tag and ch != '<': + if ch in [' ', '\t', '\n']: + # maybe trying to type an attribute + completion_list = self.get_attribute_completions(view, locations[0], prefix) + # only ever trigger completion inside a tag if the previous character is a < + # this is needed to stop completion from happening when typing attributes + return (completion_list, sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS) + + if prefix == '': + # need completion list to match + return ([], sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS) + + # match completion list using prefix + completion_list = self.prefix_completion_dict.get(prefix[0], []) + + # if the opening < is not here insert that + if ch != '<': + completion_list = [(pair[0], '<' + pair[1]) for pair in completion_list] + + flags = 0 + if is_inside_tag: + flags = sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS + + return (completion_list, flags) + + def default_completion_list(self): + """ + Generate a default completion list for HTML + """ + default_list = [] + normal_tags = ([ + 'abbr', 'acronym', 'address', 'applet', 'article', 'aside', + 'audio', 'b', 'basefont', 'bdi', 'bdo', 'big', 'blockquote', + 'body', 'button', 'center', 'canvas', 'caption', 'cdata', + 'cite', 'colgroup', 'code', 'content', 'data', 'datalist', + 'dir', 'div', 'dd', 'del', 'details', 'dfn', 'dl', 'dt', 'element', + 'em', 'embed', 'fieldset', 'figure', 'figcaption', 'font', 'footer', + 'form', 'frame', 'frameset', 'head', 'header', 'h1', 'h2', 'h3', + 'h4', 'h5', 'h6', 'i', 'ins', 'isindex', 'kbd', 'keygen', + 'li', 'label', 'legend', 'main', 'map', 'mark', 'meter', + 'nav', 'noframes', 'noscript', 'object', 'ol', 'optgroup', + 'option', 'output', 'p', 'picture', 'pre', 'q', 'rp', + 'rt', 'rtc', 'ruby', 's', 'samp', 'section', 'select', 'shadow', + 'small', 'span', 'strong', 'sub', 'summary', 'sup', + 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', + 'thead', 'time', 'title', 'tr', 'tt', 'u', 'ul', 'var', + 'video' + ]) + + for tag in normal_tags: + default_list.append(make_completion(tag)) + default_list.append(make_completion(tag.upper())) + + default_list += ([ + ('a\tTag', 'a href=\"$1\">$0</a>'), + ('area\tTag', 'area shape=\"$1\" coords=\"$2\" href=\"$3\">'), + ('audio\tTag', 'audio src=\"$1\">$0</audio>'), + ('base\tTag', 'base href=\"$1\">'), + ('br\tTag', 'br>'), + ('col\tTag', 'col>'), + ('hr\tTag', 'hr>'), + ('iframe\tTag', 'iframe src=\"$1\">$0</iframe>'), + ('input\tTag', 'input type=\"$1\" name=\"$2\">'), + ('img\tTag', 'img src=\"$1\">'), + ('link\tTag', 'link rel=\"stylesheet\" type=\"text/css\" href=\"$1\">'), + ('meta\tTag', 'meta ${1:charset=\"utf-8\"}>'), + ('param\tTag', 'param name=\"$1\" value=\"$2\">'), + ('progress\tTag', 'progress value=\"$1\" max=\"$2\">'), + ('script\tTag', 'script${2: type=\"${1:text/javascript}\"}>$0</script>'), + ('source\tTag', 'source src=\"$1\" type=\"$2\">'), + ('style\tTag', 'style type=\"${1:text/css}\">$0</style>'), + ('track\tTag', 'track kind=\"$1\" src=\"$2\">'), + ('wbr\tTag', 'wbr>'), + ('video\tTag', 'video src=\"$1\">$0</video>') + ]) + + return default_list + + # This responds to on_query_completions, but conceptually it's expanding + # expressions, rather than completing words. + # + # It expands these simple expressions: + # tag.class + # tag#id + def expand_tag_attributes(self, view, locations): + # Get the contents of each line, from the beginning of the line to + # each point + lines = [view.substr(sublime.Region(view.line(l).a, l)) + for l in locations] + + # Reverse the contents of each line, to simulate having the regex + # match backwards + lines = [l[::-1] for l in lines] + + # Check the first location looks like an expression + rex = re.compile("([\w-]+)([.#])(\w+)") + expr = match(rex, lines[0]) + if not expr: + return [] + + # Ensure that all other lines have identical expressions + for i in range(1, len(lines)): + ex = match(rex, lines[i]) + if ex != expr: + return [] + + # Return the completions + arg, op, tag = rex.match(expr).groups() + + arg = arg[::-1] + tag = tag[::-1] + expr = expr[::-1] + + if op == '.': + snippet = '<{0} class=\"{1}\">$1</{0}>$0'.format(tag, arg) + else: + snippet = '<{0} id=\"{1}\">$1</{0}>$0'.format(tag, arg) + + return [(expr, snippet)] + + def get_attribute_completions(self, view, pt, prefix): + SEARCH_LIMIT = 500 + search_start = max(0, pt - SEARCH_LIMIT - len(prefix)) + line = view.substr(sublime.Region(search_start, pt + SEARCH_LIMIT)) + + line_head = line[0:pt - search_start] + line_tail = line[pt - search_start:] + + # find the tag from end of line_head + i = len(line_head) - 1 + tag = None + space_index = len(line_head) + while i >= 0: + c = line_head[i] + if c == '<': + # found the open tag + tag = line_head[i + 1:space_index] + break + elif c == ' ': + space_index = i + i -= 1 + + # check that this tag looks valid + if not tag or not tag.isalnum(): + return [] + + # determines whether we need to close the tag + # default to closing the tag + suffix = '>' + + for c in line_tail: + if c == '>': + # found end tag + suffix = '' + break + elif c == '<': + # found another open tag, need to close this one + break + + if suffix == '' and not line_tail.startswith(' ') and not line_tail.startswith('>'): + # add a space if not there + suffix = ' ' + + # got the tag, now find all attributes that match + attributes = self.tag_to_attributes.get(tag, []) + # ("class\tAttr", "class="$1">"), + attri_completions = [(a + '\tAttr', a + '="$1"' + suffix) for a in attributes] + return attri_completions + + +# unit testing +# to run it in sublime text: +# import HTML.html_completions +# HTML.html_completions.Unittest.run() + +import unittest + +class Unittest(unittest.TestCase): + + class Sublime: + INHIBIT_WORD_COMPLETIONS = 1 + INHIBIT_EXPLICIT_COMPLETIONS = 2 + + # this view contains a hard coded one line super simple HTML fragment + class View: + def __init__(self): + self.buf = '<tr><td class="a">td.class</td></tr>' + + def line(self, pt): + # only ever 1 line + return sublime.Region(0, len(self.buf)) + + def substr(self, region): + return self.buf[region.a : region.b] + + def run(): + # redefine the modules to use the mock version + global sublime + + sublime_module = sublime + # use the normal region + Unittest.Sublime.Region = sublime.Region + sublime = Unittest.Sublime + + test = Unittest() + test.test_simple_completion() + test.test_inside_tag_completion() + test.test_inside_tag_no_completion() + test.test_expand_tag_attributes() + + # set it back after testing + sublime = sublime_module + + # def get_completions(self, view, prefix, locations, is_inside_tag): + def test_simple_completion(self): + # <tr><td class="a">td.class</td></tr> + view = Unittest.View() + completor = HtmlTagCompletions() + + # simulate typing 'tab' at the start of the line, it is outside a tag + completion_list, flags = completor.get_completions(view, 'tab', [0], False) + + # should give a bunch of tags that starts with t + self.assertEqual(completion_list[0], ('table\tTag', '<table>$0</table>')) + self.assertEqual(completion_list[1], ('tbody\tTag', '<tbody>$0</tbody>')) + # don't suppress word based completion + self.assertEqual(flags, 0) + + def test_inside_tag_completion(self): + # <tr><td class="a">td.class</td></tr> + view = Unittest.View() + completor = HtmlTagCompletions() + + # simulate typing 'h' after <tr><, i.e. <tr><h + completion_list, flags = completor.get_completions(view, 'h', [6], True) + + # should give a bunch of tags that starts with h, and without < + self.assertEqual(completion_list[0], ('head\tTag', 'head>$0</head>')) + self.assertEqual(completion_list[1], ('header\tTag', 'header>$0</header>')) + self.assertEqual(completion_list[2], ('h1\tTag', 'h1>$0</h1>')) + # suppress word based completion + self.assertEqual(flags, sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS) + + # simulate typing 'he' after <tr><, i.e. <tr><he + completion_list, flags = completor.get_completions(view, 'he', [7], True) + + # should give a bunch of tags that starts with h, and without < (it filters only on the first letter of the prefix) + self.assertEqual(completion_list[0], ('head\tTag', 'head>$0</head>')) + self.assertEqual(completion_list[1], ('header\tTag', 'header>$0</header>')) + self.assertEqual(completion_list[2], ('h1\tTag', 'h1>$0</h1>')) + # suppress word based completion + self.assertEqual(flags, sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS) + + def test_inside_tag_no_completion(self): + # <tr><td class="a">td.class</td></tr> + view = Unittest.View() + completor = HtmlTagCompletions() + + # simulate typing 'h' after <tr><td , i.e. <tr><td h + completion_list, flags = completor.get_completions(view, 'h', [8], True) + + # should give nothing, but disable word based completions, since it is inside a tag + self.assertEqual(completion_list, []) + self.assertEqual(flags, sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS) + + def test_expand_tag_attributes(self): + # <tr><td class="a">td.class</td></tr> + view = Unittest.View() + completor = HtmlTagCompletions() + + # simulate typing tab after td.class + completion_list, flags = completor.get_completions(view, '', [26], False) + + # should give just one completion, and suppress word based completion + self.assertEqual(completion_list, [('td.class', '<td class="class">$1</td>$0')]) + self.assertEqual(flags, sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS) diff --git a/syntaxes/HTML/syntax_test_html.html b/syntaxes/HTML/syntax_test_html.html @@ -0,0 +1,639 @@ +## SYNTAX TEST "Packages/HTML/HTML.sublime-syntax" +<?xml version="1.0" encoding="utf-8"?> +## <- meta.tag.preprocessor punctuation.definition.tag.begin +##^^^entity.name.tag.xml +## ^ punctuation.definition.tag.end +<!DOCTYPE html SYSTEM "html5.dtd" [ <!-- comment --> +## <- meta.tag.sgml.doctype punctuation.definition.tag.begin +##^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.sgml.doctype +##^^^^^^^ keyword.declaration.doctype +## ^^^^ constant.language.doctype +## ^^^^^^ keyword.content.external +## ^^^^^^^^^^^ string.quoted.double +## ^ meta.brackets meta.internal-subset punctuation.section.brackets.begin +## ^^^^^^^^^^^^^^^^ comment.block +## ^^^^ punctuation.definition.comment.begin +## ^^^ punctuation.definition.comment.end + <!ENTITY name "&#160;">; +## ^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.sgml.doctype meta.brackets meta.internal-subset +]> +## <- meta.tag.sgml.doctype meta.brackets meta.internal-subset punctuation.section.brackets.end +<html> + <head> + <title>Test HTML</title> + + <script> <!-- + ## ^^^^^ meta.tag.script.begin.html + ## ^ entity.name.tag.script - source.js.embedded.html + ## ^^^^ comment.block.html punctuation.definition.comment.begin.html + var foo = 100; + var baz = function() { + ## <- entity.name.function.js + } + + (a --> b); + ## ^^^ source.js.embedded.html meta.group.js keyword.operator + --> </script> + ## <- comment.block.html punctuation.definition.comment.end.html + ## ^^^^^^ entity.name.tag.script.html + ## ^^^^^^^^^ meta.tag.script.end.html - source.js.embedded.html + ## ^ - meta.tag + + <script type="text/javascript"> <!-- + ## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.script.begin.html + ## ^ entity.name.tag.script - source.js.embedded.html + ## ^ string.quoted.double.html - source.js.embedded.html + ## ^^^^ comment.block.html punctuation.definition.comment.begin.html + var foo = 100; + var baz = function() { + ## <- entity.name.function.js + } + + (a --> b); + ## ^^^ source.js.embedded.html meta.group.js keyword.operator + --> </script> + ## <- comment.block.html punctuation.definition.comment.end.html + ## ^^^^^^ entity.name.tag.script.html + ## ^^^^^^^^^ meta.tag.script.end.html - source.js.embedded.html + ## ^ - meta.tag + + <script + type + = + application/jAvAsCrIpT> + var foo = 100; + ## ^^^^^^^^^^^^^^^ source.js.embedded + </script> + + <script type = "text/html"> <!-- + ## ^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.script.begin.html + ## ^ entity.name.tag.script - text.html.embedded.html + ## ^ string.quoted.double.html - text.html.embedded.html + ## ^^^^ comment.block.html punctuation + comment --> + ## ^^^^^^^^^^^ text.html.embedded.html comment.block.html + <div></div> + ## ^^^^^^^^^^^ text.html.basic text.html.embedded meta.tag.block.any + <script type=text/javascript> + ## ^ text.html.basic text.html.embedded.html - source.js.embedded.html + function test() {} + ## ^ text.html.basic text.html.embedded.html source.js.embedded.html + </script> + ## ^^^^^^^^^ text.html.basic text.html.embedded.html meta.tag.script.end + </script> +## ^ text.html.basic text.html.embedded.html +## ^^^^^^^^^ text.html.basic - text.html.embedded.html meta.tag.script.end +## ^ text.html.basic - text.html.embedded.html + + <script>42</script > +## ^^^^^^^^ meta.tag.script.begin +## ^^ source.js.embedded +## ^^^^^^^^^^ meta.tag.script.end + + <script + type + = + 'other' + > + var foo = 100; + ## ^^^^^^^^^^^^^^^ - source.js + </script> + + <style type="text/css"> + ## ^^^^^^^^^^^^^^^^^^^^ meta.tag.style.begin.html + ## ^ entity.name.tag.style.html + ## ^^^^^^^^^^^^^^^^^^^^ - source.css.embedded.html + ## ^ entity.other.attribute-name + ## ^ - meta.tag + h2 { + ## <- entity.name.tag.css +## <- source.css.embedded.html + font-family: "Arial"; + ## ^ string.quoted.double.css + } + </style> + ##^^^^^ entity.name.tag.style.html + ##<- meta.tag.style.end.html - source.css.embedded.html + ##^^^^^^ meta.tag.style.end.html - source.css.embedded.html + ## ^ - meta.tag + + <style + type + = + text/css> + div {} + ## ^^^^^^ source.css.embedded + </style> + + <style + type + = + text/csss> + div {} + ## ^^^^^^ - source.css + </style> + + <style /> + ## ^ - source.css.embedded.html + ## ^ meta.tag.style entity.name.tag.style + <script /> + ## ^ - source.js.embedded.html + ## ^ meta.tag.script entity.name.tag.script + </head> + <body> + + <![CDATA[<!DOCTYPE catalog plist "dtd">]]> +## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.sgml.cdata +## ^^^ punctuation.definition.tag.begin +## ^^^^^ keyword.declaration.cdata +## ^ punctuation.definition.tag.begin +## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.cdata +## ^ - string.unquoted.cdata +## ^^^ punctuation.definition.tag.end + <![CDATA[ +## ^^^^^^^^^^ meta.tag.sgml.cdata +## ^^^ punctuation.definition.tag.begin +## ^^^^^ keyword.declaration.cdata +## ^ punctuation.definition.tag.begin + <!DOCTYPE catalog plist "dtd"> +## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.cdata + ]]> +## ^ - string.unquoted.cdata +## ^^^ punctuation.definition.tag.end + + <![CDATA[ + <![CDATA[ unparsed! ]]> +## ^^^^^^^^^^^^^^^^^^^^ string.unquoted.cdata +## ^^^ - punctuation.definition.tag.begin +## ^^^^^ - keyword.declaration.cdata +## ^ - punctuation.definition.tag.begin +## ^^^ punctuation.definition.tag.end + ]]> +## ^^^ - punctuation.definition.tag.end - illegal + + <code>]]></code> +## ^^^ - punctuation.definition.tag.end - illegal + + <!-- Comment --> +## ^^^^^^^^^^^^^^^^ comment.block.html +## ^^^^ punctuation.definition.comment.begin.html +## ^^^ punctuation.definition.comment.end.html +## ^^^^^^^^^ - punctuation + + <!----- hyphens - -- --- --> +## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block - invalid.illegal.bad-comments-or-CDATA + + <!-->-- hyphens <!-- --!> <!---> +## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block +## ^ invalid.illegal.bad-comments-or-CDATA +## ^^^^ invalid.illegal.bad-comments-or-CDATA +## ^^^^ invalid.illegal.bad-comments-or-CDATA +## ^^^ invalid.illegal.bad-comments-or-CDATA + + <!--->- hyphens <!- -!> <!--> +## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block +## ^^ invalid.illegal.bad-comments-or-CDATA +## ^^^^^^^^^^^^^^^ - invalid.illegal.bad-comments-or-CDATA + + <script type=html/text/> + ## ^ - meta.attribute-with-value + ## ^^^^ entity.other.attribute-name + ## ^^^^^^^^^^^^^^ meta.attribute-with-value + ## ^^^^^^^^^ string.unquoted + ## ^^ punctuation.definition.tag.end.html + + <img title/> + ## ^ - meta.attribute-with-value + ## ^^^^^ entity.other.attribute-name + ## ^^^^^ meta.attribute-with-value + ## ^^ punctuation.definition.tag.end.html + + <img src=//> + ## ^ - meta.attribute-with-value + ## ^^^ entity.other.attribute-name + ## ^^^^^ meta.attribute-with-value + ## ^ string.unquoted.html + ## ^^ punctuation.definition.tag.end.html + + <img src=/f̱oo⏡/bar/baz//> + ## ^ - meta.attribute-with-value + ## ^^^ entity.other.attribute-name + ## ^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value + ## ^^^^^^^^^^^^^^^ string.unquoted + ## ^^ punctuation.definition.tag.end.html + + <img src=/f̱oo⏡/bar/baz/ /> + ## ^ - meta.attribute-with-value + ## ^^^ entity.other.attribute-name + ## ^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value + ## ^^^^^^^^^^^^^^^ string.unquoted + ## ^ - meta.attribute-with-value + ## ^^ punctuation.definition.tag.end.html + + <img title=foo"/> + ## ^ - meta.attribute-with-value + ## ^^^^^ entity.other.attribute-name + ## ^^^^^^^^^^ meta.attribute-with-value + ## ^^^^ string.unquoted.html + ## ^ invalid.illegal.attribute-value.html + ## ^^ punctuation.definition.tag.end.html + + <img title=/f̱oo⏡/"bar"/baz//> + ## ^ - meta.attribute-with-value + ## ^^^^^ entity.other.attribute-name + ## ^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value + ## ^^^^^^^^^^^^^^^^^ string.unquoted.html + ## ^ invalid.illegal.attribute-value.html + ## ^ invalid.illegal.attribute-value.html + ## ^^ punctuation.definition.tag.end.html + + <div title=description></div> + ## ^ - meta.attribute-with-value + ## ^^^^^ entity.other.attribute-name + ## ^^^^^^^^^^^^^^^^^ meta.attribute-with-value + ## ^^^^^^^^^^^ string.unquoted + +<div +title="description"></div> +## <- entity.other.attribute-name + +<div +title = "description"></div> +## <- entity.other.attribute-name +## ^ punctuation.separator.key-value.html +## ^^^^^^^^^^^^^ string + +<div title= + "description"></div> +## ^^^^^^^^^^^^^ string + +<div title + ="description"></div> +## ^ punctuation.separator.key-value +## ^^^^^^^^^^^^^ string + +<div title="description" +class="foo"></div> +## <- entity.other.attribute-name.class + + <div title='description'></div> + ## ^ - meta.attribute-with-value + ## ^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value + ## ^^^^^ entity.other.attribute-name + ## ^^^^^^^^^^^^^ string.quoted.single + ## ^ punctuation.definition.string.begin + ## ^ punctuation.definition.string.end + + <div title="description"></div> + ## ^ - meta.attribute-with-value + ## ^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value + ## ^^^^^ entity.other.attribute-name + ## ^^^^^^^^^^^^^ string.quoted.double + ## ^ punctuation.definition.string.begin + ## ^ punctuation.definition.string.end + + <div id=MyId></div> + ## ^ - meta.attribute-with-value.id + ## ^^ entity.other.attribute-name.id + ## ^^^^^^^ meta.attribute-with-value.id + ## ^^^^ string.unquoted meta.toc-list.id + + <div id=My&#x49;d></div> + ## ^ - meta.attribute-with-value.id + ## ^^ entity.other.attribute-name.id + ## ^^^^^^^^^^^^ meta.attribute-with-value.id + ## ^^^^^^^^^ string.unquoted meta.toc-list.id + ## ^^^^^^ constant.character.entity.hexadecimal + + <div id='MyId2'></div> + ## ^ - meta.attribute-with-value.id + ## ^^^^^^^^^^ meta.attribute-with-value.id + ## ^^ entity.other.attribute-name.id + ## ^^^^^^^ string.quoted.single + ## ^ punctuation.definition.string.begin - meta.toc-list.id + ## ^^^^^ meta.toc-list.id + ## ^ punctuation.definition.string.end - meta.toc-list.id + + <div id="ElementID"></div> + ## ^ - meta.attribute-with-value.id + ## ^^^^^^^^^^ meta.attribute-with-value.id + ## ^^ entity.other.attribute-name.id + ## ^^^^^^^^^^^ string.quoted.double + ## ^ punctuation.definition.string.begin - meta.toc-list.id + ## ^^^^^^^^^ meta.toc-list.id + ## ^ punctuation.definition.string.end - meta.toc-list.id + + <div id=el-&foo;" bar&baz;></div> + ## ^ - meta.attribute-with-value.id + ## ^^ entity.other.attribute-name.id + ## ^^^^^^^^^^^^ meta.attribute-with-value.id + ## ^^^^^^^^^ string.unquoted meta.toc-list.id + ## ^^^^^ constant.character.entity.named + ## ^ invalid.illegal.attribute-value.html + ## ^ - meta.attribute-with-value - entity - constant - string - punctuation + ## ^^^^^^^^ meta.attribute-with-value entity.other.attribute-name + + <div id='el-&foo;" bar&baz;'></div> + ## ^ - meta.attribute-with-value.id + ## ^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.id + ## ^^ entity.other.attribute-name.id + ## ^^^^^^^^^^^^^^^^^^^^ string.quoted.single + ## ^ punctuation.definition.string.begin - meta.toc-list.id + ## ^^^^^^^^^ meta.toc-list.id + ## ^^^^^ constant.character.entity + ## ^ - meta.toc-list.id + ## ^^^^^^^^ meta.toc-list.id + ## ^^^^^ constant.character.entity + ## ^ punctuation.definition.string.end - meta.toc-list.id + + <div id="el-&foo;' bar&baz;"></div> + ## ^ - meta.attribute-with-value.id + ## ^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.id + ## ^^ entity.other.attribute-name.id + ## ^^^^^^^^^^^^^^^^^^^^ string.quoted.double + ## ^ punctuation.definition.string.begin - meta.toc-list.id + ## ^^^^^^^^^ meta.toc-list.id + ## ^^^^^ constant.character.entity + ## ^ - meta.toc-list.id + ## ^^^^^^^^ meta.toc-list.id + ## ^^^^^ constant.character.entity + ## ^ punctuation.definition.string.end - meta.toc-list.id + + <div class=element-class></div> + ## ^ - meta.attribute-with-value.class + ## ^^^^^ entity.other.attribute-name.class + ## ^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.class + ## ^^^^^^^^^^^^^ string.unquoted meta.class-name + + <div class=element&#xAD;class></div> + ## ^ - meta.attribute-with-value.class + ## ^^^^^ entity.other.attribute-name.class + ## ^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.class + ## ^^^^^^^^^^^^^^^^^^ string.unquoted meta.class-name + ## ^^^^^^ constant.character.entity.hexadecimal + + <div class='element-class'></div> + ## ^ - meta.attribute-with-value.class + ## ^^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.class + ## ^^^^^ entity.other.attribute-name.class + ## ^^^^^^^^^^^^^^^ string.quoted.single + ## ^ punctuation.definition.string.begin - meta.class-name + ## ^^^^^^^^^^^^^ meta.class-name + ## ^ punctuation.definition.string.end - meta.class-name + + <div class="element-class"></div> + ## ^ - meta.attribute-with-value.class + ## ^^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.class + ## ^^^^^ entity.other.attribute-name.class + ## ^^^^^^^^^^^^^^^ string.quoted.double + ## ^ punctuation.definition.string.begin - meta.class-name + ## ^^^^^^^^^^^^^ meta.class-name + ## ^ punctuation.definition.string.end - meta.class-name + + <div class=el-&foo;" bar&baz;></div> + ## ^ - meta.attribute-with-value.class + ## ^^^^^ entity.other.attribute-name.class + ## ^^^^^^^^^^^^^^^ meta.attribute-with-value.class + ## ^^^^^^^^^ string.unquoted meta.class-name + ## ^^^^^ constant.character.entity.named + ## ^ invalid.illegal.attribute-value.html + ## ^ - meta.attribute-with-value - entity - constant - string - punctuation + ## ^^^^^^^^ meta.attribute-with-value entity.other.attribute-name + + <div class='el-&foo;" bar&baz;'></div> + ## ^ - meta.attribute-with-value.class + ## ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.class + ## ^^^^^ entity.other.attribute-name.class + ## ^^^^^^^^^^^^^^^^^^^^ string.quoted.single + ## ^ punctuation.definition.string.begin - meta.class-name + ## ^^^^^^^^^ meta.class-name + ## ^^^^^ constant.character.entity + ## ^ - meta.class-name + ## ^^^^^^^^ meta.class-name + ## ^^^^^ constant.character.entity + ## ^ punctuation.definition.string.end - meta.class-name + + <div class="el-&foo;' bar&baz;"></div> + ## ^ - meta.attribute-with-value.class + ## ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.class + ## ^^^^^ entity.other.attribute-name.class + ## ^^^^^^^^^^^^^^^^^^^^ string.quoted.double + ## ^ punctuation.definition.string.begin - meta.class-name + ## ^^^^^^^^^ meta.class-name + ## ^^^^^ constant.character.entity + ## ^ - meta.class-name + ## ^^^^^^^^ meta.class-name + ## ^^^^^ constant.character.entity + ## ^ punctuation.definition.string.end - meta.class-name + + <div style="width: 100%"></div> + ## ^ - meta.attribute-with-value.style + ## ^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.style + ## ^^^^^ meta.attribute-with-value.style.html entity.other.attribute-name.style.html + ## ^ punctuation.definition.string.begin.html - source.css + ## ^^^^^^^^^^^ source.css + ## ^ punctuation.definition.string.end.html - source.css + ## ^^^^^ meta.property-name.css support.type.property-name.css + ## ^^^^ meta.property-value.css constant.numeric.integer.decimal.css + + <div style='width: 100%;'></div> + ## ^ - meta.attribute-with-value.style + ## ^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.style + ## ^^^^^ meta.attribute-with-value.style.html entity.other.attribute-name.style.html + ## ^ punctuation.definition.string.begin.html - source.css + ## ^ punctuation.definition.string.end.html - source.css + ## ^^^^^^^^^^^^ source.css + ## ^^^^^ meta.property-name.css support.type.property-name.css + ## ^^^^ meta.property-value.css constant.numeric.integer.decimal.css + + <tag attr otherattr attr-with-dashes attr_with_underscores attr.with.dot attr.with.dot.value="val"></tag> + ## ^ entity.other.attribute-name.html + ## ^ entity.other.attribute-name.html + ## ^ entity.other.attribute-name.html + ## ^ entity.other.attribute-name.html + ## ^^^^^^^^^^^^^ entity.other.attribute-name.html + ## ^^^^^^^^^^^^^^^^^^^ entity.other.attribute-name.html + + <tag "f'o`o<bar"="bar"></tag> + ## ^^^^^^^^^^^^^^^^^ meta.attribute-with-value.html + ## ^^^^^^^^^^^ entity.other.attribute-name.html + ## ^ invalid.illegal.attribute-name.html + ## ^ invalid.illegal.attribute-name.html + ## ^ invalid.illegal.attribute-name.html + ## ^ invalid.illegal.attribute-name.html + ## ^ invalid.illegal.attribute-name.html + + <tag *([&\=></tag> + ## ^^^^^^^ - invalid + ## ^^^^^ entity.other.attribute-name + ## ^ punctuation.separator.key-value + + <tag foo bar></tag>Mind the tab character! + ## ^^^ entity.other.attribute-name + ## ^ - entity.other.attribute-name + ## ^^^ entity.other.attribute-name + + <tag foo=a bar=b></tag> + ## ^^^ entity.other.attribute-name + ## ^ string.unquoted + ## ^^^ entity.other.attribute-name + ## ^ string.unquoted + + <a disabled onclick="setTimeout(function(){}, 100)">Test</a> + ## ^ - meta.attribute-with-value.event + ## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.event + ## ^ - source.js + ## ^ - source.js + ## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.js + ## ^ meta.function-call.js support.function + ## ^^^^^^^^ entity.other.attribute-name + + <article><span><othertag></othertag><othertag /></span></article> + ## ^^^^^ entity.name.tag.block.any.html + ## ^^^^ entity.name.tag.inline.any.html + ## ^^^^^^^^ entity.name.tag.other.html + ## ^ - punctuation.definition.tag.end.html + ## ^^ meta.tag.other.html punctuation.definition.tag.end.html + + <body·other attrib=1/> + ## ^^^^^^^^ entity.name.tag.other.html + ## ^^^^^^ entity.other.attribute-name.html + + <xsl:tag></xsl:tag> + ##^^^^^^ entity.name.tag.other.html + ## ^^^^^^^ entity.name.tag.other.html + + <t*([&/> + ##^^^^ entity.name.tag.other.html + ## ^^ punctuation.definition.tag.end.html + + <t*℗[& *([&\="₦"></t*([&> + ##^^^^ entity.name.tag.other.html + ##^^^^^^^^^^^^^^^^^^^^^^^ - invalid + ## ^^^^^ entity.other.attribute-name.html + ## ^ punctuation.separator.key-value.html + ## ^^^ string.quoted.double.html + ## ^ punctuation.definition.tag.end.html + ## ^^ punctuation.definition.tag.begin.html + ## ^^^^^ entity.name.tag.other.html + ## ^ punctuation.definition.tag.end.html + + <form-custom-tag><div-custom-tag><span-custom-tag></span-custom-tag></div-custom-tag></form-custom-tag> + ##^^^^^^^^^^^^^^ entity.name.tag.custom.html + ## ^^^^^^^^^^^^^^ entity.name.tag.custom.html + ## ^^^^^^^^^^^^^^^ entity.name.tag.custom.html + ## ^^^^^^^^^^^^^^^ entity.name.tag.custom.html + ## ^^^^^^^^^^^^^^ entity.name.tag.custom.html + + <test-custom-tag/> + ##^^^^^^^^^^^^^^^^ meta.tag.custom.html + ## ^^ punctuation.definition.tag.end.html + ## ^ - meta.tag.custom.html - punctuation.definition.tag.end.html + + <body-custom·tag₡name/> + ## ^^^^^^^^^^^^^^^^^^ entity.name.tag.custom.html + + <INVALID-custom-TAG></INVALID-CUSTOM-TAG> + ## ^^^^^ invalid.illegal.custom-tag-name.html + ## ^^^^^^ - invalid.illegal.custom-tag-name.html + ## ^^^ invalid.illegal.custom-tag-name.html + ## ^^^^^^^ invalid.illegal.custom-tag-name.html + ## ^^^^^^ invalid.illegal.custom-tag-name.html + ## ^^^ invalid.illegal.custom-tag-name.html + + <form name="formName" type="post"> + ## ^ entity.name.tag.block.form.html + ## <- punctuation.definition.tag.begin.html + ## ^ punctuation.definition.tag.end.html + <label for="inputId"> + ## ^ entity.name.tag.inline.form.html + ## ^ entity.other.attribute-name.html + ## ^ punctuation.separator.key-value.html + <input id="inputId" type="text" value="value"> + ## ^ entity.name.tag.inline.form.html + ## ^ entity.other.attribute-name.html + <textarea name="texareaName"></textarea> + ## ^ entity.name.tag.inline.form.html + </form> + + <table border="0" cellspacing="0" cellpadding="2" class="editor"> + ## ^ entity.name.tag.inline.table.html + <thead> + ## ^ entity.name.tag.inline.table.html + <tr> + ## ^ entity.name.tag.inline.table.html + <th> </th> + </tr> + </thead> + ## ^ entity.name.tag.inline.table.html + <tfoot> + ## ^ entity.name.tag.inline.table.html + <tr> + <td> </td> + ##^ entity.name.tag.inline.table.html + </tr> + </tfoot> + ## ^ entity.name.tag.inline.table.html + <tbody> + <tr> + <td> </td> + </tr> + </tbody> + </table> + + &amp; +## ^^^^^ constant.character.entity.named +## ^ punctuation.definition.entity +## ^ punctuation.terminator.entity + + &#123; +## ^^^^^^ constant.character.entity.decimal +## ^^ punctuation.definition.entity +## ^ punctuation.terminator.entity + + &#x7f; +## ^^^^^^ constant.character.entity.hexadecimal +## ^^^ punctuation.definition.entity +## ^ punctuation.terminator.entity + + &#X7F; +## ^^^^^^ constant.character.entity.hexadecimal +## ^^^ punctuation.definition.entity +## ^ punctuation.terminator.entity + + &β; +## ^^^ - constant.character.entity + + &#; +## ^^^ - constant.character.entity + + &#x; +## ^^^^ - constant.character.entity + + + <a href="http://google.com/?one=1&amp;two=2"></a> + ## ^^^^^ constant.character.entity + <a href="http://google.com/?one=1&two=2"></a> + ## ^ - constant.character.entity + ## ^ - invalid.illegal + + <hr/><hr /> + ## ^^ meta.tag.block.any punctuation.definition.tag.end + ## ^^ entity.name.tag.block.any + ## ^^ punctuation.definition.tag.end + + # make sure to stop tag names before the next < to prevent php + # and other syntaxes from breaking. + <article<?php> + ##^^^^^^ entity.name.tag.block.any.html + ## ^^^^^^ - entity.name.tag + + <_notag> + ##^^^^^ - entity.name.tag + + <2notag> + ##^^^^^ - entity.name.tag + + </body> + # ^^^^ entity.name.tag.structure +</html> diff --git a/syntaxes/Haskell/Comments.tmPreferences b/syntaxes/Haskell/Comments.tmPreferences @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Comments</string> + <key>scope</key> + <string>source.haskell</string> + <key>settings</key> + <dict> + <key>shellVariables</key> + <array> + <dict> + <key>name</key> + <string>TM_COMMENT_START_2</string> + <key>value</key> + <string>{-</string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_END_2</string> + <key>value</key> + <string>-}</string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_START</string> + <key>value</key> + <string>-- </string> + </dict> + </array> + </dict> +</dict> +</plist> diff --git a/syntaxes/Haskell/Haskell.sublime-build b/syntaxes/Haskell/Haskell.sublime-build @@ -0,0 +1,5 @@ +{ + "shell_cmd": "runhaskell \"$file\"", + "file_regex": "^(...*?):([0-9]*):?([0-9]*)", + "selector": "source.haskell" +} diff --git a/syntaxes/Haskell/Haskell.sublime-syntax b/syntaxes/Haskell/Haskell.sublime-syntax @@ -0,0 +1,253 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: Haskell +file_extensions: + - hs +scope: source.haskell +contexts: + main: + - match: "(`)[a-zA-Z_']*?(`)" + comment: "In case this regex seems unusual for an infix operator, note that Haskell allows any ordinary function application (elem 4 [1..10]) to be rewritten as an infix expression (4 `elem` [1..10])." + scope: keyword.operator.function.infix.haskell + captures: + 1: punctuation.definition.entity.haskell + 2: punctuation.definition.entity.haskell + - match: \(\) + scope: constant.language.unit.haskell + - match: '\[\]' + scope: constant.language.empty-list.haskell + - match: \b(module)\b + captures: + 1: keyword.other.haskell + push: + - meta_scope: meta.declaration.module.haskell + - match: (where) + captures: + 1: keyword.other.haskell + pop: true + - include: module_name + - include: module_exports + - match: "[a-z]+" + scope: invalid + - match: \b(class)\b + captures: + 1: keyword.other.haskell + push: + - meta_scope: meta.declaration.class.haskell + - match: \b(where)\b + captures: + 1: keyword.other.haskell + pop: true + - match: \b(Mon(ad|oid)|Functor|Applicative|(Folda|Traversa)ble|Eq|Ord|Read|Show|Num|(Frac|Ra)tional|Enum|Bounded|Real(Frac|Float)?|Integral|Floating)\b + scope: support.class.prelude.haskell + - match: "[A-Z][A-Za-z_']*" + scope: entity.other.inherited-class.haskell + - match: '\b[a-z][a-zA-Z0-9_'']*\b' + scope: variable.other.generic-type.haskell + - match: \b(instance)\b + captures: + 1: keyword.other.haskell + push: + - meta_scope: meta.declaration.instance.haskell + - match: \b(where)\b|$ + captures: + 1: keyword.other.haskell + pop: true + - include: type_signature + - match: \b(import)\b + captures: + 1: keyword.other.haskell + push: + - meta_scope: meta.import.haskell + - match: ($|;) + pop: true + - match: (qualified|as|hiding) + scope: keyword.other.haskell + - include: module_name + - include: module_exports + - include: comments + - match: (deriving)\s*\( + captures: + 1: keyword.other.haskell + push: + - meta_scope: meta.deriving.haskell + - match: \) + pop: true + - match: '\b[A-Z][a-zA-Z_'']*' + scope: entity.other.inherited-class.haskell + - match: \b(deriving|where|data|type|case|of|let|in|newtype|default)\b + scope: keyword.other.haskell + - match: '\binfix[lr]?\b' + scope: keyword.operator.haskell + - match: \b(do|if|then|else)\b + scope: keyword.control.haskell + - match: \b\d+(?:(\.)\d+(?:[eE][-+]?\d+)?|(?:[eE][-+]?\d+))\b + scope: constant.numeric.float.decimal.haskell + captures: + 1: punctuation.separator.decimal.haskell + - match: \b(0[oO])[0-7]+\b + scope: constant.numeric.integer.octal.haskell + captures: + 1: punctuation.definition.numeric.base.haskell + - match: \b(0[xX])\h+\b + scope: constant.numeric.integer.hexadecimal.haskell + captures: + 1: punctuation.definition.numeric.base.haskell + - match: \b\d+\b + scope: constant.numeric.integer.decimal.haskell + - match: ^\s*(#)\s*\w+ + comment: In addition to Haskell's "native" syntax, GHC permits the C preprocessor to be run on a source file. + scope: meta.preprocessor.c + captures: + 1: punctuation.definition.preprocessor.c + - include: pragma + - match: '"' + scope: punctuation.definition.string.begin.haskell + push: + - meta_scope: string.quoted.double.haskell + - match: $|" + scope: punctuation.definition.string.end.haskell + pop: true + - match: '\\(NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|[abfnrtv\\\"''\&])' + scope: constant.character.escape.haskell + - match: '\\o[0-7]+|\\x[0-9A-Fa-f]+|\\[0-9]+' + scope: constant.character.escape.octal.haskell + - match: '\^[A-Z@\[\]\\\^_]' + scope: constant.character.escape.control.haskell + - match: '\[(?:|e|d|t|p)\|' + comment: Points out splices in ast quotes + scope: keyword.other.quasibracket.haskell + push: + - meta_scope: meta.other.quasiquote.haskell + - match: '(.*)(\|\])' + captures: + 1: string.quasiquoted.haskell + 2: keyword.other.quasibracket.haskell + pop: true + - match: \$\( + scope: keyword.other.splice.haskell + - match: \$ + scope: string.quasiquoted.haskell + - match: "[^$]*" + scope: string.quasiquoted.haskell + - match: \$\( + comment: Highlight the beginning of a splice. + scope: keyword.other.splice.haskell + - match: '\[[a-zA-Z0-9_'']*\|' + scope: keyword.other.quasibracket.haskell + push: + - meta_scope: meta.other.quasiquote.haskell + - match: '(.*)(\|\])' + captures: + 1: string.quasiquoted.haskell + 2: keyword.other.quasibracket.haskell + pop: true + - match: .* + scope: string.quasiquoted.haskell + - match: |- + (?x) + (') + (?: + [\ -\[\]-~] # Basic Char + | (\\(?:NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE + |DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS + |US|SP|DEL|[abfnrtv\\\"'\&])) # Escapes + | (\\o[0-7]+) # Octal Escapes + | (\\x[0-9A-Fa-f]+) # Hexadecimal Escapes + | (\^[A-Z@\[\]\\\^_]) # Control Chars + ) + (') + scope: string.quoted.single.haskell + captures: + 1: punctuation.definition.string.begin.haskell + 2: constant.character.escape.haskell + 3: constant.character.escape.octal.haskell + 4: constant.character.escape.hexadecimal.haskell + 5: constant.character.escape.control.haskell + 6: punctuation.definition.string.end.haskell + - match: '^(\s*)([a-z_][a-zA-Z0-9_'']*|\([|!%$+\-.,=</>]+\))\s*(::|∷)' + captures: + 2: entity.name.function.haskell + 3: keyword.other.double-colon.haskell + push: + - meta_scope: meta.function.type-declaration.haskell + - match: ^(?!\s*(?:--|{-|$)|\1\s) + pop: true + - include: type_signature + - match: '\b[A-Z]\w*\b' + scope: constant.other.haskell + - include: comments + - include: infix_op + - match: '[|!%$?~+:\-.=</>\\]+' + comment: In case this regex seems overly general, note that Haskell permits the definition of new operators which can be nearly any string of punctuation characters, such as $%^&*. + scope: keyword.operator.haskell + - match: "," + scope: punctuation.separator.comma.haskell + block_comment: + - match: '\{-(?!#)' + scope: punctuation.definition.comment.begin.haskell + push: + - meta_scope: comment.block.haskell + - match: '\{-#' + push: + - match: '-\}' + pop: true + - include: block_comment + - include: block_comment + - match: '-\}' + scope: punctuation.definition.comment.end.haskell + pop: true + comments: + - match: '--' + scope: punctuation.definition.comment.haskell + push: + - meta_scope: comment.line.double-dash.haskell + - match: $\n? + pop: true + - include: block_comment + infix_op: + - match: \([-+*/,|!%$:.=<>]+\) + scope: entity.name.function.infix.haskell + module_exports: + - match: \( + push: + - meta_scope: meta.declaration.exports.haskell + - match: \) + pop: true + - match: '\b[a-z][a-zA-Z_''0-9]*' + scope: entity.name.function.haskell + - match: '\b[A-Z][A-Za-z_''0-9]*' + scope: storage.type.haskell + - match: "," + scope: punctuation.separator.comma.haskell + - include: infix_op + - match: \(.*?\) + comment: So named because I don't know what to call this. + scope: meta.other.unknown.haskell + - include: comments + module_name: + - match: "[A-Z][A-Za-z._']*" + scope: support.other.module.haskell + pragma: + - match: '\{-#' + push: + - meta_scope: meta.preprocessor.haskell + - match: '#-\}' + pop: true + - match: \b(LANGUAGE|OPTIONS_GHC|INCLUDE|WARNING|DEPRECATED|MINIMAL|UNPACK|NOUNPACK|SOURCE|OVERLAPPING|OVERLAPPABLE|OVERLAPS|INCOHERENT|INLINE|NOINLINE|INLINABLE|CONLIKE|LINE|RULES|SPECIALIZE|SPECIALISE)\b + # https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#pragmas + scope: keyword.other.preprocessor.haskell + type_signature: + - include: pragma + - match: "(->|→)" + scope: keyword.other.arrow.haskell + - match: "(=>|⇒)" + scope: keyword.other.big-arrow.haskell + - match: '\b[a-z][a-zA-Z0-9_'']*\b' + scope: variable.other.generic-type.haskell + - match: '\b[A-Z][a-zA-Z0-9_'']*\b' + scope: storage.type.haskell + - match: \(\) + scope: support.constant.unit.haskell + - include: comments diff --git a/syntaxes/Haskell/Indent Patterns.tmPreferences b/syntaxes/Haskell/Indent Patterns.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Indent Patterns</string> + <key>scope</key> + <string>source.haskell</string> + <key>settings</key> + <dict> + <key>increaseIndentPattern</key> + <string>((^.*(=|\bdo|\bwhere|\bthen|\belse|\bof)\s*$)|(^.*\bif(?!.*\bthen\b.*\belse\b.*).*$))</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Haskell/Literate Haskell.sublime-syntax b/syntaxes/Haskell/Literate Haskell.sublime-syntax @@ -0,0 +1,50 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: Literate Haskell +file_extensions: + - lhs +scope: text.tex.latex.haskell +contexts: + prototype: + - include: scope:text.tex.latex#comments + + main: + - include: scope:text.tex.latex#unique-latex + - include: scope:text.tex.latex#packages + - include: haskell-code + - include: scope:text.tex.latex#plain-tex + - include: scope:text.tex.latex#begin-end-commands + - include: scope:text.tex.latex#general-commands + - include: global-braces + + global-braces: + - match: '\{' + scope: punctuation.definition.group.brace.begin.latex + push: + - meta_scope: meta.group.brace.latex + - match: '\}' + scope: punctuation.definition.group.brace.end.latex + pop: true + - include: main + + haskell-code: + - match: '(?:\s*)((\\)begin)(\{)(code)(\})' + captures: + 1: support.function.be.latex + 2: punctuation.definition.backslash.latex + 3: punctuation.definition.group.brace.begin.latex + 4: variable.parameter.function.latex + 5: punctuation.definition.group.brace.end.latex + push: + - meta_scope: meta.function.embedded.haskell.latex + - meta_content_scope: source.haskell.embedded.latex + - match: '((\\)end)(\{)(code)(\})' + captures: + 1: support.function.be.latex + 2: punctuation.definition.backslash.latex + 3: punctuation.definition.group.brace.begin.latex + 4: variable.parameter.function.latex + 5: punctuation.definition.group.brace.end.latex + pop: true + - include: scope:source.haskell diff --git a/syntaxes/Haskell/Snippets/Case.sublime-snippet b/syntaxes/Haskell/Snippets/Case.sublime-snippet @@ -0,0 +1,7 @@ +<snippet> + <content><![CDATA[case ${1:a} of ${2:True} -> ${3:$1} + ${1/./ /g} ${4:otherwise} -> ${0:$1}]]></content> + <tabTrigger>case</tabTrigger> + <scope>source.haskell</scope> + <description>Case</description> +</snippet> diff --git a/syntaxes/Haskell/Snippets/Instance.sublime-snippet b/syntaxes/Haskell/Snippets/Instance.sublime-snippet @@ -0,0 +1,7 @@ +<snippet> + <content><![CDATA[instance ${1:Class} ${2:Data} where + ${3:func} = $0]]></content> + <tabTrigger>instance</tabTrigger> + <scope>source.haskell</scope> + <description>Instance</description> +</snippet> diff --git a/syntaxes/Haskell/Snippets/Lambda.sublime-snippet b/syntaxes/Haskell/Snippets/Lambda.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[\\${1:t} -> ${0:f t}]]></content> + <tabTrigger>\</tabTrigger> + <scope>source.haskell</scope> + <description>\t -&gt; f t</description> +</snippet> diff --git a/syntaxes/Haskell/Snippets/Main.sublime-snippet b/syntaxes/Haskell/Snippets/Main.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[module Main where + +main = ${1:putStrLn "Hello World"}]]></content> + <tabTrigger>main</tabTrigger> + <scope>source.haskell</scope> + <description>Main</description> +</snippet> diff --git a/syntaxes/Haskell/Snippets/module.sublime-snippet b/syntaxes/Haskell/Snippets/module.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[module ${1:Main} where + +${2:main = ${3:putStrLn "Hello World"}}]]></content> + <tabTrigger>mod</tabTrigger> + <scope>source.haskell</scope> + <description>Module</description> +</snippet> diff --git a/syntaxes/Haskell/Symbol List.tmPreferences b/syntaxes/Haskell/Symbol List.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List</string> + <key>scope</key> + <string>source.haskell entity.name.function - entity.name.function.infix</string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <string>1</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Haskell/syntax_test_haskell.hs b/syntaxes/Haskell/syntax_test_haskell.hs @@ -0,0 +1,188 @@ +-- SYNTAX TEST "Packages/Haskell/Haskell.sublime-syntax" + +23*36 -- single line comment +-- ^^ punctuation.definition.comment.haskell +-- ^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-dash.haskell +23*36 +-- <- - comment.line.double-dash.haskell + + {- block comment -} 23*36 +-- ^^ punctuation.definition.comment.begin.haskell +-- ^^^^^^^^^^^^^^^^^^^ comment.block.haskell +-- ^^ punctuation.definition.comment.end.haskell +-- ^ - comment.block.haskell + + {- {-# #-} -} 23*36 +-- ^^ punctuation.definition.comment.begin.haskell +-- ^^^^^^^^^^^^^ comment.block.haskell - meta.preprocessor.haskell +-- ^^ punctuation.definition.comment.end.haskell +-- ^ - comment.block.haskell + + {- {- #-} -} 23*36 +-- ^^ punctuation.definition.comment.begin.haskell +-- ^^^^^^^^^^^^ comment.block.haskell +-- ^^ punctuation.definition.comment.end.haskell +-- ^ - comment.block.haskell + + {- {- -} -} 23*36 +-- ^^ punctuation.definition.comment.begin.haskell +-- ^^^^^^^^^^^ comment.block.haskell +-- ^^ punctuation.definition.comment.end.haskell +-- ^ - comment.block.haskell + + {- {-# -} -} 23*36 +-- ^^ punctuation.definition.comment.begin.haskell +-- ^^^^^^^^^^^^ comment.block.haskell - meta.preprocessor.haskell +-- ^^ punctuation.definition.comment.end.haskell +-- ^ - comment.block.haskell + + {- {-# {- test -} -} -} 23*36 +-- ^^ punctuation.definition.comment.begin.haskell +-- ^^^^^^^^^^^^^^^^^^^^^^^ comment.block.haskell - meta.preprocessor.haskell +-- ^^ punctuation.definition.comment.end.haskell +-- ^ - comment.block.haskell + + class (Functor t, Foldable t) => Traversable t where +-- ^^^^^ keyword.other.haskell +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.declaration.class.haskell + {-# MINIMAL traverse | sequenceA LANGUAGE #-} +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell +-- ^ - meta.preprocessor.haskell +-- ^^^^^^^ keyword.other.preprocessor.haskell + +-- | Map each element of a structure to an action, +-- evaluate these actions from left to right, and +-- collect the results. For a version that ignores +-- the results see 'Data.Foldable.traverse_'. +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-dash.haskell + + traverse :: Applicative f => +-- ^^^^^^^^ entity.name.function.haskell +-- ^^ keyword.other.double-colon.haskell +-- ^^^^^^^^^^^ storage.type.haskell +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.type-declaration.haskell +-- ^^ keyword.other.big-arrow.haskell + (a -> f b) +-- ^^^^^^^^^^^^ meta.function.type-declaration.haskell +-- ^^ keyword.other.arrow.haskell + -> t a +-- ^^^^^^^^ meta.function.type-declaration.haskell +-- ^^ keyword.other.arrow.haskell + -> f (t b) +-- ^^^^^^^^^^^^ meta.function.type-declaration.haskell +-- ^^ keyword.other.arrow.haskell + traverse f = sequenceA . fmap f +-- ^ keyword.operator.haskell +-- ^ keyword.operator.haskell + +-- | Evaluate each action in the structure from +-- left to right, and collect the results. +-- For a version that ignores the results see +-- 'Data.Foldable.sequenceA_'. + sequenceA ∷ Applicative f ⇒ t (f a) → f (t a) +-- ^^^^^^^^^ entity.name.function.haskell +-- ^ keyword.other.double-colon.haskell +-- ^^^^^^^^^^^ storage.type.haskell +-- ^ keyword.other.big-arrow.haskell +-- ^ keyword.other.arrow.haskell + sequenceA = traverse id +-- ^ keyword.operator.haskell + +-- +-- infix operators +-- + a a = (+) a 2 +-- ^ keyword.operator.haskell +-- ^^^ entity.name.function.infix.haskell +-- ^ constant.numeric.integer.decimal.haskell + a a = (-) a 2 +-- ^ keyword.operator.haskell +-- ^^^ entity.name.function.infix.haskell +-- ^ constant.numeric.integer.decimal.haskell + a a = (*) a 2 +-- ^ keyword.operator.haskell +-- ^^^ entity.name.function.infix.haskell +-- ^ constant.numeric.integer.decimal.haskell + a a = (/) a 2 +-- ^ keyword.operator.haskell +-- ^^^ entity.name.function.infix.haskell +-- ^ constant.numeric.integer.decimal.haskell + +-- Tests for #1320, #1880. + + class TooMany a where + tooMany :: a -> Bool +-- ^^^^^^^^^^^^^^^^^^^^^^ meta.function.type-declaration.haskell + tooManyToo :: +-- ^^^^^^^^^^^^^^^ meta.function.type-declaration.haskell + a -> Bool +-- ^^^^^^^^^^^^^ meta.function.type-declaration.haskell + + instance TooMany Int where +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.declaration.instance.haskell + tooMany n = n > 42 + + foldBoolGuard :: a -> a -> Bool -> a +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.type-declaration.haskell + foldBoolGuard x y z +-- ^^^^^^^^^^^^^^^^^^^ source.haskell + | z = y +-- ^ keyword.operator.haskell + | otherwise = x + + countTheBeforeVowel :: String + -- This comment should not interrupt the type signature. + + -- The blank line above should not interrupt the type signature. + + {- + This multiline comment should + not interrupt the type signature. + -} + + -> Integer +-- ^^^^^^^^^^^^ meta.function.type-declaration.haskell + countTheBeforeVowel = undefined + + +--NUMBERS + + 0 +-- ^ constant.numeric.integer.decimal + + 1234567890 +-- ^^^^^^^^^^ constant.numeric.integer.decimal + + 0o1234567 +-- ^^^^^^^^^ constant.numeric.integer.octal +-- ^^ punctuation.definition.numeric.base.haskell + + 1. +-- ^ constant.numeric.integer.decimal +-- ^ keyword.operator.haskell + + .2 +-- ^ keyword.operator.haskell +-- ^ constant.numeric.integer.decimal + + 12.345 +-- ^^^^^^ constant.numeric.float.decimal +-- ^ punctuation.separator.decimal + + 1e10 +-- ^^^^ constant.numeric.float.decimal + + 0.5e+0 +-- ^^^^^^ constant.numeric.float.decimal +-- ^ punctuation.separator.decimal + + 9e-1 +-- ^^^^ constant.numeric.float.decimal + + 0x0 +-- ^^^ constant.numeric.integer.hexadecimal +-- ^^ punctuation.definition.numeric.base + + 0XdeafBEEF42 +-- ^^^^^^^^^^^^ constant.numeric.integer.hexadecimal +-- ^^ punctuation.definition.numeric.base diff --git a/syntaxes/Java/Ant.sublime-build b/syntaxes/Java/Ant.sublime-build @@ -0,0 +1,12 @@ +{ + "cmd": ["ant"], + "file_regex": "^ *\\[javac\\] (.+):([0-9]+):() (.*)$", + "working_dir": "${project_path:${folder}}", + "selector": "source.java", + "keyfiles": ["build.xml"], + + "windows": + { + "cmd": ["ant.bat"] + } +} diff --git a/syntaxes/Java/Comments - Properties.tmPreferences b/syntaxes/Java/Comments - Properties.tmPreferences @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Comments - Properties</string> + <key>scope</key> + <string>source.java-props</string> + <key>settings</key> + <dict> + <key>shellVariables</key> + <array> + <dict> + <key>name</key> + <string>TM_COMMENT_START</string> + <key>value</key> + <string># </string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_START_2</string> + <key>value</key> + <string>! </string> + </dict> + </array> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Comments.tmPreferences b/syntaxes/Java/Comments.tmPreferences @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Comments</string> + <key>scope</key> + <string>source.java</string> + <key>settings</key> + <dict> + <key>shellVariables</key> + <array> + <dict> + <key>name</key> + <string>TM_COMMENT_START</string> + <key>value</key> + <string>// </string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_START_2</string> + <key>value</key> + <string>/*</string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_END_2</string> + <key>value</key> + <string>*/</string> + </dict> + </array> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Completion Rules.tmPreferences b/syntaxes/Java/Completion Rules.tmPreferences @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>scope</key> + <string>source.java</string> + <key>settings</key> + <dict> + <key>cancelCompletion</key> + <string>^\s*(\}?\s*(else|try|do|finally)|(class|package|enum)\s*[a-zA-Z_0-9]+*)$</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Indentation Rules Annex.tmPreferences b/syntaxes/Java/Indentation Rules Annex.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Indentation Rules Annex</string> + <key>scope</key> + <string>source.java</string> + <key>settings</key> + <dict> + <key>unIndentedLinePattern</key> + <string>^\s*((\*/|//| \*).*)?$</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Indentation Rules.tmPreferences b/syntaxes/Java/Indentation Rules.tmPreferences @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Indentation Rules</string> + <key>scope</key> + <string>source.java - comment</string> + <key>settings</key> + <dict> + <key>decreaseIndentPattern</key> + <string>^(.*\*/)?\s*\}.*$|^\s*(public|private|protected):\s*$</string> + <key>increaseIndentPattern</key> + <string>^.*\{[^}"']*$|^\s*(public|private|protected):\s*$</string> + + <key>bracketIndentNextLinePattern</key> + <string>(?x) + ^ \s* \b(if|while|else)\b [^;]* $ + | ^ \s* \b(for)\b .* $ + </string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Indexed Symbol List.tmPreferences b/syntaxes/Java/Indexed Symbol List.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List: Classes</string> + <key>scope</key> + <string>source.java entity.name.class.java, source.java entity.name.function.java</string> + <key>settings</key> + <dict> + <key>showInIndexedSymbolList</key> + <integer>1</integer> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Java Server Pages (JSP).sublime-syntax b/syntaxes/Java/Java Server Pages (JSP).sublime-syntax @@ -0,0 +1,87 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: Java Server Page (JSP) +file_extensions: + - jsp +scope: text.html.jsp +contexts: + main: + - match: <%-- + scope: punctuation.definition.comment.jsp + push: + - meta_scope: comment.block.jsp + - match: "--%>" + scope: punctuation.definition.comment.jsp + pop: true + - match: <%@ + scope: punctuation.section.directive.jsp + push: + - meta_scope: meta.directive.jsp + - match: "%>" + scope: punctuation.section.directive.jsp + pop: true + - match: \w+ + scope: keyword.other.directive.jsp + push: + - match: \w+ + scope: constant.other.directive.attribute.jsp + - match: "=" + scope: keyword.operator.assignment.jsp + - match: '"' + scope: punctuation.definition.string.begin.jsp + push: + - meta_scope: string.quoted.double.jsp + - match: '"' + scope: punctuation.definition.string.end.jsp + pop: true + - match: \\. + scope: constant.character.escape.jsp + - match: "'" + scope: punctuation.definition.string.begin.jsp + push: + - meta_scope: string.quoted.single.jsp + - match: "'" + scope: punctuation.definition.string.end.jsp + pop: true + - match: \\. + scope: constant.character.escape.jsp + - match: '(?=\S)' + pop: true + - match: "(<%[!=]?)|(<jsp:scriptlet>|<jsp:expression>|<jsp:declaration>)" + captures: + 1: punctuation.section.embedded.begin.jsp + 2: meta.tag.block.jsp + push: + - match: (</jsp:scriptlet>|</jsp:expression>|</jsp:declaration>)|(%>) + captures: + 1: meta.tag.block.jsp + 2: punctuation.section.embedded.end.jsp + pop: true + - match: '(?<!\n)(?!</jsp:scriptlet>|</jsp:expression>|</jsp:declaration>|%>|\{|\})' + push: + - meta_scope: source.java.embedded.html + - match: '(?=</jsp:scriptlet>|</jsp:expression>|</jsp:declaration>|%>|\{|\})|\n' + pop: true + - include: scope:source.java + - match: "{" + push: + - match: "}" + pop: true + - match: (</jsp:scriptlet>|</jsp:expression>|</jsp:declaration>)|(%>) + captures: + 1: meta.tag.block.jsp + 2: punctuation.section.embedded.end.jsp + push: + - match: "(<jsp:scriptlet>|<jsp:expression>|<jsp:declaration>)|(<%(?!--)[!=]?)" + captures: + 1: meta.tag.block.jsp + 2: punctuation.section.embedded.begin.jsp + pop: true + - include: scope:text.html.jsp + - include: scope:source.java + # Prevent stray brace detection since brace matching won't work with + # %> pop pattern + - match: "}" + - include: scope:source.java + - include: scope:text.html.basic diff --git a/syntaxes/Java/Java.sublime-completions b/syntaxes/Java/Java.sublime-completions @@ -0,0 +1,224 @@ +{ + "scope": "source.java", + + // All the completions with a . are commented out because they cause the autocompletion system to misbehave. + "completions": [ + // Keywords + "abstract", + "continue", + "for", + "new", + "switch", + "assert", + "default", + "goto", + "package", + "synchronized", + "boolean", + "do", + "if", + "private", + "this", + "break", + "double", + "implements", + "protected", + "throw", + "byte", + "else", + "import", + "public", + "throws", + "case", + "enum", + "instanceof", + "return", + "transient", + "catch", + "extends", + "int", + "short", + "try", + "char", + "final", + "interface", + "static", + "void", + "class", + "finally", + "long", + "strictfp", + "volatile", + "const", + "float", + "native", + "super", + "while", + + // Extracted from https://docs.oracle.com/javase/8/docs/api/java/lang/package-summary.html + + // java.lang interfaces + "Appendable", + "AutoCloseable", + "CharSequence", + "Cloneable", + "Comparable", + "Iterable", + "Readable", + "Runnable", + // "Thread.UncaughtExceptionHandler", + + // java.lang Classes + "Boolean", + "Byte", + "Character", + // "Character.Subset", + // "Character.UnicodeBlock", + "Class", + "ClassLoader", + "ClassValue", + "Compiler", + "Double", + "Enum", + "Float", + "InheritableThreadLocal", + "Integer", + "Long", + "Math", + "Number", + "Object", + "Package", + "Process", + "ProcessBuilder", + // "ProcessBuilder.Redirect", + "Runtime", + "RuntimePermission", + "SecurityManager", + "Short", + "StackTraceElement", + "StrictMath", + "String", + "StringBuffer", + "StringBuilder", + "System", + "Thread", + "ThreadGroup", + "ThreadLocal", + "Throwable", + "Void", + + // java.lang Enums + // "Character.UnicodeScript", + // "ProcessBuilder.Redirect.Type", + // "Thread.State", + + // java.lang Exceptions + "ArithmeticException", + "ArrayIndexOutOfBoundsException", + "ArrayStoreException", + "ClassCastException", + "ClassNotFoundException", + "CloneNotSupportedException", + "EnumConstantNotPresentException", + "Exception", + "IllegalAccessException", + "IllegalArgumentException", + "IllegalMonitorStateException", + "IllegalStateException", + "IllegalThreadStateException", + "IndexOutOfBoundsException", + "InstantiationException", + "InterruptedException", + "NegativeArraySizeException", + "NoSuchFieldException", + "NoSuchMethodException", + "NullPointerException", + "NumberFormatException", + "ReflectiveOperationException", + "RuntimeException", + "SecurityException", + "StringIndexOutOfBoundsException", + "TypeNotPresentException", + "UnsupportedOperationException", + + // java.lang Errors + "AbstractMethodError", + "AssertionError", + "BootstrapMethodError", + "ClassCircularityError", + "ClassFormatError", + "Error", + "ExceptionInInitializerError", + "IllegalAccessError", + "IncompatibleClassChangeError", + "InstantiationError", + "InternalError", + "LinkageError", + "NoClassDefFoundError", + "NoSuchFieldError", + "NoSuchMethodError", + "OutOfMemoryError", + "StackOverflowError", + "ThreadDeath", + "UnknownError", + "UnsatisfiedLinkError", + "UnsupportedClassVersionError", + "VerifyError", + "VirtualMachineError", + + // java.lang Annotations + "Deprecated", + "FunctionalInterface", + "Override", + "SafeVarargs", + "SuppressWarnings", + + + // Extracted from https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html + + // java.util.function Interfaces + "BiConsumer", + "BiFunction", + "BinaryOperator", + "BiPredicate", + "BooleanSupplier", + "Consumer", + "DoubleBinaryOperator", + "DoubleConsumer", + "DoubleFunction", + "DoublePredicate", + "DoubleSupplier", + "DoubleToIntFunction", + "DoubleToLongFunction", + "DoubleUnaryOperator", + "Function", + "IntBinaryOperator", + "IntConsumer", + "IntFunction", + "IntPredicate", + "IntSupplier", + "IntToDoubleFunction", + "IntToLongFunction", + "IntUnaryOperator", + "LongBinaryOperator", + "LongConsumer", + "LongFunction", + "LongPredicate", + "LongSupplier", + "LongToDoubleFunction", + "LongToIntFunction", + "LongUnaryOperator", + "ObjDoubleConsumer", + "ObjIntConsumer", + "ObjLongConsumer", + "Predicate", + "Supplier", + "ToDoubleBiFunction", + "ToDoubleFunction", + "ToIntBiFunction", + "ToIntFunction", + "ToLongBiFunction", + "ToLongFunction", + "UnaryOperator" + ] +} diff --git a/syntaxes/Java/Java.sublime-syntax b/syntaxes/Java/Java.sublime-syntax @@ -0,0 +1,1246 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: Java +file_extensions: + - java + - bsh +scope: source.java + +variables: + primitives: (?:boolean|byte|char|short|int|float|long|double) + storage_modifiers: (?:public|private|protected|static|final|native|synchronized|strictfp|abstract|transient|default|volatile) + + id: (?:[\p{L}_$][\p{L}\p{N}_$]*) + classcase_id: (?:\p{Lu}[\p{L}\p{N}_$]*) + lowercase_id: (?:[_$]*\p{Ll}[\p{Ll}\p{N}_$]*\b) + uppercase_id: (?:[_$]*\p{Lu}[\p{Lu}\p{N}_$]*\b) + + # One dot is mandatory to not compete with other regexes that match an id. + before_fqn: (?={{lowercase_id}}\s*\.) + + # utility lookaround + lambda_lookahead: (?:\(.*\)|{{id}})\s*-> + + # digits + ddigits0: '\d[\d_]*?(_*)' + ddigits: (?:(_*){{ddigits0}}) + hdigits: (?:(_*)\h[\h_]*?(_*)) + exponent: '[-+]?{{ddigits}}' + eexponent: (?:[eE]{{exponent}}) + pexponent: (?:[pP]{{exponent}}) + +contexts: + prototype: + - match: (?=%>) + pop: true + - include: comments + - include: illegal-keywords + + any_POP: + - match: (?=\S) + pop: true + + immediate_POP: + - match: '' + pop: true + + main: + - include: prototype + - include: package-statement + - include: import-statement + - include: module + - include: class + - include: annotations + # Get modifiers defined on a different line than the class + - include: storage-modifiers + - include: stray-braces + - include: code + + punctuation-accessor-dot: + - match: \. + scope: punctuation.accessor.dot.java + + punctuation-separator-comma: + - match: \, + scope: punctuation.separator.comma.java + + punctuation-terminator-semicolon: + - match: ; + scope: punctuation.terminator.java + + dot-separated-identifier: + - match: '{{id}}' + - include: punctuation-accessor-dot + - include: immediate_POP + + package-statement: + - match: \bpackage\b + scope: keyword.other.package.java + push: + - - meta_scope: meta.package-declaration.java + - include: immediate_POP + - - match: '{{id}}' + set: + - meta_scope: meta.path.java entity.name.namespace.java + - include: dot-separated-identifier + - include: any_POP + + import-statement: + - match: \bimport\b + scope: keyword.control.import.java + push: + - - meta_scope: meta.import.java + - include: immediate_POP + - import-statement-body + + import-statement-body: + - match: \bstatic\b + scope: keyword.control.import.static.java + set: static-import-statement-body + - include: before-next-import + - match: '{{lowercase_id}}' + scope: meta.path.java support.type.package.java + set: + - meta_content_scope: meta.path.java + - include: before-next-import + - include: package + - match: \* + scope: meta.path.java keyword.operator.wildcard.asterisk.java + pop: true + - match: '{{classcase_id}}' + scope: support.class.import.java + set: + - include: before-next-import + - include: punctuation-accessor-dot + - include: import-class + - include: import-wildcard + - include: any_POP + - include: any_POP + - include: any_POP + + static-import-statement-body: + - include: before-next-import + - match: '{{lowercase_id}}' + scope: meta.path.java support.type.package.java + set: + - meta_content_scope: meta.path.java + - include: before-next-import + - include: package + - match: '{{classcase_id}}' + scope: support.class.import.java + set: + - include: before-next-import + - include: punctuation-accessor-dot + - include: import-constant + - include: import-class + - include: import-function + - include: import-wildcard + - include: any_POP + - include: any_POP + - include: any_POP + + before-next-import: + # Prevent next import statement to be consumed when a current statement isn't terminated with ';'. + - match: (?=\bimport\b) + pop: true + # For a case of a statement immediately before a class definition. + - match: (?=\b(?:{{storage_modifiers}}|class|interface|enum)\b) + pop: true + + package: + - match: '{{lowercase_id}}' + scope: support.type.package.java + - include: punctuation-accessor-dot + + all-types: + - include: primitive-types + - include: object-types + + import-constant: + - match: '{{uppercase_id}}' + scope: constant.other.import.java + + import-class: + - match: '{{classcase_id}}' + scope: support.class.import.java + + import-function: + - match: '{{id}}' + scope: support.function.import.java + + import-wildcard: + - match: \* + scope: keyword.operator.wildcard.asterisk.java + + annotations: + - match: \@ + scope: punctuation.definition.annotation.java + push: + - - meta_scope: meta.annotation.java + - include: immediate_POP + - annotation-parameters + - - meta_content_scope: meta.annotation.identifier.java + - include: immediate_POP + - annotation-type-reference + + annotation-type-reference: + - match: '{{before_fqn}}' + set: + - meta_scope: meta.path.java + - match: '{{lowercase_id}}' + scope: variable.annotation.package.java + - include: punctuation-accessor-dot + - include: annotation-type-no-fqn + - include: annotation-type-no-fqn + + annotation-type-no-fqn: + - match: '{{classcase_id}}' + scope: variable.annotation.java + set: after-annotation-type-reference + - include: any_POP + + after-annotation-type-reference: + - match: \. + scope: punctuation.accessor.dot.java + set: annotation-type-no-fqn + - include: any_POP + + annotation-parameters: + - match: \( + scope: punctuation.section.parens.begin.java + set: + - meta_scope: meta.annotation.parameters.java + - match: \) + scope: punctuation.section.parens.end.java + pop: true + - match: ({{id}})\s*(=) + captures: + 1: variable.parameter.java + 2: keyword.operator.assignment.java + push: + - match: (?=[,})]) + pop: true + - include: annotations + - include: code + - include: annotation-array-initialization + - include: annotations + - include: code + - include: any_POP + + annotation-array-initialization: + - match: \{ + scope: punctuation.section.braces.begin.java + push: + - meta_scope: meta.braces.annotation-array-initialization.java + - include: array-initialization-common + - include: annotations + + anonymous-classes-and-new: + - match: \bnew\b + scope: keyword.other.storage.new.java + push: + - - meta_scope: meta.instantiation.java + - include: immediate_POP + - instantiation + + instantiation: + - match: \b{{primitives}}\b + scope: storage.type.primitive.java + set: array-definition + - match: '{{before_fqn}}' + set: [after-object-type-in-instantiation, object-type-fqn] + - include: object-type-instantiation-no-fqn + + object-type-instantiation-no-fqn: + - match: '{{classcase_id}}' + scope: support.class.java + set: after-object-type-in-instantiation + - include: any_POP + + after-object-type-in-instantiation: + - match: (?=\[) + set: array-definition + - match: (?=\() + set: object-construction + - match: <> + scope: punctuation.definition.generic.diamond.java + set: object-construction + - match: (?=<) + set: [after-generic-in-instantiation, generic-type-invocation] + - match: \. + scope: punctuation.accessor.dot.java + set: object-type-instantiation-no-fqn + - include: any_POP + + after-generic-in-instantiation: + - match: (?=\[) + set: array-definition + - include: object-construction + + object-construction: + - match: \( + scope: punctuation.section.parens.begin.java + set: + - meta_scope: meta.parens.constructor-arguments.java + - match: \) + scope: punctuation.section.parens.end.java + set: + - match: \{ + scope: punctuation.section.braces.begin.java + set: + - meta_scope: meta.class.body.anonymous.java + - match: \} + scope: punctuation.section.braces.end.java + pop: true + - include: class-body + - include: any_POP + - include: illegal-parens-terminators + - include: code + - include: any_POP + + array-definition: + - match: \[ + scope: punctuation.section.brackets.begin.java + set: + - meta_scope: meta.brackets.array-initialization.java + - match: \] + scope: punctuation.section.brackets.end.java + set: + - match: (?=\[) + set: array-definition + - match: \{ + scope: punctuation.section.braces.begin.java + set: array-initialization + - include: any_POP + - include: code + - include: any_POP + + array-initialization: + - meta_scope: meta.braces.array-initialization.java + - include: array-initialization-common + + array-initialization-common: + - match: \} + scope: punctuation.section.braces.end.java + pop: true + - match: \{ + scope: punctuation.section.braces.begin.java + push: array-initialization + - include: code + + class: + - match: (?=({{storage_modifiers}}\s+)*(?:class|(?:@)?interface|enum)\b) + push: [class-meta, class-type] + + class-meta: + - meta_scope: meta.class.java + - include: immediate_POP + + class-type: + - include: storage-modifiers + - match: (?:class|(\@?)interface)\b + scope: storage.type.java + captures: + 1: punctuation.definition.type.java + set: + - class-block + - class-extends + - generic-type-declaration + - class-name + - match: enum\b + scope: storage.type.java + set: + - enum-block + - class-extends + - generic-type-declaration + - class-name + - include: any_POP + + class-name: + - meta_scope: meta.class.identifier.java + - match: (?!extends|implements){{id}}\b + scope: entity.name.class.java + pop: true + - include: any_POP + + class-extends: + - match: extends\b + scope: keyword.declaration.extends.java + push: + - - meta_scope: meta.class.extends.java + - match: \, + scope: punctuation.separator.comma.java + push: inherited-object-type-reference + - include: any_POP + - inherited-object-type-reference + - match: implements\b + scope: keyword.declaration.implements.java + push: + - - meta_scope: meta.class.implements.java + - match: \, + scope: punctuation.separator.comma.java + push: inherited-object-type-reference + - include: any_POP + - inherited-object-type-reference + - include: any_POP + + class-block: + - match: \{ + scope: punctuation.section.block.begin.java + set: + - meta_scope: meta.class.body.java meta.block.java + - match: \} + scope: punctuation.section.block.end.java + pop: true + - include: class-body + - include: any_POP + + class-body: + - include: class + - include: annotations + - include: fields-and-methods + - include: constants-and-special-vars + - include: storage-modifiers + - include: all-types + - include: static-code-block + - include: punctuation-separator-comma + - include: punctuation-terminator-semicolon + - match: (?=<) + push: generic-type-declaration + + enum-block: + - match: \{ + scope: punctuation.section.block.begin.java + set: + - meta_scope: meta.class.body.java meta.block.java + - match: \} + scope: punctuation.section.block.end.java + pop: true + - include: enum-body + - include: any_POP + + enum-body: + - match: ^(?=\s*([[:upper:]_][[:upper:][:digit:]_]*|(?!{{primitives}}|{{storage_modifiers}})[[:lower:]_][[:alnum:]_]*)\s*[,;{(]) + push: + - match: (?=[;}]) + pop: true + - match: \w+ + scope: constant.other.enum.java + push: + - meta_scope: meta.enum.java + - match: \{ + scope: punctuation.section.block.begin.java + push: + - meta_scope: meta.enum.body.java meta.block.java + - match: \} + scope: punctuation.section.block.end.java + pop: true + - include: enum-body + - include: parens + - include: any_POP + - include: punctuation-separator-comma + - include: class-body + + code: + - include: constants-and-special-vars + - include: assignment + - include: lambdas + - include: strings + - include: anonymous-classes-and-new + - include: keywords-control + - include: method-invocations + - include: uppercase-identifiers + - include: all-types + - include: keywords + - include: code-block-include + - include: parens + code-block-include: + - match: \{ + scope: punctuation.section.block.begin.java + push: + - meta_scope: meta.block.java + - match: \} + scope: punctuation.section.block.end.java + pop: true + - include: code-block + code-block: + - include: storage-modifiers + - include: var-type + - include: code + - include: annotations + - include: code-block-include + - include: stray-parens + comments: + - match: /\*\*/ + scope: comment.block.empty.java punctuation.definition.comment.java + - include: scope:text.html.javadoc + - include: comments-inline + comments-inline: + - match: /\* + scope: punctuation.definition.comment.java + push: + - meta_scope: comment.block.java + - match: \*/ + scope: punctuation.definition.comment.java + pop: true + - match: // + scope: punctuation.definition.comment.java + push: + - meta_scope: comment.line.double-slash.java + - match: \n + pop: true + - match: (?=%>) + pop: true + + constants-and-special-vars: + - match: \b(true|false|null)\b + scope: constant.language.java + - match: \b(this|super)\b + scope: variable.language.java + # hexadecimal floats + - match: |- + \b(0[xX])(?x: + # 0x1., 0x1.1, 0x1.1p1, 0x1.1p-1, 0x1.p1, 0x1.p-1 | 0x1p1 + {{hdigits}} (?: (\.) (?: {{hdigits}}? {{pexponent}}? \b )? | {{pexponent}} \b ) + # 0x.1, 0x.1p1, 0x.1p-1 + | (\.) {{hdigits}} {{pexponent}}? \b + ) + scope: constant.numeric.float.hexadecimal.java + captures: + 1: punctuation.definition.numeric.hexadecimal.java + 2: invalid.illegal.numeric.java + 3: invalid.illegal.numeric.java + 4: punctuation.separator.decimal.java + 5: invalid.illegal.numeric.java + 6: invalid.illegal.numeric.java + 7: invalid.illegal.numeric.java + 8: invalid.illegal.numeric.java + 9: invalid.illegal.numeric.java + 10: invalid.illegal.numeric.java + 11: punctuation.separator.decimal.java + 12: invalid.illegal.numeric.java + 13: invalid.illegal.numeric.java + 14: invalid.illegal.numeric.java + 15: invalid.illegal.numeric.java + # decimal floats + - match: |- + (?x: + \b{{ddigits0}} + (?: + # 1., 1.1, 1.1e1, 1.1e-1, 1.e1, 1.e-1, 1.d, 1.1d, 1.1e1d, 1.1e-1d, 1.e1d, 1.e-1d + (\.) (?: {{ddigits}}? {{eexponent}}? ([dDfF])? \b )? + # 1e1 1e1d + | {{eexponent}} ([dDfF])? \b + # 1d + | ([dDfF]) \b + ) + # .1, .1e1, .1e-1 + | (\.) {{ddigits}} {{eexponent}}? ([dDfF])? \b + ) + scope: constant.numeric.float.decimal.java + captures: + 1: invalid.illegal.numeric.java + 2: punctuation.separator.decimal.java + 3: invalid.illegal.numeric.java + 4: invalid.illegal.numeric.java + 5: invalid.illegal.numeric.java + 6: invalid.illegal.numeric.java + 7: storage.type.numeric.java + 8: invalid.illegal.numeric.java + 9: invalid.illegal.numeric.java + 10: storage.type.numeric.java + 11: storage.type.numeric.java + 12: punctuation.separator.decimal.java + 13: invalid.illegal.numeric.java + 14: invalid.illegal.numeric.java + 15: invalid.illegal.numeric.java + 16: invalid.illegal.numeric.java + 17: storage.type.numeric.java + # binary integers + - match: \b(0[bB])(_*)[01][01_]*?(_*)([lL])?\b + scope: constant.numeric.integer.binary.java + captures: + 1: punctuation.definition.numeric.binary.java + 2: invalid.illegal.numeric.java + 3: invalid.illegal.numeric.java + 4: storage.type.numeric.java + # hexadecimal integers + - match: \b(0[xX]){{hdigits}}([lL])?\b + scope: constant.numeric.integer.hexadecimal.java + captures: + 1: punctuation.definition.numeric.hexadecimal.java + 2: invalid.illegal.numeric.java + 3: invalid.illegal.numeric.java + 4: storage.type.numeric.java + # octal integers + - match: \b(0)(?:(_+)|[0-7_]+?(_*)|([\d_]+))([lL])?\b + scope: constant.numeric.integer.octal.java + captures: + 1: punctuation.definition.numeric.octal.java + 2: invalid.illegal.numeric.java + 3: invalid.illegal.numeric.java + 4: invalid.illegal.numeric.java + 5: storage.type.numeric.java + # decimal integers + - match: \b{{ddigits0}}([lL])?\b + scope: constant.numeric.integer.decimal.java + captures: + 1: invalid.illegal.numeric.java + 2: storage.type.numeric.java + + keywords: + - match: '::' + scope: punctuation.accessor.double-colon.java + push: + - match: '{{id}}' + scope: variable.function.reference.java + pop: true + - include: any_POP + - match: '\?|:' + scope: keyword.operator.ternary.java + - match: \binstanceof\b + scope: keyword.operator.word.instanceof.java + - match: (<<|>>>?) + scope: keyword.operator.bitshift.java + - match: (==|!=|<=|>=|<>|<|>) + scope: keyword.operator.comparison.java + - match: (\-\-|\+\+) + scope: keyword.operator.increment-decrement.java + - match: (\-|\+|\*|\/|%) + scope: keyword.operator.arithmetic.java + - match: (!|&&|\|\|) + scope: keyword.operator.logical.java + - match: (~|\^|&|\|) + scope: keyword.operator.bitwise.java + - match: (\.)(class\b)? + captures: + 1: punctuation.accessor.dot.java + 2: variable.language.java + - include: punctuation-separator-comma + - include: punctuation-terminator-semicolon + + keywords-control: + # exceptions + - match: \bcatch\b + scope: keyword.control.exception.catch.java + push: + - meta_scope: meta.catch.java + - match: (?=\() + set: + - match: \( + scope: punctuation.section.parens.begin.java + set: + - meta_scope: meta.catch.parameters.java meta.parens.java + - match: \) + scope: punctuation.section.parens.end.java + pop: true + - match: \| + scope: punctuation.separator.bar.java + - include: parameters + - include: any_POP + - match: \bfinally\b + scope: keyword.control.exception.finally.java + - match: \btry\b + scope: keyword.control.exception.try.java + push: declaration-statement-parens + # flow + - match: \bassert\b + scope: keyword.control.flow.assert.java + push: + - meta_scope: meta.assertion.java + - match: (?=;) + pop: true + - match: ':' + scope: punctuation.separator.expressions.java + - include: code + - match: \bbreak\b + scope: keyword.control.flow.break.java + - match: \bcontinue\b + scope: keyword.control.flow.continue.java + - match: \breturn\b + scope: keyword.control.flow.return.java + - match: \bthrow\b + scope: keyword.control.flow.throw.java + # conditional + - match: \bif\b + scope: keyword.control.conditional.if.java + - match: \belse\b + scope: keyword.control.conditional.else.java + - match: \bswitch\b + scope: keyword.control.conditional.switch.java + - match: \bcase\b + scope: keyword.control.conditional.case.java + - match: \bdefault\b + scope: keyword.control.conditional.default.java + # loop + - match: \bdo\b + scope: keyword.control.loop.do-while.java + - match: \bfor\b + scope: keyword.control.loop.for.java + push: declaration-statement-parens + - match: \bwhile\b + scope: keyword.control.loop.while.java + + illegal-keywords: + - match: \b(goto|const)\b + scope: invalid.illegal.keyword.java + + illegal-open-block: + - match: \s?(?={) + scope: invalid.illegal.stray-terminator-end + pop: true + + illegal-semicolon: + - match: ; + scope: invalid.illegal.stray-terminator-end + pop: true + + illegal-parens-terminators: + # Pops the stack if anything matches + - include: illegal-semicolon + - include: illegal-open-block + + method-invocations: + - match: (\.)\s*(?=<) + captures: + 1: punctuation.accessor.dot.java + push: generic-type-invocation + - match: ({{id}})\s*(\() + captures: + 1: variable.function.java + 2: punctuation.section.parens.begin.java + push: + - meta_scope: meta.function-call.java + - match: \) + scope: punctuation.section.parens.end.java + pop: true + - include: illegal-parens-terminators + - include: code + + fields-and-methods: + - match: \bvoid\b + scope: storage.type.void.java + push: method + - match: (?={{id}}\s*\() + push: method + - match: '{{before_fqn}}' + push: [field-or-method, after-object-and-array-types, object-type-fqn] + - match: \b{{classcase_id}} + scope: support.class.java + push: [field-or-method, after-object-and-array-types] + - match: \b{{primitives}}\b + scope: storage.type.primitive.java + push: [field-or-method, array-brackets] + + field-or-method: + - match: (?={{id}}\s*\() + set: method + - match: (?=\S) + set: + - include: before-next-field + - match: (?:({{uppercase_id}})|({{id}})) + captures: + 1: entity.name.constant.java + 2: meta.field.java + push: [static-assignment, array-brackets] + - include: punctuation-separator-comma + - include: any_POP + + before-next-field: + # Prevent style from being removed from whole file when making a new expression + - match: (?=\b(?:{{storage_modifiers}}|{{primitives}}|void)\b) + pop: true + + method: + - meta_scope: meta.method.java + - match: ({{classcase_id}})\s*(?=\() + captures: + 1: meta.method.identifier.java entity.name.function.constructor.java + - match: ({{id}})\s*(?=\() + captures: + 1: meta.method.identifier.java entity.name.function.java + - match: \( + scope: punctuation.section.parens.begin.java + push: + - meta_scope: meta.method.parameters.java meta.parens.java + - match: \) + scope: punctuation.section.parens.end.java + pop: true + - include: parameters + - match: \S + scope: invalid.illegal.missing-parameter-end + pop: true + - include: throws + - include: annotation-default + - match: \{ + scope: punctuation.section.block.begin.java + set: + - meta_scope: meta.method.java meta.method.body.java + - match: \} + scope: punctuation.section.block.end.java + pop: true + - include: code-block + - include: any_POP + + throws: + - match: \bthrows\b + scope: keyword.declaration.throws.java + push: + - - meta_scope: meta.method.throws.java + - match: \, + scope: punctuation.separator.comma.java + push: object-type-reference + - include: any_POP + - object-type-reference + + # Stand-along uppercase id, either type or constant. + # Should be used only inside code blocks. + uppercase-identifiers: + # Popular JDK classes + - match: \b(?:UUID|UR[LI])\b + scope: support.class.java + push: after-object-type + # Generic type variable + - match: \b\p{Lu}\b + scope: support.class.java + push: after-object-type + # Uppercase constants + - match: \b{{uppercase_id}} + scope: constant.other.java + + # Stand-alone type, maybe type of the variable or class object reference. + # Should be used only inside code blocks. + object-types: + # Here the match is more complex than 'before_fqn'. + # In code block we can't simply distinguish package from variable. + - match: (?=\b(?:{{lowercase_id}}\.)+\p{Lu}) + push: [after-object-type, object-type-fqn] + - match: \b{{classcase_id}}\b + scope: support.class.java + push: after-object-type + + object-type-fqn: + - meta_scope: meta.path.java + - include: package + - match: '{{classcase_id}}' + scope: support.class.java + pop: true + - include: any_POP + + after-object-type: + - match: (?=<) + set: [array-brackets, generic-type-invocation] + - match: \.(?!\.) + scope: punctuation.accessor.dot.java + set: + - match: (?=<) + set: generic-type-invocation + - match: (?:(class)\b|({{uppercase_id}})) + captures: + 1: variable.language.java + 2: constant.other.java + pop: true + - match: '{{classcase_id}}' + scope: support.class.java + set: after-object-type + - include: any_POP + - include: array-brackets + + # Used in 'throws' and generic bounds + object-type-reference: + - match: '{{before_fqn}}' + set: + - meta_scope: meta.path.java + - include: package + - include: object-type-reference-no-fqn + - include: object-type-reference-no-fqn + + object-type-reference-no-fqn: + - match: '{{classcase_id}}' + scope: support.class.java + set: after-object-type-reference + - include: any_POP + + after-object-type-reference: + - match: (?=<) + set: generic-type-invocation + - match: \. + scope: punctuation.accessor.dot.java + set: object-type-reference-no-fqn + - include: any_POP + + # Used in method's and generic's parameters + object-and-array-types: + - match: '{{before_fqn}}' + push: + - meta_scope: meta.path.java + - include: package + - include: object-and-array-types-no-fqn + - match: \b({{primitives}})(?=\s*\[) + scope: storage.type.primitive.java + push: array-brackets + - match: \b{{classcase_id}} + scope: support.class.java + push: after-object-and-array-types + + object-and-array-types-no-fqn: + - match: '{{classcase_id}}' + scope: support.class.java + set: after-object-and-array-types + - include: any_POP + + after-object-and-array-types: + - match: (?=<) + set: [array-brackets, generic-type-invocation] + - match: \.(?!\.) + scope: punctuation.accessor.dot.java + set: object-and-array-types-no-fqn + - include: array-brackets + + # Used in class-level 'extends' and 'implements' + inherited-object-type-reference: + - match: '{{before_fqn}}' + set: + - meta_scope: meta.path.java + - match: '{{lowercase_id}}' + scope: entity.other.inherited-class.package.java + - include: punctuation-accessor-dot + - include: inherited-object-type-reference-no-fqn + - include: inherited-object-type-reference-no-fqn + + inherited-object-type-reference-no-fqn: + - match: (?!class|extends|implements|interface){{id}} + scope: entity.other.inherited-class.java + set: after-inherited-object-type-reference + - include: any_POP + + after-inherited-object-type-reference: + - match: (?=<) + set: generic-type-invocation + - match: \. + scope: punctuation.accessor.dot.java + set: inherited-object-type-reference-no-fqn + - include: any_POP + + generic-type-declaration: + - match: < + scope: punctuation.definition.generic.begin.java + push: generic-type-parameter + - include: any_POP + + generic-type-terminator: + - include: illegal-semicolon + # These characters can't appear in a generic. If we've matched + # them then someone forgot to close it. + - match: (?=[{}()]) + pop: true + - match: '>' + scope: punctuation.definition.generic.end.java + pop: true + + generic-type-parameter: + - meta_scope: meta.generic.declaration.java + - match: \b{{id}}\b + scope: variable.parameter.type.java + push: generic-type-bounds + - include: generic-type-terminator + + generic-type-bounds: + - match: (,)|(?=>) + captures: + 1: punctuation.separator.comma.java + pop: true + - match: \bextends\b + scope: keyword.declaration.extends.java + push: [generic-type-extends-multiple-bounds, object-type-reference] + - match: \bsuper\b + scope: keyword.declaration.super.java + push: object-type-reference + + generic-type-extends-multiple-bounds: + - match: '&' + scope: keyword.operator.multiple-bounds.java + set: [generic-type-extends-multiple-bounds, object-type-reference] + - include: any_POP + + generic-type-invocation: + - match: < + scope: punctuation.definition.generic.begin.java + set: generic-type-argument + - include: any_POP + + generic-type-argument: + - meta_scope: meta.generic.java + - match: \? + scope: keyword.operator.wildcard.java + push: generic-type-bounds + - include: generic-type-terminator + - include: object-and-array-types + - include: punctuation-separator-comma + + annotation-default: + - match: \bdefault\b + scope: keyword.declaration.default.java + push: + - meta_scope: meta.annotation.default.java + - match: (?=;) + pop: true + - include: code + + parameters: + - match: \bfinal\b + scope: storage.modifier.java + - include: annotations + - include: primitive-types + - include: object-and-array-types + - match: \.\.\. + scope: keyword.operator.variadic.java + - match: '{{id}}' + scope: variable.parameter.java + push: array-brackets + - include: punctuation-separator-comma + + lambdas: + - match: (?={{lambda_lookahead}}) + push: lambda-params + + lambda-params: + - meta_scope: meta.function.anonymous.parameters.java + - match: \( + scope: punctuation.section.parens.begin.java + set: + - meta_scope: meta.function.anonymous.parameters.java + - match: \) + scope: punctuation.section.parens.end.java + set: lambda-arrow + - include: parameters + - match: '{{id}}' + scope: variable.parameter.java + set: lambda-arrow + + lambda-arrow: + - match: -> + scope: storage.type.function.anonymous.java + set: + - meta_scope: meta.function.anonymous.body.java + - match: (?=[)};]) + pop: true + - include: code + + parens: + - match: \( + scope: punctuation.section.parens.begin.java + push: + - meta_scope: meta.parens.java + - match: \) + scope: punctuation.section.parens.end.java + pop: true + - include: illegal-parens-terminators + - include: code + + declaration-statement-parens: + - match: \( + scope: punctuation.section.parens.begin.java + set: + - meta_scope: meta.parens.java + - match: \) + scope: punctuation.section.parens.end.java + pop: true + - include: illegal-open-block + - include: code-block + - include: any_POP + + primitive-types: + - match: \b{{primitives}}\b + scope: storage.type.primitive.java + push: array-brackets + + var-type: + - match: \bvar\b + scope: storage.type.var.java + + array-brackets: + - match: \[\s*\] + scope: storage.modifier.array.java + - include: any_POP + + static-assignment: + - match: \= + scope: keyword.operator.assignment.java + set: + - meta_scope: meta.assignment.rhs.java + - match: (?=[,;]) + pop: true + - include: before-next-field + - include: code + - include: stray-parens + - include: any_POP + + assignment: + - match: ([|&^*/+-]\=|\=(?!=)) + scope: keyword.operator.assignment.java + push: + - meta_scope: meta.assignment.rhs.java + - match: (?=;|\)|\}|,) + pop: true + - include: code + static-code-block: + - match: \{ + scope: punctuation.section.block.begin.java + push: + - meta_scope: meta.static.body.java + - match: \} + scope: punctuation.section.block.end.java + pop: true + - include: code-block + storage-modifiers: + - match: \b{{storage_modifiers}}\b + scope: storage.modifier.java + stray-braces: + - match: \} + scope: invalid.illegal.stray-brace-end + stray-parens: + - match: \) + scope: invalid.illegal.stray-parens-end + + strings: + - match: \" + scope: punctuation.definition.string.begin.java + push: + - meta_include_prototype: false + - meta_scope: string.quoted.double.java + - match: \" + scope: punctuation.definition.string.end.java + pop: true + - include: strings-common + - match: \' + scope: punctuation.definition.string.begin.java + push: + - meta_include_prototype: false + - meta_scope: string.quoted.single.java + - match: \' + scope: punctuation.definition.string.end.java + pop: true + - include: strings-common + + strings-common: + - match: \n + scope: invalid.illegal.newline.java + pop: true + - match: \\. + scope: constant.character.escape.java + + module: + - match: (?=\b(?:open\s+)?module\b) + push: + - - meta_scope: meta.module.java + - include: immediate_POP + - - match: \bopen\b + scope: storage.modifier.java + - match: \bmodule\b + scope: storage.type.java + set: [module-body, module-identifier-scope, module-identifier] + + module-identifier-scope: + - meta_scope: meta.module.identifier.java + - include: immediate_POP + + module-identifier: + - match: '{{id}}' + set: + - - meta_scope: entity.name.module.java + - include: immediate_POP + - dot-separated-identifier + - include: any_POP + + module-body: + - match: \{ + scope: punctuation.section.braces.begin.java + set: + - meta_scope: meta.module.body.java + - include: module-body-content + - match: \} + scope: punctuation.section.braces.end.java + pop: true + - include: any_POP + + module-body-content: + - match: \bexports\b + scope: keyword.other.module.exports.java + push: [exports-statement-scope, exports-or-opens-statement] + - match: \bopens\b + scope: keyword.other.module.opens.java + push: [opens-statement-scope, exports-or-opens-statement] + - match: \brequires\b + scope: keyword.other.module.requires.java + push: requires-statement + - match: \buses\b + scope: keyword.other.module.uses.java + push: [uses-statement-scope, object-type-reference] + - match: \bprovides\b + scope: keyword.other.module.provides.java + push: [provides-statement-scope, provides-with-statement, object-type-reference] + - include: punctuation-terminator-semicolon + + # Should always come before module/package patterns + module-statement-terminator: + - match: (?=[;\}]) + pop: true + - match: (?=\b(?:requires|exports|uses|provides|opens)\b) + pop: true + + support-type-module: + - match: '{{id}}' + push: + - - meta_scope: support.type.module.java + - include: immediate_POP + - dot-separated-identifier + + exports-statement-scope: + - meta_scope: meta.exports.java + - include: immediate_POP + + opens-statement-scope: + - meta_scope: meta.opens.java + - include: immediate_POP + + exports-or-opens-statement: + - match: \bto\b + scope: keyword.other.module.to.java + set: + - include: module-statement-terminator + - include: support-type-module + - include: punctuation-separator-comma + - include: module-statement-terminator + - match: '{{id}}' + push: + - - meta_scope: support.type.package.java + - include: immediate_POP + - dot-separated-identifier + + requires-statement: + - meta_scope: meta.requires.java + - match: \btransitive\b + scope: keyword.other.module.transitive.java + - include: module-statement-terminator + - include: support-type-module + + uses-statement-scope: + - meta_scope: meta.uses.java + - include: immediate_POP + + provides-statement-scope: + - meta_scope: meta.provides.java + - include: immediate_POP + + provides-with-statement: + - match: \bwith\b + scope: keyword.other.module.with.java + set: + - - match: \, + scope: punctuation.separator.comma.java + push: object-type-reference + - include: any_POP + - object-type-reference + - include: any_POP diff --git a/syntaxes/Java/JavaC.sublime-build b/syntaxes/Java/JavaC.sublime-build @@ -0,0 +1,5 @@ +{ + "shell_cmd": "javac \"$file\"", + "file_regex": "^(...*?):([0-9]*):?([0-9]*)", + "selector": "source.java" +} diff --git a/syntaxes/Java/JavaDoc.sublime-syntax b/syntaxes/Java/JavaDoc.sublime-syntax @@ -0,0 +1,195 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: Javadoc +file_extensions: [] +scope: text.html.javadoc +hidden: true + +variables: + id: '(?:[\p{L}_$][\p{L}\p{N}_$]*)' + javadoc_block_tag_terminator: (?=^\s*\*?\s*@) + +contexts: + prototype: + # https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#leadingasterisks + - match: ^\s*(\*)\s*(?!\s*@) + captures: + 1: punctuation.definition.comment.javadoc + + main: + - meta_include_prototype: false + - match: /\*\* + scope: comment.block.documentation.javadoc punctuation.definition.comment.begin.javadoc + embed: contents + embed_scope: comment.block.documentation.javadoc text.html.javadoc + escape: \*/ + escape_captures: + 0: comment.block.documentation.javadoc punctuation.definition.comment.end.javadoc + + contents: + - meta_include_prototype: false + + # Block tag in the first line (immediately after '/**'). + - match: \s*(?=@) + embed: javadoc-block-tags + escape: '{{javadoc_block_tag_terminator}}' + + # We rely on 'escape' to pop the inner context out. + # 'set' unfortunately will mess up the meta scopes. + - match: '' + push: + - match: ^\s*(\*)?\s*(?=@) + captures: + 1: punctuation.definition.comment.javadoc + embed: javadoc-block-tags + escape: '{{javadoc_block_tag_terminator}}' + - include: inline-formatting + + inline-formatting: + - include: javadoc-inline-tags + - include: scope:text.html.basic + + javadoc-block-tag-base: + - meta_scope: meta.block-tag.javadoc + - include: inline-formatting + + javadoc-block-tags: + # https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#param + - match: (@)param\b + scope: keyword.other.documentation.param.javadoc + captures: + 1: punctuation.definition.keyword.javadoc + push: [javadoc-block-tag-base, param-tag-parameter] + # https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#see + - match: (@)see\b + scope: keyword.other.documentation.see.javadoc + captures: + 1: punctuation.definition.keyword.javadoc + push: [javadoc-block-tag-base, see-tag-content] + # https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#throws + - match: (@)(throws|exception)\b + scope: keyword.other.documentation.throws.javadoc + captures: + 1: punctuation.definition.keyword.javadoc + push: [javadoc-block-tag-base, reference] + - match: (@)(uses|provides)\b + scope: keyword.other.documentation.uses-or-provides.javadoc + captures: + 1: punctuation.definition.keyword.javadoc + push: [javadoc-block-tag-base, reference] + - match: (@)(return|deprecated|author|version|since|apiNote|impl(?:Note|Spec)|moduleGraph|serial(?:Field|Data)?)\b + scope: keyword.other.documentation.javadoc + captures: + 1: punctuation.definition.keyword.javadoc + push: javadoc-block-tag-base + - match: '@' + pop: true + + param-tag-parameter: + - match: \S+ + scope: variable.parameter.javadoc + pop: true + + see-tag-content: + - match: (?=['<]) + pop: true + - match: (?=\S) + set: reference + + reference: + - match: (?:{{id}}\.)*{{id}}(?:#{{id}})?|#{{id}} + scope: markup.underline.link.javadoc + set: + - match: \( + scope: markup.underline.link.javadoc + set: + - match: \) + scope: markup.underline.link.javadoc + pop: true + - match: . + scope: markup.underline.link.javadoc + - match: '' + pop: true + + javadoc-inline-tag-terminator: + - match: \} + scope: punctuation.section.inline-tag.end.javadoc + pop: true + + javadoc-inline-tag-base: + - meta_scope: meta.inline-tag.javadoc + - include: javadoc-inline-tag-terminator + + # Multi-line tags mustn't highlight leading asterisk. + javadoc-inline-tags: + # https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#code + # https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#literal + - match: ({)((@)(?:code|literal))(?:\s+|(?=\})) + captures: + 1: punctuation.section.inline-tag.begin.javadoc + 2: keyword.other.documentation.code-or-literal.javadoc + 3: punctuation.definition.keyword.javadoc + push: + - meta_scope: meta.inline-tag.javadoc + - include: javadoc-inline-tag-terminator + - include: code-tag-bracket-balancing + - match: ^\s+ + - match: . + scope: markup.raw.javadoc + # https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#link + - match: ({)((@)link(?:plain)?)\b + captures: + 1: punctuation.section.inline-tag.begin.javadoc + 2: keyword.other.documentation.link.javadoc + 3: punctuation.definition.keyword.javadoc + push: [javadoc-inline-tag-base, link-tag-label, reference-in-inline-tag] + # https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#value + - match: ({)((@)value)\b + captures: + 1: punctuation.section.inline-tag.begin.javadoc + 2: keyword.other.documentation.value.javadoc + 3: punctuation.definition.keyword.javadoc + push: [javadoc-inline-tag-base, reference-in-inline-tag] + # http://openjdk.java.net/jeps/225 + # https://bugs.openjdk.java.net/browse/JDK-8178725 + - match: ({)((@)(?:index|extLink))\b + captures: + 1: punctuation.section.inline-tag.begin.javadoc + 2: keyword.other.documentation.javadoc + 3: punctuation.definition.keyword.javadoc + push: javadoc-inline-tag-base + # https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#inheritDoc + - match: ({)((@)inheritDoc)(}) + scope: meta.inline-tag.javadoc + captures: + 1: punctuation.section.inline-tag.begin.javadoc + 2: keyword.other.documentation.javadoc + 3: punctuation.definition.keyword.javadoc + 4: punctuation.section.inline-tag.end.javadoc + + code-tag-bracket-balancing: + - match: \{ + scope: markup.raw.javadoc + push: + - match: \} + scope: markup.raw.javadoc + pop: true + - include: code-tag-bracket-balancing + - match: . + scope: markup.raw.javadoc + + link-tag-label: + - match: \s* + set: + - meta_content_scope: meta.label.javadoc + - include: scope:text.html.basic + - match: (?=\}) + pop: true + + reference-in-inline-tag: + - match: '' + set: reference + with_prototype: + - match: (?=\}) + pop: true diff --git a/syntaxes/Java/JavaProperties.sublime-syntax b/syntaxes/Java/JavaProperties.sublime-syntax @@ -0,0 +1,50 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: Java Properties +file_extensions: + - properties +scope: source.java-props + +# https://en.wikipedia.org/wiki/.properties +contexts: + main: + - match: ^\s*([#!]).* + scope: comment.line.java-props + captures: + 1: punctuation.definition.comment.java-props + + - match: (?=\S) + push: + - - meta_scope: meta.property.java-props + - match: '' + pop: true + - property + + property: + - meta_content_scope: entity.name.key.java-props + - include: backslash + - match: (?=[:=\s]) + set: + - match: '[:=]' + scope: punctuation.separator.java-props + set: property-value + - include: property-value + with_prototype: + - match: (?=\n) + pop: true + + property-value: + - match: (?=\S) + set: + - meta_content_scope: string.unquoted.java-props + - include: backslash + + backslash: + - match: (\\)\n + captures: + 1: punctuation.separator.continuation.java-props + - match: \\u[[:xdigit:]]{4} + scope: constant.character.escape.unicode.java-props + - match: \\[^u] + scope: constant.character.escape.java-props diff --git a/syntaxes/Java/Snippets/abstract.sublime-snippet b/syntaxes/Java/Snippets/abstract.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[abstract ]]></content> + <tabTrigger>ab</tabTrigger> + <scope>source.java</scope> + <description>abstract</description> +</snippet> diff --git a/syntaxes/Java/Snippets/assert.sublime-snippet b/syntaxes/Java/Snippets/assert.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[assert ${1:test}${2/(.+)/(?1: \: ")/}${2:Failure message}${2/(.+)/(?1:")/};$0]]></content> + <tabTrigger>as</tabTrigger> + <scope>source.java</scope> + <description>assert</description> +</snippet> diff --git a/syntaxes/Java/Snippets/break.sublime-snippet b/syntaxes/Java/Snippets/break.sublime-snippet @@ -0,0 +1,7 @@ +<snippet> + <content><![CDATA[break; +]]></content> + <tabTrigger>br</tabTrigger> + <scope>source.java</scope> + <description>break</description> +</snippet> diff --git a/syntaxes/Java/Snippets/case.sublime-snippet b/syntaxes/Java/Snippets/case.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[case $1: + $2 +$0]]></content> + <tabTrigger>cs</tabTrigger> + <scope>source.java</scope> + <description>case</description> +</snippet> diff --git a/syntaxes/Java/Snippets/catch.sublime-snippet b/syntaxes/Java/Snippets/catch.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[catch (${1:Exception} ${2:e}) { + $0 +}]]></content> + <tabTrigger>ca</tabTrigger> + <scope>source.java</scope> + <description>catch</description> +</snippet> diff --git a/syntaxes/Java/Snippets/class.sublime-snippet b/syntaxes/Java/Snippets/class.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[class ${1:${TM_FILENAME/(.*?)(\..+)/$1/}} ${2:extends ${3:Parent} }${4:implements ${5:Interface} }{ + $0 +}]]></content> + <tabTrigger>cl</tabTrigger> + <scope>source.java</scope> + <description>class</description> +</snippet> diff --git a/syntaxes/Java/Snippets/constant-string.sublime-snippet b/syntaxes/Java/Snippets/constant-string.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[static public final String ${1:var} = "$2";$0]]></content> + <tabTrigger>cos</tabTrigger> + <scope>source.java</scope> + <description>constant string</description> +</snippet> diff --git a/syntaxes/Java/Snippets/constant.sublime-snippet b/syntaxes/Java/Snippets/constant.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[static public final ${1:String} ${2:var} = $3;$0]]></content> + <tabTrigger>co</tabTrigger> + <scope>source.java</scope> + <description>constant</description> +</snippet> diff --git a/syntaxes/Java/Snippets/default.sublime-snippet b/syntaxes/Java/Snippets/default.sublime-snippet @@ -0,0 +1,7 @@ +<snippet> + <content><![CDATA[default: + $0]]></content> + <tabTrigger>de</tabTrigger> + <scope>source.java</scope> + <description>default</description> +</snippet> diff --git a/syntaxes/Java/Snippets/else-if.sublime-snippet b/syntaxes/Java/Snippets/else-if.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[else if ($1) { + $0 +}]]></content> + <tabTrigger>elif</tabTrigger> + <scope>source.java</scope> + <description>else if</description> +</snippet> diff --git a/syntaxes/Java/Snippets/else.sublime-snippet b/syntaxes/Java/Snippets/else.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[else { + $0 +}]]></content> + <tabTrigger>el</tabTrigger> + <scope>source.java</scope> + <description>else</description> +</snippet> diff --git a/syntaxes/Java/Snippets/final.sublime-snippet b/syntaxes/Java/Snippets/final.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[final ]]></content> + <tabTrigger>fi</tabTrigger> + <scope>source.java</scope> + <description>final</description> +</snippet> diff --git a/syntaxes/Java/Snippets/for-(each).sublime-snippet b/syntaxes/Java/Snippets/for-(each).sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[for ($1 : $2) { + $0 +}]]></content> + <tabTrigger>fore</tabTrigger> + <scope>source.java</scope> + <description>for (each)</description> +</snippet> diff --git a/syntaxes/Java/Snippets/for.sublime-snippet b/syntaxes/Java/Snippets/for.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[for ($1; $2; $3) { + $0 +}]]></content> + <tabTrigger>for</tabTrigger> + <scope>source.java</scope> + <description>for</description> +</snippet> diff --git a/syntaxes/Java/Snippets/if.sublime-snippet b/syntaxes/Java/Snippets/if.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[if ($1) { + $0 +}]]></content> + <tabTrigger>if</tabTrigger> + <scope>source.java</scope> + <description>if</description> +</snippet> diff --git a/syntaxes/Java/Snippets/import-junit_framework_TestCase;.sublime-snippet b/syntaxes/Java/Snippets/import-junit_framework_TestCase;.sublime-snippet @@ -0,0 +1,7 @@ +<snippet> + <content><![CDATA[import junit.framework.TestCase; +$0]]></content> + <tabTrigger>imt</tabTrigger> + <scope>source.java</scope> + <description>import junit.framework.TestCase;</description> +</snippet> diff --git a/syntaxes/Java/Snippets/import.sublime-snippet b/syntaxes/Java/Snippets/import.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[import ]]></content> + <tabTrigger>im</tabTrigger> + <scope>source.java</scope> + <description>import</description> +</snippet> diff --git a/syntaxes/Java/Snippets/interface.sublime-snippet b/syntaxes/Java/Snippets/interface.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[interface ${1:${TM_FILENAME/(.*?)(\..+)/$1/}} ${2:extends ${3:Parent} }{ + $0 +}]]></content> + <tabTrigger>in</tabTrigger> + <scope>source.java</scope> + <description>interface</description> +</snippet> diff --git a/syntaxes/Java/Snippets/java_beans_.sublime-snippet b/syntaxes/Java/Snippets/java_beans_.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[java.beans.]]></content> + <tabTrigger>j.b</tabTrigger> + <scope>source.java</scope> + <description>java.beans.</description> +</snippet> diff --git a/syntaxes/Java/Snippets/java_io.sublime-snippet b/syntaxes/Java/Snippets/java_io.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[java.io.]]></content> + <tabTrigger>j.i</tabTrigger> + <scope>source.java</scope> + <description>java.io.</description> +</snippet> diff --git a/syntaxes/Java/Snippets/java_math.sublime-snippet b/syntaxes/Java/Snippets/java_math.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[java.math.]]></content> + <tabTrigger>j.m</tabTrigger> + <scope>source.java</scope> + <description>java.math.</description> +</snippet> diff --git a/syntaxes/Java/Snippets/java_net_.sublime-snippet b/syntaxes/Java/Snippets/java_net_.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[java.net.]]></content> + <tabTrigger>j.n</tabTrigger> + <scope>source.java</scope> + <description>java.net.</description> +</snippet> diff --git a/syntaxes/Java/Snippets/java_util_.sublime-snippet b/syntaxes/Java/Snippets/java_util_.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[java.util.]]></content> + <tabTrigger>j.u</tabTrigger> + <scope>source.java</scope> + <description>java.util.</description> +</snippet> diff --git a/syntaxes/Java/Snippets/method-(main).sublime-snippet b/syntaxes/Java/Snippets/method-(main).sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[public static void main(String[] args) { + $0 +}]]></content> + <tabTrigger>main</tabTrigger> + <scope>source.java</scope> + <description>method (main)</description> +</snippet> diff --git a/syntaxes/Java/Snippets/method.sublime-snippet b/syntaxes/Java/Snippets/method.sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <content><![CDATA[${1:void} ${2:method}($3) ${4:throws $5 }{ + $0 +} +]]></content> + <tabTrigger>m</tabTrigger> + <scope>source.java</scope> + <description>method</description> +</snippet> diff --git a/syntaxes/Java/Snippets/package.sublime-snippet b/syntaxes/Java/Snippets/package.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[package ]]></content> + <tabTrigger>pa</tabTrigger> + <scope>source.java</scope> + <description>package</description> +</snippet> diff --git a/syntaxes/Java/Snippets/print.sublime-snippet b/syntaxes/Java/Snippets/print.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[System.out.print($1);$0]]></content> + <tabTrigger>p</tabTrigger> + <scope>source.java</scope> + <description>print</description> +</snippet> diff --git a/syntaxes/Java/Snippets/println.sublime-snippet b/syntaxes/Java/Snippets/println.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[System.out.println($1);$0]]></content> + <tabTrigger>pl</tabTrigger> + <scope>source.java</scope> + <description>println</description> +</snippet> diff --git a/syntaxes/Java/Snippets/private.sublime-snippet b/syntaxes/Java/Snippets/private.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[private ]]></content> + <tabTrigger>pr</tabTrigger> + <scope>source.java</scope> + <description>private</description> +</snippet> diff --git a/syntaxes/Java/Snippets/protected.sublime-snippet b/syntaxes/Java/Snippets/protected.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[protected ]]></content> + <tabTrigger>po</tabTrigger> + <scope>source.java</scope> + <description>protected</description> +</snippet> diff --git a/syntaxes/Java/Snippets/public.sublime-snippet b/syntaxes/Java/Snippets/public.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[public ]]></content> + <tabTrigger>pu</tabTrigger> + <scope>source.java</scope> + <description>public</description> +</snippet> diff --git a/syntaxes/Java/Snippets/return.sublime-snippet b/syntaxes/Java/Snippets/return.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[return ]]></content> + <tabTrigger>re</tabTrigger> + <scope>source.java</scope> + <description>return</description> +</snippet> diff --git a/syntaxes/Java/Snippets/static.sublime-snippet b/syntaxes/Java/Snippets/static.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[static ]]></content> + <tabTrigger>st</tabTrigger> + <scope>source.java</scope> + <description>static</description> +</snippet> diff --git a/syntaxes/Java/Snippets/switch.sublime-snippet b/syntaxes/Java/Snippets/switch.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[switch ($1) { + $0 +}]]></content> + <tabTrigger>sw</tabTrigger> + <scope>source.java</scope> + <description>switch</description> +</snippet> diff --git a/syntaxes/Java/Snippets/synchronized.sublime-snippet b/syntaxes/Java/Snippets/synchronized.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[synchronized ]]></content> + <tabTrigger>sy</tabTrigger> + <scope>source.java</scope> + <description>synchronized</description> +</snippet> diff --git a/syntaxes/Java/Snippets/test-case.sublime-snippet b/syntaxes/Java/Snippets/test-case.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[public class ${1:${TM_FILENAME/(.*?)(\..+)/$1/}} extends ${2:TestCase} { + $0 +}]]></content> + <tabTrigger>tc</tabTrigger> + <scope>source.java</scope> + <description>test case</description> +</snippet> diff --git a/syntaxes/Java/Snippets/test.sublime-snippet b/syntaxes/Java/Snippets/test.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[public void test${1:Name}() throws Exception { + $0 +}]]></content> + <tabTrigger>t</tabTrigger> + <scope>source.java</scope> + <description>test</description> +</snippet> diff --git a/syntaxes/Java/Snippets/throw.sublime-snippet b/syntaxes/Java/Snippets/throw.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[throw $0]]></content> + <tabTrigger>th</tabTrigger> + <scope>source.java</scope> + <description>throw</description> +</snippet> diff --git a/syntaxes/Java/Snippets/variable.sublime-snippet b/syntaxes/Java/Snippets/variable.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[${1:String} ${2:var}${3: = ${0:null}};]]></content> + <tabTrigger>v</tabTrigger> + <scope>source.java</scope> + <description>variable</description> +</snippet> diff --git a/syntaxes/Java/Snippets/while.sublime-snippet b/syntaxes/Java/Snippets/while.sublime-snippet @@ -0,0 +1,8 @@ +<snippet> + <content><![CDATA[while ($1) { + $0 +}]]></content> + <tabTrigger>wh</tabTrigger> + <scope>source.java</scope> + <description>while</description> +</snippet> diff --git a/syntaxes/Java/Symbol List - Classes.tmPreferences b/syntaxes/Java/Symbol List - Classes.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List: Classes</string> + <key>scope</key> + <string>source.java meta.class meta.class.identifier</string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>1</integer> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Symbol List - Constants.tmPreferences b/syntaxes/Java/Symbol List - Constants.tmPreferences @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List: Constants</string> + <key>scope</key> + <string>source.java entity.name.constant.java</string> + <key>settings</key> + <dict> + <key>showInIndexedSymbolList</key> + <integer>1</integer> + + <key>showInSymbolList</key> + <integer>1</integer> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Symbol List - Inner Class Methods.tmPreferences b/syntaxes/Java/Symbol List - Inner Class Methods.tmPreferences @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List: Inner Class Methods</string> + <key>scope</key> + <string>source.java meta.class.body meta.class.body meta.method.identifier</string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>1</integer> + <key>symbolTransformation</key> + <string> + s/\s{2,}/ /g; + s/.*/ $0/g; + </string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Symbol List - Inner Classes.tmPreferences b/syntaxes/Java/Symbol List - Inner Classes.tmPreferences @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List: Inner Classes</string> + <key>scope</key> + <string>source.java meta.class.body meta.class.identifier</string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>1</integer> + <key>symbolTransformation</key> + <string>s/.*/ $0/g</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Symbol List - Inner Inner Class Methods.tmPreferences b/syntaxes/Java/Symbol List - Inner Inner Class Methods.tmPreferences @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List: Inner Inner Class Methods</string> + <key>scope</key> + <string>source.java meta.class.body meta.class.body meta.class.body meta.method.identifier</string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>1</integer> + <key>symbolTransformation</key> + <string> + s/\s{2,}/ /g; + s/.*/ $0/g; + </string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Symbol List - Inner Inner Classes.tmPreferences b/syntaxes/Java/Symbol List - Inner Inner Classes.tmPreferences @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List: Inner Inner Classes</string> + <key>scope</key> + <string>source.java meta.class.body meta.class.body meta.class.identifier</string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>1</integer> + <key>symbolTransformation</key> + <string>s/.*/ $0/g</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Symbol List - Method.tmPreferences b/syntaxes/Java/Symbol List - Method.tmPreferences @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List: Methods</string> + <key>scope</key> + <string>source.java meta.class.body meta.method.identifier</string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>1</integer> + <key>symbolTransformation</key> + <string> + s/\s{2,}/ /g; + s/.*/ $0/g; + </string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Symbol List - Modules.tmPreferences b/syntaxes/Java/Symbol List - Modules.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List: Modules</string> + <key>scope</key> + <string>source.java meta.module meta.module.identifier</string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>1</integer> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/Symbol List - Properties.tmPreferences b/syntaxes/Java/Symbol List - Properties.tmPreferences @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List - Properties</string> + <key>scope</key> + <string>entity.name.key.java-props</string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>1</integer> + <key>symbolTransformation</key> + <string>s/\\(?!u)//g;</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Java/syntax_test_java.java b/syntaxes/Java/syntax_test_java.java @@ -0,0 +1,2550 @@ +// SYNTAX TEST "Packages/Java/Java.sublime-syntax" + +package apple; +// <- source.java meta.package-declaration.java keyword.other.package.java +// ^^^^^ entity.name.namespace.java +// ^ punctuation.terminator.java + +package com.example.apple; +//^^^^^^^^^^^^^^^^^^^^^^^ meta.package-declaration.java +// ^^^^^^^^^^^^^^^^^ entity.name.namespace.java +// ^ punctuation.accessor.dot.java +// ^ punctuation.accessor.dot.java +// ^ punctuation.terminator.java + +import a.b.Class; +// <- meta.import.java keyword.control.import.java +// ^^^^^^^^^ meta.path.java +// ^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^ support.class.import.java +// ^ punctuation.terminator.java + +import a.b.Class.SubClass; +//^^^^^^^^^^^^^^^^^^^^^^^ meta.import.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^ support.class.import.java + +import a.b.Class.*; +//^^^^^^^^^^^^^^^^ meta.import.java +// ^ punctuation.accessor.dot.java +// ^ keyword.operator.wildcard.asterisk.java + +import com.google +// ^^^^^^^^^^ meta.import.java meta.path.java +// ^ punctuation.accessor.dot.java +// ^^^^^^ support.type.package.java + .common.collect +//^ punctuation.accessor.dot.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^ support.type.package.java +//^^^^^^^^^^^^^^^ meta.import.java meta.path.java + .ListMultimap; +//^ punctuation.accessor.dot.java +// ^^^^^^^^^^^^ support.class.import.java +//^^^^^^^^^^^^^ meta.import.java meta.path.java +// ^ punctuation.terminator.java + +import no.terminator +// <- meta.import.java keyword.control.import.java + +import static no.terminator +// <- meta.import.java keyword.control.import.java + +import +// <- meta.import.java keyword.control.import.java + +import static +// <- meta.import.java keyword.control.import.java + +import java.net.URL; +// <- meta.import.java keyword.control.import.java +//^^^^^^^^^^^^^^^^^ meta.import.java +// ^^^^^^^^^^^^ meta.path.java +// ^^^ support.class.import.java +// ^^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^ punctuation.terminator.java + +import java.util.*; +//^^^^^^^^^^^^^^^^ meta.import.java +// ^^^^^^^^^^^ meta.path.java +// ^^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^ keyword.operator.wildcard.asterisk.java + +import static a.b.Class.fooMethod; +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import.java +// <- meta.import.java keyword.control.import.java +// ^^^^^^ meta.import.java keyword.control.import.static.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^ meta.path.java +// ^^^^ support.class.import.java +// ^ punctuation.accessor.dot.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^ meta.import.java support.function.import.java +// ^ punctuation.terminator.java + +import static a.b.Class.CONSTANT; +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import.java +// ^^^^^^^^^ meta.path.java +// ^^^^ support.class.import.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^ constant.other.import.java + +import static a.b.Class.*; +// ^ punctuation.accessor.dot.java +// ^ keyword.operator.wildcard.asterisk.java + +public class SyntaxTest { +//^^^^^^^^^^^^^^^^^^^^^^^ meta.class +// ^^^ storage.modifier.java +// ^^^^^ storage.type.java +// ^^^^^^^^^^ meta.class.identifier entity.name.class.java +// ^ - meta.class.identifier.java - meta.class.body.java +// ^ meta.class.body.java + private String memberString = "Hello"; + private String memberString2 = new String("Hello"); +// ^^^^^^ support.class.java + private String memberString3 = String.valueOf("Hello"); +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.assignment.rhs.java +// ^^^^^^^ storage.modifier.java +// ^^^^^^ support.class.java +// ^ keyword.operator.assignment.java +// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.assignment.rhs.java +// ^^^^^^^ string.quoted.double.java +// ^ punctuation.definition.string.begin.java +// ^ punctuation.definition.string.end.java +// ^ - string.quoted.double.java +// ^ punctuation.terminator.java - meta.assignment.rhs.java + private int memberLpos = memberString3.indexOf("l"); +// ^^^ storage.type +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.assignment.rhs.java +// ^^^ string +// ^ punctuation.terminator.java + + public static void main(String... args) { +// ^^^^^^^^^^^^^^^^^^^^^^^ meta.method +// ^^^^^^ storage.modifier.java +// ^^^^^^ storage.modifier.java +// ^^^^ storage.type +// ^^^^ meta.method.identifier.java entity.name.function.java +// ^^^^^^^^^^^^^^^^ meta.method.parameters.java +// ^ punctuation.section.parens.begin.java +// ^^^ keyword.operator.variadic.java +// ^^^^^ support.class.java +// ^^^^ variable.parameter.java +// ^ punctuation.section.parens.end.java +// ^ - meta.method.parameters +// ^ meta.method.body.java punctuation.section.block.begin.java + String[] strings = new String[5]; +// ^^^^^^^^^^^^^^ meta.assignment.rhs.java +// ^^^ keyword.other.storage.new.java +// ^ constant.numeric.integer.decimal + printList(Arrays.stream(args) + .collect(Collectors.toCollection(ArrayList::new))); +// ^^^ meta.method.body.java - keyword.other.storage.new.java +// ^^^ variable.function.reference.java +// ^^ punctuation.accessor.double-colon.java + anotherMethod(); + try (Stream<String> lines = Files.lines(path)) { +// ^^^ keyword.control.exception.try.java +// ^^^^^^^^^^^^^^^^^^ meta.assignment.rhs.java +// ^ - meta.parens.java +// ^ meta.method.body.java - meta.assignment.rhs.java + lines.forEach(System.out::println); +// ^^^^^^^ variable.function.reference.java + + } catch (IOException ignore) { +// ^^^^^^ meta.catch.java +// ^^^^^^^^^^^^^^^^^^^^ meta.catch.parameters.java meta.parens.java +// ^^^^^ keyword.control.exception.catch.java +// ^ punctuation.section.parens.begin.java +// ^^^^^^^^^^^ support.class.java +// ^^^^^^ variable.parameter +// ^ punctuation.section.parens.end.java + } catch (final MyException | com.net.org.Foo.Bar | +// ^^^^^^ meta.catch.java +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.catch.parameters.java meta.parens.java +// ^^^^^ keyword.control.exception.catch.java +// ^ punctuation.section.parens.begin +// ^ meta.catch.parameters storage.modifier.java +// ^^^^^^^^^^^ support.class +// ^ punctuation.separator.bar.java +// ^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^ support.class.java +// ^ punctuation.accessor.dot.java +// ^^^ support.class.java +// ^ punctuation.separator.bar.java + YourException ignore) {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.catch +// ^ support.class +// ^ variable.parameter +// ^ meta.catch.parameters +// ^ punctuation.section.parens.end + + try (final InputStream is = new FileInputStream(args[0]); +// ^^^^^ storage.modifier + final OutputStream os = new FileOutputStream(args[1])) { +// ^^^^^ storage.modifier + + os.write(is.read()); +// ^^^^ variable.function + } + + try { +// ^^^ keyword.control.exception.try.java + Class.forName(args[2]); + } catch (Exception e) { +// ^^^^^ keyword.control.exception.catch.java + log.error(e); + } finally { +// ^^^^^^^ keyword.control.exception.finally.java + } + + for (final int x = 10;;) { System.out.println(x); break; } +// ^^^^^ storage.modifier + + for (int i = 0; i < 10; i+= 2) { +// ^^^ keyword.control +// ^^^ storage.type +// ^ keyword.operator.assignment.java +// ^ constant.numeric.integer.decimal +// ^^ meta.assignment.rhs.java +// ^ punctuation.terminator.java - meta.assignment.rhs.java +// ^ keyword.operator.comparison.java +// ^^ constant.numeric.integer.decimal +// ^ punctuation.terminator.java +// ^^ keyword.operator.assignment.java +// ^^ meta.assignment.rhs.java +// ^ - meta.assignment.rhs.java + System.out.println(i); + } + } +// ^ meta.method.java meta.method.body.java punctuation.section.block.end.java + private static void printList(List<String> args) { +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method +// ^^^^^^^ storage.modifier.java +// ^^^^^^ storage.modifier.java +// ^^^^ storage.type +// ^^^^^^^^^ meta.method.identifier entity.name.function.java +// ^^^^^^^^^^^^^^^^^^^ meta.method.parameters +// ^^^^^^ support.class.java +// ^^^^ variable.parameter.java +// ^^ - meta.method.identifier.java +// ^^ meta.method.body.java + args.stream().forEach(System.out::println); +// ^^ punctuation.accessor.double-colon.java + } + + private static void anotherMethod() throws MyException<Abc> { +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method +// ^^^^^^^ storage.modifier.java +// ^^^^^^ storage.modifier.java +// ^^^^ storage.type +// ^^^^^^^^^^^^^ meta.method.identifier entity.name.function.java +// ^^ meta.method.parameters +// ^^^^^^^^^^^^^^^^^^^^^^^ meta.method.throws +// ^^^^^^ keyword.declaration.throws.java +// ^^^^^ meta.generic.java +// ^^ meta.method.body.java -meta.method.throws + throw new MyException + ("hello (world)"); +// ^ - string + } + <T> void save(T obj); +// ^^^^^^^^^^^ meta.method +// ^^^ meta.generic +// ^ variable.parameter.type +// ^^^^ storage.type +// ^^^^ meta.method.identifier +// ^^^^^^^ meta.method.parameters +} + +class ExtendsTest extends Foo {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class +// ^^^^^^^^^^^ meta.class.extends +// ^^^^^^^ keyword.declaration.extends.java +// ^^^ entity.other.inherited-class.java +// ^ - meta.class.extends + +class ExtendsTest implements Foo {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class +// ^^^^^^^^^^^^^^ meta.class.implements.java +// ^^^^^^^^^^ keyword.declaration.implements.java +// ^^^ entity.other.inherited-class.java +// ^ - meta.class.implements.java + +class Foo<A> extends Bar<? extends A> {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class +// ^^^ meta.generic.declaration.java +// ^ variable.parameter.type.java +// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.extends +// ^^^^^^^ keyword.declaration.extends.java + +class ExtendsAndImplementsTest extends Foo implements Bar<Foo>, OtherBar {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class +// ^^^^^^^^^^^ meta.class.extends +// ^^^^^^^ keyword.declaration.extends.java +// ^^^ entity.other.inherited-class.java +// ^ - meta.class.extends +// ^^^^^^^^^^^^^^ meta.class.implements.java +// ^^^^^^^^^^ keyword.declaration.implements.java +// ^^^ entity.other.inherited-class.java +// ^^^^^ meta.generic.java +// ^ punctuation.separator.comma.java +// ^^^^^^^^ entity.other.inherited-class.java +// ^ - meta.class.implements.java + +class ExtendsAndImplementsTest extends Foo, Bar implements Bar<Foo>, OtherBar {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class +// ^^^^^^^^^^^^^^^^^ meta.class.extends +// ^^^^^^^ keyword.declaration.extends.java +// ^^^ entity.other.inherited-class.java +// ^ punctuation.separator.comma.java +// ^^^ entity.other.inherited-class.java +// ^ - meta.class.extends +// ^^^^^^^^^^^^^^ meta.class.implements.java +// ^^^^^^^^^^ keyword.declaration.implements.java +// ^^^ entity.other.inherited-class.java +// ^^^^^ meta.generic.java +// ^ punctuation.separator.comma.java +// ^^^^^^^^ entity.other.inherited-class.java +// ^ - meta.class.implements.java + +class AnyClass { +// ^^^^^^^^ entity.name.class.java + int bar; // this comment() is recognized as code +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line +// ^^ punctuation.definition.comment.java + + public void anyMethod(String finality){ +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method +// ^^^^^^^^^ meta.method.identifier +// ^^^^^^^^^^^^^^^^^ meta.method.parameters +// ^^^^^^^^ variable.parameter - storage.modifier +// ^^ meta.method.body.java - meta.method.identifier.java + System.out.println("Printed: " + finality); +// ^ keyword.operator + } + + public abstract <A> void test(A thing); +// ^^^ meta.generic.declaration.java +// ^ variable.parameter.type.java + + public void test2(Type) abc +// ^^^ - variable.parameter +// ^ - meta.method.java +} +// <- punctuation.section.block.end.java + +interface T extends A, BB {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.java +// ^^ meta.class.identifier.java +// ^^^^^^^^^^^^^^ meta.class.extends.java +// ^^ meta.class.body.java +// ^ entity.name.class.java +// ^^^^^^^ keyword.declaration.extends.java +// ^ entity.other.inherited-class.java +// ^ punctuation.separator.comma.java +// ^^ entity.other.inherited-class.java +// ^ punctuation.section.block.begin.java +// ^ punctuation.section.block.end.java + +public enum FooBaz { +// ^^^^ storage.type.java +//^^^^^^^^^^^^^^^^^^ meta.class +// ^^^^^^ meta.class.identifier.java entity.name.class.java +// ^ meta.class.body + // This is a test +// ^^^^^^^^^^^^^^^^^^ comment.line + UPLOAD("foo bar"), /* This a comment */ +// ^^^^^^ constant.other.enum +// ^^^^^^^^^ string.quoted.double.java +// ^^^^^^^^^^^^^^^^^^^^ comment.block +// ^ - comment.block + DELETE("baz"), +// ^^^^^^ constant.other.enum + // Comment here +// ^^^^^^^^^^^^^^^^ comment.line +} + +enum MyEnum { + FIRST_VALUE, // comment1 +//^^^^^^^^^^^ constant.other.enum +// ^^^^^^^^^^^ comment + MID_VALUE, // comment2 +//^^^^^^^^^ constant.other.enum +// ^^^^^^^^^^^ comment + LAST_VALUE // comment3 +//^^^^^^^^^^ constant.other.enum +// ^^^^^^^^^^^ comment +} + +public enum TokenKind extends MyEnum, FooBaz implements Foo, Bar { +//<- meta.class.java storage.modifier.java +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.java +//^^^^ storage.modifier.java +// ^^^^ storage.type.java +// ^^^^^^^^^ entity.name.class.java +// ^^^^^^^ keyword.declaration.extends.java +// ^^^^^^ entity.other.inherited-class.java +// ^ punctuation.separator.comma.java +// ^^^^^^ entity.other.inherited-class.java +// ^^^^^^^^^^ keyword.declaration.implements.java +// ^^^ entity.other.inherited-class.java +// ^ punctuation.separator.comma.java +// ^^^ entity.other.inherited-class.java +// ^ punctuation.section.block.begin.java + a, +// ^ constant.other.enum.java +// ^ punctuation.separator.comma.java + a(1, 2, 3), +// ^ constant.other.enum.java +// ^^^^^^^^^ meta.parens.java +// ^ punctuation.section.parens.begin.java +// ^ constant.numeric.integer.decimal.java +// ^ punctuation.separator.comma.java +// ^ constant.numeric.integer.decimal.java +// ^ punctuation.separator.comma.java +// ^ constant.numeric.integer.decimal.java +// ^ punctuation.section.parens.end.java +// ^ punctuation.separator.comma.java + a {}, +// ^ constant.other.enum.java +// ^ meta.block.java punctuation.section.block.begin.java +// ^ meta.block.java punctuation.section.block.end.java +// ^ punctuation.separator.comma.java + A, +// ^ constant.other.enum.java +// ^ punctuation.separator.comma.java + A(1), +// ^ constant.other.enum.java +// ^^^ meta.parens.java +// ^ punctuation.section.parens.begin.java +// ^ constant.numeric.integer.decimal.java +// ^ punctuation.section.parens.end.java +// ^ punctuation.separator.comma.java + A {}, +// ^ constant.other.enum.java +// ^ meta.block.java punctuation.section.block.begin.java +// ^ meta.block.java punctuation.section.block.end.java +// ^ punctuation.separator.comma.java + integerToken, +// ^^^^^^^^^^^^ constant.other.enum.java +// ^ punctuation.separator.comma.java + integerToken("integer literal"), +// ^^^^^^^^^^^^^^^^^^^ meta.parens.java +// ^^^^^^^^^^^^ constant.other.enum.java +// ^ punctuation.section.parens.begin.java +// ^^^^^^^^^^^^^^^^^ string.quoted.double.java +// ^ punctuation.section.parens.end.java +// ^ punctuation.separator.comma.java + integerToken {}; +// ^^^^^^^^^^^^ constant.other.enum.java +// ^ meta.block.java punctuation.section.block.begin.java +// ^ meta.block.java punctuation.section.block.end.java +// ^ punctuation.terminator.java + int {} +// ^^^ storage.type.primitive.java + static {} +// ^^^^^^ storage.modifier.java + String image = ""; +// ^^^^^^ support.class.java +// ^^^^^ meta.field.java +// ^ keyword.operator.assignment.java +// ^^ string.quoted.double.java +// ^ punctuation.terminator.java + TokenKind(String s) {} +// ^^^^^^^^^^^^^^^^^^^^^^ meta.method.java +// ^^^^^^^^^ meta.method.identifier.java entity.name.function.constructor.java +// ^^^^^^^^^^ meta.method.parameters.java meta.parens.java +// ^^ meta.method.body.java +// ^ punctuation.section.parens.begin.java +// ^^^^^^ support.class.java +// ^ variable.parameter.java +// ^ punctuation.section.parens.end.java +// ^ punctuation.section.block.begin.java +// ^ punctuation.section.block.end.java + public static void main(String[]a){} +// ^^^^^^^^^^^^^^ meta.class.java meta.class.body.java meta.block.java +// ^^^^^^^^^^^^^^^^^^^^^^ meta.class.java meta.class.body.java meta.block.java meta.method.java +// ^^^^ meta.method.identifier.java +// ^^^^^^^^^^^ meta.method.parameters.java meta.parens.java +// ^^ meta.method.body.java +// ^^^^^^ storage.modifier.java +// ^^^^^^ storage.modifier.java +// ^^^^ storage.type.void.java +// ^^^^ entity.name.function.java +// ^ punctuation.section.parens.begin.java +// ^^^^^^ support.class.java +// ^^ storage.modifier.array.java +// ^ variable.parameter.java +// ^ punctuation.section.parens.end.java +// ^ punctuation.section.block.begin.java +// ^ punctuation.section.block.end.java +} + +public // comment +//<- storage.modifier.java +enum // comment +//<- meta.class.java meta.class.identifier.java storage.type.java +TokenKind // comment +//<- meta.class.java meta.class.identifier.java entity.name.class.java +extends // comment +//<- meta.class.java meta.class.extends.java keyword.declaration.extends.java +MyEnum, // comment +//<- meta.class.java meta.class.extends.java entity.other.inherited-class.java +FooBaz // comment +//<- meta.class.java meta.class.extends.java entity.other.inherited-class.java +implements // comment +//<- meta.class.java meta.class.implements.java keyword.declaration.implements.java +Foo, // comment +//<- meta.class.java meta.class.implements.java entity.other.inherited-class.java +Bar // comment +//<- meta.class.java meta.class.implements.java entity.other.inherited-class.java +{ +//<- meta.class.java meta.class.body.java meta.block.java punctuation.section.block.begin.java +} +//<- meta.class.java meta.class.body.java meta.block.java punctuation.section.block.end.java + +class InvalidStuff +{ + goto +// ^^^^ invalid.illegal + + const int 3; +// ^^^^^ invalid.illegal +} + +public class Lambdas { + volatile int foo; +//^^^^^^^^ storage.modifier.java + + void anonymousFunctions() { + foo(); +// ^^^ variable.function.java + +// Capital names are usually used for classes + Foo(); +// ^^^ variable.function.java + + foo (); +// ^^^ variable.function.java + this.<A>foo(); +// ^^^ variable.function.java +// ^^^ meta.generic.java +// ^ punctuation.definition.generic.begin.java +// ^ support.class.java + this.<B> foo(); +// ^^^ variable.function.java +// ^^^ meta.generic.java +// ^ punctuation.definition.generic.begin.java +// ^ support.class.java + + Function<String, Integer> func = a -> 42; +// ^^^^^^^^^ meta.assignment.rhs.java +// ^ variable.parameter.java +// ^^ storage.type.function.anonymous.java +// ^^ constant.numeric.integer.decimal +// ^ punctuation.terminator.java + foo(a -> 42); +// ^^^^^^^^^^^^ meta.function-call.java +// ^^^ variable.function.java +// ^ punctuation.section.parens.begin.java +// ^ variable.parameter.java +// ^^ storage.type.function.anonymous.java +// ^^ constant.numeric.integer.decimal +// ^ punctuation.section.parens.end.java +// ^ punctuation.terminator.java + + a -> { return 42; }; +// ^^^^^^^^^^^^^^ meta.function.anonymous.body.java + + (a, b) -> 42; +// ^ variable.parameter.java +// ^ variable.parameter.java +// ^^ storage.type.function.anonymous.java +// ^^ constant.numeric.integer.decimal + + (int a, Foo<Integer>[] b) -> 42; +// ^^^ storage.type.primitive +// ^ variable.parameter.java +// ^^^ support.class.java +// ^ punctuation.definition.generic.begin.java +// ^^^^^^^ support.class.java +// ^ punctuation.definition.generic.end.java +// ^ variable.parameter.java +// ^^ storage.type.function.anonymous.java +// ^^ constant.numeric.integer + + // Lambda parameter tests + Function<String, String> lambda1 = (final @MyAnnotation String foo) -> foo; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.anonymous.parameters.java +// ^^^^^ storage.modifier.java +// ^^^^^^^^^^^^^ meta.annotation +// ^ punctuation.definition.annotation +// ^^^^^^ support.class.java - meta.annotation +// ^^^ variable.parameter.java +// ^^ storage.type.function.anonymous.java - meta.function.anonymous.parameters.java + + Function<String, String> lambda2 = (@MyAnnotation String foo) -> foo; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.anonymous.parameters.java +// ^^^^^^^^^^^^^ meta.annotation +// ^ punctuation.definition.annotation +// ^^^^^^ support.class.java - meta.annotation +// ^^^ variable.parameter.java +// ^^ storage.type.function.anonymous.java - meta.function.anonymous.parameters.java + + Function<String, String> lambda3 = (@MyAnnotation(foo = Foo.BAR) String foo) -> foo; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.anonymous.parameters.java +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation +// ^ punctuation.definition.annotation +// ^^^ variable.parameter.java +// ^^^ support.class.java +// ^ punctuation.accessor.dot.java +// ^^^ constant.other.java +// ^^^^^^ support.class.java - meta.annotation +// ^^^ variable.parameter.java +// ^^ storage.type.function.anonymous.java - meta.function.anonymous.parameters.java + + Function<String, String> lambda4 = (String foo) -> foo; +// ^^^^^^^^^^^^ meta.function.anonymous.parameters.java +// ^^^^^^ support.class.java - meta.annotation +// ^^^ variable.parameter.java +// ^^ storage.type.function.anonymous.java - meta.function.anonymous.parameters.java + + Function<String, String> lambda5 = (foo) -> foo; +// ^^^^^ meta.function.anonymous.parameters.java +// ^^^ variable.parameter.java +// ^^ storage.type.function.anonymous.java - meta.function.anonymous.parameters.java + + Function<String, String> lambda6 = foo -> foo; +// ^^^ meta.function.anonymous.parameters.java +// ^^^ variable.parameter.java +// ^^ storage.type.function.anonymous.java - meta.function.anonymous.parameters.java + + Function<String[], String> lambda7 = (String... foo) -> foo[0]; +// ^^^^^^^^^^^^^^^ meta.function.anonymous.parameters.java +// ^^^^^^ support.class.java - meta.annotation +// ^^^ keyword.operator.variadic.java +// ^^^ variable.parameter.java +// ^^ storage.type.function.anonymous.java - meta.function.anonymous.parameters.java + + IntFunction<String> intLambda1 = (int foo) -> String.valueOf(foo); +// ^^^^^^^^^ meta.function.anonymous.parameters.java +// ^^^ storage.type.primitive - meta.annotation +// ^^^ variable.parameter.java +// ^^ storage.type.function.anonymous.java - meta.function.anonymous.parameters.java + } +} + +class Generics { + + List<String> field; +// ^^^^^^^^ meta.generic.java +// ^ punctuation.definition.generic.begin.java +// ^^^^^^ support.class.java +// ^ punctuation.definition.generic.end.java + + List<java.net.URI> field; +// ^^^^^^^^^^^^^^ meta.generic.java +// ^ punctuation.definition.generic.begin.java +// ^^^^^^^^^^^^ meta.path.java +// ^^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^ support.class.java + + void variableTypes() { + List<String> x; +// ^^^^^^^^ meta.generic.java +// ^ punctuation.definition.generic.begin.java +// ^ punctuation.definition.generic.end.java + + List<java.lang.String> x; +// ^^^^^^^^^^^^^^^^^^ meta.generic.java +// ^^^^^^^^^^^^^^^^ meta.path.java +// ^^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^^ support.class.java +// ^ punctuation.definition.generic.end.java + + List<URI> x; +// ^^^^^ meta.generic.java +// ^^^ support.class.java + + List<java.net.URI> x; +// ^^^^^^^^^^^^^^ meta.generic.java +// ^^^^^^^^^^^^ meta.path.java +// ^^^ support.class.java + + List<int[]> x; +// ^^^^^^^ meta.generic.java +// ^^^ storage.type.primitive.java +// ^^ storage.modifier.array.java + + List<java.lang.String[]> x; +// ^^^^^^^^^^^^^^^^^^^^ meta.generic.java +// ^^^^^^^^^^^^^^^^ meta.path.java +// ^^ storage.modifier.array.java + + List<URI[]> x; +// ^^^^^^^ meta.generic.java +// ^^^ support.class.java +// ^^ storage.modifier.array.java + + List<int[][]>[][] x; +// ^^^^^^^^^ meta.generic.java +// ^^^ storage.type.primitive.java +// ^^^^ storage.modifier.array.java +// ^^^^ storage.modifier.array.java + } + + void instantiation() { + + new Foo<Abc>(); +// ^^^^^ meta.generic.java +// ^^^ support.class.java +// ^ punctuation.definition.generic.begin.java +// ^ punctuation.definition.generic.end.java + + new Foo<?>(); +// ^ keyword.operator.wildcard.java + + new Foo<? extends Bar, String>(); +// ^ keyword.operator.wildcard.java +// ^^^ support.class.java +// ^^^^^^^ keyword.declaration.extends.java +// ^ punctuation.separator.comma.java + // ^^^^^^ support.class.java + + new Foo<? super Bar>(); +// ^ keyword.operator.wildcard.java +// ^^^^^ keyword.declaration.super.java + + new Foo<int>(); +// ^^^ -storage.type.primitive + + new Foo<String, int>(); +// ^^^^^^ support.class.java +// ^^^ -storage.type.primitive + + new Foo<a.b.FooBar>(); +// ^^^^^^^^^^^^ meta.generic.java +// ^^^^^^^^^^ meta.path.java +// ^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^ support.type.package.java +// ^ punctuation.accessor.dot.java + + new Foo<?>[] { new Foo(1), new Foo(2) }; +// ^^^ meta.generic.java +// ^^ punctuation.section.brackets +// ^ punctuation.section.braces.begin +// ^^^ support.class.java +// ^ punctuation.separator.comma.java +// ^^^ support.class.java +// ^ punctuation.section.braces.end + + new ArrayList<?>[] { new ArrayList<java.sql.Date>(), new ArrayList<Date>() } +// ^^^^^^^^^^^^^^^ meta.generic.java +// ^^^^^^^^^^^^^ meta.path.java +// ^^^^^^ meta.generic.java + + new a. +// ^^ meta.path.java + b.Foo<a. +// ^^^^^ meta.path.java +// ^^ meta.generic.java meta.path.java + b.Foo>(); +// ^^^^^ meta.generic.java meta.path.java + } +} + +public class Test { + + void test1() { + Foo.abc(); +// ^ punctuation.accessor.dot.java +// ^^^ variable.function.java + Foo.class; +// ^ punctuation.accessor.dot.java +// ^^^^^ variable.language.java - storage.type.java +// ^ punctuation.terminator.java + } + + void test2() { +// ^^^^^ entity.name.function.java + } +} + +@ClassName.FixMethodOrder( MethodSorters.NAME_ASCENDING ) +// <- meta.annotation punctuation.definition.annotation -meta.annotation.identifier +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation +//^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation.identifier +//^^^^^^^^ variable.annotation.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation.parameters +// ^ punctuation.accessor.dot +// ^ constant +public class GrafoTest { + @Override +// ^^^^^^^^^ meta.annotation +// ^ punctuation.definition.annotation +// ^^^^^^^^ variable.annotation.java + void test1() { +// ^ entity.name.function + } + + @Author(first = "Oompah", last = "Loompah") +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation +// ^ punctuation.definition.annotation +// ^^^^^^ meta.annotation.identifier variable.annotation.java +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation.parameters +// ^ punctuation.section.parens.begin +// ^^^^^ variable.parameter.java +// ^ keyword.operator +// ^^^^^^^^ string +// ^ punctuation.separator.comma.java +// ^^^^ variable.parameter.java +// ^ keyword.operator +// ^^^^^^^^ string +// ^ punctuation.section.parens.end + void test2() { +// ^ entity.name.function + + Grafo grafo = new Grafo( true ); + final Grafo temposMaisCedo = new Grafo( true ); +// ^ storage.modifier +// ^ support.class + } + + + @Partial @Mock(type=Grafo.class) DataLoader inline; +// ^^^^^^^^ meta.annotation +// ^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation +// ^ support.class + + @Override public int inline() { +// ^^^^^^^^^ meta.annotation +// ^ punctuation.definition.annotation +// ^^^^^^^^ variable.annotation + } + + void annotatedArgs(@NonNull final String p1, +// ^^^^^^^^ meta.annotation +// ^ storage.modifier - meta.annotation + @Named(value = "") List<T> p2, @NonNull final String p3) {} +// ^^^^^^^^^^^^^^^^^^ meta.annotation +// ^ support.class +// ^ meta.generic punctuation.definition.generic.begin +// ^ variable.parameter +// ^ punctuation.separator +// ^^^^^^^^ meta.annotation +// ^ storage.modifier - meta.annotation +// ^ support.class + +} + +public enum FooEnum { +// ^^^^ storage.type.java + FOO; +//^^^ constant.other.enum +} +// <- meta.class.java meta.class.body.java punctuation.section.block.end.java + +public enum FooBarEnum { +// ^^^^ storage.type.java + FOO, +//^^^ constant.other.enum + BAR; +//^^^ constant.other.enum +} + +public enum AbstractEnum { +// ^^^^ storage.type.java + FOO { +//^^^ constant.other.enum +// ^ meta.enum.java meta.enum.body.java meta.block.java punctuation.section.block.begin.java + public void doSomething() { return; } +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.java + }, +//^ meta.enum.java meta.enum.body.java meta.block.java punctuation.section.block.end.java + BAR { +//^^^ constant.other.enum + public void doSomething() { return; } +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.java + }; + + public abstract void doSomething(); +// ^^^^^^^^^^^^^ meta.method.java +} + +public final class SomeClass<V extends OtherClass, T> extends BaseClass<V> { +// ^ punctuation.definition.generic.begin.java +// ^ punctuation.definition.generic.end.java +// ^ punctuation.separator.comma.java +// ^ support.class.java +// ^ punctuation.section.block.begin.java +} + +public @interface PublicAnnotation { +// ^^^^^^^^^^ storage.type.java + int numericValue() default 42; +// ^^^^^^^ keyword.declaration.default.java +// ^^ constant.numeric + boolean booleanValue() default true; +// ^^^^^^^ keyword.declaration.default.java +// ^^^^ constant.language + char charValue() default 'S'; +// ^^^^^^^ keyword.declaration.default.java +// ^^^ string.quoted.single.java + String value() default "Default value"; +// ^^^^^^^ keyword.declaration.default.java +// ^^^^^^^^^^^^^^^ string.quoted.double.java + Class<?> classValue() default String.class; +// ^^^^^^^ keyword.declaration.default.java +// ^^^^^^ support.class.java +// ^^^^^ variable.language.java + String[] arrayValue() default {"Foo", "Bar"}; +// ^^^^^^^ keyword.declaration.default.java +// ^ punctuation.section.block.begin +// ^^^^^ string.quoted.double.java +// ^^^^^ string.quoted.double.java +// ^ punctuation.section.block.end +} + +@interface PackageAnnotation {} +//^^^^^^^^ storage.type.java + +@MultiLineAnnotation( +// <- meta.annotation.java +// <- punctuation.definition.annotation.java +//^^^^^^^^^^^^^^^^^^ variable.annotation.java +// ^ meta.annotation.java meta.annotation.parameters.java punctuation.section.parens.begin.java + foo = BAR, +//^^^ variable.parameter.java +// ^ keyword.operator.assignment.java +// ^ constant.other.java +// ^ punctuation.separator.comma.java + other = "foo" +//^^^^^ variable.parameter.java +// ^ keyword.operator.assignment.java +// ^ string +) +// <- meta.annotation.java meta.annotation.parameters.java punctuation.section.parens.end.java +@fully.qualified.Annotation +// <- punctuation.definition.annotation.java +//^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation.java meta.annotation.identifier.java meta.path.java +//^^^^ variable.annotation.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^ variable.annotation.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^ variable.annotation.java +@fully.qualified.ParentClass.InnerAnnotation +// <- punctuation.definition.annotation.java +//^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation.java meta.annotation.identifier.java meta.path.java +//^^^^ variable.annotation.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^ variable.annotation.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^^^ variable.annotation.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^^^^^^^ variable.annotation.java +@fully.qualified +//^^^^^^^^^^^^^^ meta.annotation.identifier.java meta.path.java + .multiline.Annotation +// ^^^^^^^^^^^^^^^^^^^^^ meta.annotation.identifier.java meta.path.java + (foo = "bar") +// ^^^^^^^^^^^^^ meta.annotation.parameters.java -meta.annotation.identifier.java +@FancyAnnotation({ +// <- punctuation.definition.annotation.java +// ^^ meta.annotation.parameters.java + Foo.class, +//^^^ support.class.java +// ^ punctuation.accessor.dot.java +// ^^^^^ variable.language.java +// ^ punctuation.separator.comma.java + Bar.class +//^^^ support.class.java +// ^ punctuation.accessor.dot.java +// ^^^^^ variable.language.java +}) +// <- punctuation.section.braces.end.java + // <- meta.annotation.java meta.annotation.parameters.java punctuation.section.parens.end.java +class Bàr { +// ^^^ entity.name.class.java + Bàr() {} +//^^^^^ meta.method.java +//^^^ entity.name.function.constructor.java +} + +@AnnotationAsParameterSingle( + @Parameter(name = "foo") +// ^ punctuation.definition.annotation.java +// ^^^^^^^^^ variable.annotation.java +// ^^^^ variable.parameter.java +) + +@AnnotationAsParameterSingleNamed( + value = @Parameter(name = "foo") +//^^^^^ variable.parameter.java +// ^ punctuation.definition.annotation.java +// ^^^^^^^^ variable.annotation.java +// ^^^^ variable.parameter.java +) + +@AnnotationAsParameterMultiple({ +// ^ punctuation.section.braces.begin.java + @Parameter(name = "foo"), +// ^ punctuation.definition.annotation.java +// ^^^^^^^^^ variable.annotation.java +// ^^^^ variable.parameter.java + + @Parameter(name = "bar") +// ^ punctuation.definition.annotation.java +// ^^^^^^^^^ variable.annotation.java +// ^^^^ variable.parameter.java +}) +// <- punctuation.section.braces.end.java + +@AnnotationAsParameterMultipleNamed( + first = {@Parameter(name = "foo"), @Parameter(name = "bar")}, +//^^^^^ variable.parameter.java +// ^ punctuation.definition.annotation.java +// ^^^^^^^^^ variable.annotation.java +// ^^^^ variable.parameter.java +// ^ punctuation.definition.annotation.java +// ^^^^^^^^^ variable.annotation.java +// ^^^^ variable.parameter.java + second = {@Parameter(name = "foo"), @Parameter(name = "bar")}, +//^^^^^^ variable.parameter.java + third = @Parameter(name = "foo") +//^^^^^ variable.parameter.java +// ^^^^^^^^^ variable.annotation.java +) + +@SomeInterface +// <- punctuation.definition.annotation.java +public class Foo { +// <- meta.class.java storage.modifier.java +// ^ meta.class.java meta.class.identifier.java storage.type.java +// ^ punctuation.section.block.begin.java + + FooBar MY_CONST = new FooBar(); +// ^^^^^^^^ entity.name.constant.java + + @Inject +//^^^^^^^ meta.annotation + public Foo( +//^ - meta.annotation +// ^ meta.method.java +// ^ entity.name.function.constructor + // Comment for annotation + @MyAnnotation FooType annotatedParam, +// ^ meta.annotation.java +// ^ - meta.annotation.java +// ^ support.class.java +// ^ variable.parameter.java + String unannotatedParam) { +// ^ support.class.java +// ^ variable.parameter.java + return; +// ^^^^^^ keyword.control.flow.return.java + } + + void bar$() {} +// ^^^^^^ meta.method.java +// ^^^^ entity.name.function + + void à() {} +// ^^ meta.method.java +// ^ entity.name.function + + public static void main(String[] args, String<List> moreArgs, a.b.c.Foo bar) {} +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.parameters.java +// ^^^^^^ support.class.java +// ^^ storage.modifier.array.java +// ^^^^ variable.parameter.java +// ^ punctuation.separator.comma.java +// ^^^^^^ meta.generic.java +// ^^^^^^ support.class.java +// ^^^^ support.class.java +// ^^^^^^^^ variable.parameter.java +// ^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^ punctuation.accessor.dot.java +// ^^^ support.class.java +// ^^^ variable.parameter.java + + MyClass myClass = new MyClass( + SomeEnum.ENUM_VALUE, + new OtherNewClass(), + new OtherNestedClass( + SomeEnum.ENUM_VALUE, + new SuperNestedClass(param, 2)), + anotherParam); + + public static final MyObject MY_CONST = new MyObject(), +// ^ entity.name.constant + + _MY_ANOTHER_CONST = new MyObject(); +// ^^^^^^^^^^^^^^^^^ entity.name.constant + + Object foo = new TypeLiteral< + StandardReferenceNumberProcessor< + SimpleGenerateReferenceNumberOperation, + SimpleSyncReferenceNumberOperation>>() {}; + + Object bar = SomeStaticClass.newBuilder().doThings(1) +// ^ meta.function-call.java variable.function.java +// ^ meta.function-call.java variable.function.java +// ^ meta.function-call.java constant.numeric.integer.decimal + .withString("I am a string"); +// ^ meta.function-call.java variable.function.java +// ^ meta.function-call.java string.quoted.double.java + + Object bah = someStaticMethodCall(4) +// ^ meta.function-call.java variable.function.java +// ^ meta.function-call.java constant.numeric.integer.decimal + .withString("I am a string"); +// ^ meta.function-call.java variable.function.java +// ^ meta.function-call.java string.quoted.double.java + + private static final String DEFAULT_IDEMPOTENCY_KEY = 44493; +// ^ entity.name.constant +// ^ constant.numeric.integer.decimal + + + private MyGenric<Param, With.Dots, With.Nested<Generic>, and.fully.Qualified, +// ^ meta.generic.java support.class.java +// ^ meta.generic.java punctuation.accessor.dot.java +// ^^^^^^^^^^^^^^^^^^^ meta.path.java + and.fully.Qualified<Generic>> myVariable; +// ^^^^^^^^^^^^^^^^^^^ meta.path.java +// ^ meta.generic.java meta.generic.java support.class.java + + private MyObject otherObject = MY_CONST; +// ^ constant.other.java + + private MyObject otherObject = SOME_CONST.FOO; +// ^ constant.other.java +// ^ constant.other.java + + private MyObject otherObject = SOME_CONST.get(); +// ^ constant.other.java +// ^ variable.function.java + + private MyObject object = a.b.ErrorCode.COMMUNICATION_ERROR; +// ^^^^^^^^^^^^^ meta.path.java +// ^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^ support.class.java +// ^ punctuation.accessor.dot.java +// ^ constant.other.java + + private static final UUID SECURE_ID = UUID.randomUUID(); +// ^ support.class.java +// ^ entity.name.constant +// ^ support.class.java +// ^ meta.function-call.java variable.function.java + + private URI uri = new URI(); +// ^^^ support.class.java +// ^^^ support.class.java + + private URI URI2 = new URI(); +// ^^^ support.class.java +// ^^^^ entity.name.constant.java +// ^^^ support.class.java + + + class SubClass extends AbstractClass.NestedClass { +// ^ entity.name.class.java +// ^^^^^^^^^^^^^ entity.other.inherited-class.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^^^ entity.other.inherited-class.java +// ^ punctuation.section.block.begin.java + } + + class SubClass extends AbstractClass { +// ^ entity.name.class.java +// ^ entity.other.inherited-class.java + } + + class SubClass extends fully.qualified +// ^ entity.name.class.java +// ^^^^^^^^^^^^^^^ meta.path.java +// ^^^^^ entity.other.inherited-class.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^ entity.other.inherited-class.package.java + .name.AbstractClass { +// ^^^^^^^^^^^^^^^^^^^ meta.path.java +// ^ punctuation.accessor.dot.java +// ^^^^ entity.other.inherited-class.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^^^^^ entity.other.inherited-class.java + } + + Function<Foo, Bar> BLOCK_LAMBDA = r -> { +// ^ entity.name.constant +// ^ keyword.operator.assignment.java +// ^ storage.type.function.anonymous.java +// ^ meta.block punctuation.section.block.begin + return 1; +// ^^^^^^ keyword.control.flow.return.java + }; +//^ meta.block punctuation.section.block.end +// ^ punctuation.terminator + + Supplier<Foo> supplier = () -> true; +// ^ punctuation.section.parens.begin.java +// ^ punctuation.section.parens.end.java +// ^ keyword.operator.assignment.java +// ^ storage.type.function.anonymous.java +// ^ punctuation.terminator + + byte[] byteArray; +//^^^^ storage.type.primitive.java +// ^^ storage.modifier.array.java + + byte byteArray2[] = {1, 2}; +//^^^^ storage.type.primitive.java +// ^^ storage.modifier.array.java +// ^^^^^^^^ meta.assignment.rhs.java + + static { +// ^ meta.static.body.java punctuation.section.block.begin.java + StaticFlag.setFlag("Boo!"); + } +//^ meta.static.body.java punctuation.section.block.end.java + + int operators() { + + assert scale > -100 : foo == true; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.assertion.java +// ^^^^^^ keyword.control.flow.assert.java +// ^ punctuation.separator.expressions.java +// + if (this.scale<0) { +// ^^ keyword.control.conditional.if.java +// ^^^^^^^^^^^^^^ meta.parens.java +// ^ punctuation.section.parens.begin +// ^ punctuation.accessor.dot.java +// ^ keyword.operator.comparison.java +// ^ constant.numeric.integer.decimal +// ^ - meta.parens.java + return foo<<32; +// ^^^^^^ keyword.control.flow.return.java +// ^^ keyword.operator.bitshift.java +// ^^ constant.numeric.integer.decimal +// ^ punctuation.terminator.java + } +// ^ meta.block.java punctuation.section.block.end.java + + int foo = true ? 1 : 2; +// ^^^^ constant.language.java +// ^ keyword.operator.ternary.java +// ^ constant.numeric.integer.decimal +// ^ keyword.operator.ternary.java +// ^ constant.numeric.integer.decimal +// ^ punctuation.terminator.java + + return foo<bar; +// ^^^^^^ keyword.control.flow.return.java + + if (a == false) { +// ^^ keyword.operator.comparison + + x = (e & 1) << c^2; +// ^ keyword.operator.bitwise +// ^^ keyword.operator.bitshift +// ^ keyword.operator.bitwise + + y = ~e >>> (c | 2); +// ^ keyword.operator.bitwise +// ^^^ keyword.operator.bitshift +// ^ keyword.operator.bitwise + + z &= x; z ^= x; z *= x; z /= x; +// ^^ keyword.operator.assignment +// ^^ keyword.operator.assignment +// ^^ keyword.operator.assignment +// ^^ keyword.operator.assignment + + } + + boolean inst = a instanceof Object; +// ^^^^^^^^^^ keyword.operator.word.instanceof + } +//^ meta.method.java meta.method.body.java punctuation.section.block.end.java + + int numbers() { + + a = 0x1. +// ^^^^ constant.numeric.float.hexadecimal +// ^^ punctuation.definition.numeric.hexadecimal +// ^ punctuation.separator.decimal + + a = 0x.1a2f +// ^^^^^^^ constant.numeric.float.hexadecimal +// ^^ punctuation.definition.numeric.hexadecimal +// ^ punctuation.separator.decimal +// ^ - punctuation + + a = 0x1.a2f +// ^^^^^^^ constant.numeric.float.hexadecimal +// ^^ punctuation.definition.numeric.hexadecimal +// ^ punctuation.separator.decimal +// ^ - punctuation + + a = 0x1ffp+1023 +// ^^^^^^^^^^^ constant.numeric.float.hexadecimal +// ^^ punctuation.definition.numeric.hexadecimal + + a = 0xd.aP-1074 0x_1_f_._a_d_P-_10_74_ +// ^^^^^^^^^^^ constant.numeric.float.hexadecimal +// ^^ punctuation.definition.numeric.hexadecimal +// ^ punctuation.separator.decimal +// ^^^^^^^^^^^^^^^^^^^^^^ constant.numeric.float.hexadecimal +// ^^ punctuation.definition.numeric.hexadecimal +// ^ invalid.illegal.numeric +// ^ - invalid +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^ - invalid +// ^ invalid.illegal.numeric +// ^ invalid.illegal.numeric +// ^ - invalid +// ^ invalid.illegal.numeric + +// decimal floats + + a = 0D + 12345D + 12345D + 12_34_5_D - _12_34_5D - 12a45D; +// ^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^^ - constant.numeric +// ^^^^^^ - constant.numeric + + a = 0F + 12345F + 12345F + 12_34_5_F - _12_34_5F - 12a45F; +// ^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^^ - constant.numeric +// ^^^^^^ - constant.numeric + + a = 1. + 1_. + 1_2. - _1.; +// ^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^ - constant.numeric + + a = 1.D + 1_.D + 1_2.D - _1.D; +// ^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^ - constant.numeric + + a = 1.2 + 1_.2_ + 1_2.3_4 + 1_2_._3_4_ - _1.5; +// ^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^^ - constant.numeric +// ^ punctuation.separator.decimal +// ^^ constant.numeric.float.decimal + + a = 1.2d + 1_.2_d + 1_2.3_4d + 1_2_._3_4_d - _1.5d; +// ^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^ invalid.illegal.numeric +// ^^ - constant.numeric +// ^ punctuation.separator.decimal +// ^^^ constant.numeric.float.decimal +// ^ storage.type.numeric + + a = 12e34 + 12e+3_ + 1_2e3_4 + 1_2_e3_4_ + 1_2_e_3_4 + 12e+34 + 12e-34 + 12e+3_4 - _12e34; +// ^^^^^ constant.numeric.float.decimal +// ^^^^^^ constant.numeric.float.decimal +// ^^^^^^^ constant.numeric.float.decimal +// ^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ invalid.illegal.numeric +// ^^^^^^ constant.numeric.float.decimal +// ^^^^^^ constant.numeric.float.decimal +// ^^^^^^^ constant.numeric.float.decimal +// ^^^^^^ - constant.numeric + + a = 12e34f + 12e+3_f + 1_2e3_4f + 1_2_e3_4_f + 1_2_e_3_4f + 12e+34f + 12e-34f + 12e+3_4f - _12e34f; +// ^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^^ - constant.numeric + + a = 12.e34 + 12.e+3_ + 1_2.e3_4 + 1_2_.e3_4_ + 1_2_.e_3_4 + 12.e+34 + 12.e-34 + 12.e+3_4 - _12.e34; +// ^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^ - constant.numeric + + a = 12.e34f + 12.e+3_f + 1_2.e3_4f + 1_2_.e3_4_f + 1_2_.e_3_4f + 12.e+34f + 12.e-34f + 12.e+3_4f - _12.e34f; +// ^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^^^^ - constant.numeric + + a = 12.34e56 + 12_.34_e+5_ + 1_2.3_4e5_6 + 1_2_.3_4_e5_6_ + 1_2_._3_4e_5_6 + 12.34e+56 + 12.34e-56 + 12.34e+5_6 - _12.34e+5_6; +// ^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^^^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^^^^^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^ - constant.numeric + + a = 12.34e56f + 12_.34_e+5_f + 1_2.3_4e5_6f + 1_2_.3_4_e5_6_f + 1_2_._3_4e_5_6f + 12.34e+56f + 12.34e-56f + 12.34e+5_6f - _12.34e+5_6f; +// ^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^^^^^^^^ constant.numeric.float.decimal +// ^ invalid.illegal.numeric +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ storage.type.numeric +// ^^^ - constant.numeric + + a = .2 + .2_ + .3_4 + ._3_4_; +// ^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric + + a = .2d + .2_d + .3_4d + ._3_4_d; +// ^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^ invalid.illegal.numeric + + a = .34e56 + .34_e+5_ + .3_4e5_6 + .3_4_e5_6_ + ._3_4e_5_6 + .34e+56 + .34e-56 + .34e+5_6; +// ^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^ invalid.illegal.numeric +// ^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal +// ^^^^^^^^ constant.numeric.float.decimal +// ^ punctuation.separator.decimal + + a = 23.45 + 23.45F + 23.45d; +// ^^^^^ constant.numeric.float.decimal +// ^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric + + a = .01 + .02e3+.02e3F; +// ^^^ constant.numeric.float.decimal +// ^ keyword.operator +// ^^^^^ constant.numeric.float.decimal +// ^ keyword.operator +// ^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric + + a = 23.45e67+23.45e+6F+23.45e-67D; +// ^^^^^^^^ constant.numeric.float.decimal +// ^ keyword.operator +// ^^^^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric +// ^ keyword.operator +// ^^^^^^^^^^ constant.numeric.float.decimal +// ^ storage.type.numeric + +// binary integers + + a = 0b101101 + 0b10_11_01 + 0b10_11_01_ + 0b_101101 - 0_b10_1101 - 0b; +// ^^ punctuation.definition.numeric.binary +// ^^^^^^^^ constant.numeric.integer.binary +// ^^ punctuation.definition.numeric.binary +// ^^^^^^^^^^ constant.numeric.integer.binary +// ^^ punctuation.definition.numeric.binary +// ^^^^^^^^^^^ constant.numeric.integer.binary +// ^ invalid.illegal.numeric +// ^^ punctuation.definition.numeric.binary +// ^^^^^^^^^ constant.numeric.integer.binary +// ^ invalid.illegal.numeric +// ^^^^^^^^^^ - constant.numeric +// ^^ - constant.numeric + + a = 0b101101l + 0b10_11_01l + 0b10_11_01_l + 0b_101101l - 0_b10_1101l; +// ^^ punctuation.definition.numeric.binary +// ^^^^^^^^^ constant.numeric.integer.binary +// ^ storage.type.numeric +// ^^ punctuation.definition.numeric.binary +// ^^^^^^^^^^^ constant.numeric.integer.binary +// ^ storage.type.numeric +// ^^ punctuation.definition.numeric.binary +// ^^^^^^^^^^^^ constant.numeric.integer.binary +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^ punctuation.definition.numeric.binary +// ^^^^^^^^^^ constant.numeric.integer.binary +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^^^^ - constant.numeric + +// hexadecimal integers + + a = 0xABCD + 0xAB_CD + 0xAB_CD_ + 0x_AB_CD - 0_xAB_CD - 0x; +// ^^ punctuation.definition.numeric.hexadecimal +// ^^^^^^ constant.numeric.integer.hexadecimal +// ^^ punctuation.definition.numeric.hexadecimal +// ^^^^^^ constant.numeric.integer.hexadecimal +// ^^ punctuation.definition.numeric.hexadecimal +// ^^^^^^^^ constant.numeric.integer.hexadecimal +// ^ invalid.illegal.numeric +// ^^ punctuation.definition.numeric.hexadecimal +// ^^^^^^^^ constant.numeric.integer.hexadecimal +// ^ invalid.illegal.numeric +// ^^^^^^^^ - constant.numeric +// ^^ - constant.numeric + + a = 0xABCDl + 0xAB_CDl + 0xAB_CD_l + 0x_AB_CDl - 0_xAB_CDl; +// ^^ punctuation.definition.numeric.hexadecimal +// ^^^^^^^ constant.numeric.integer.hexadecimal +// ^ storage.type.numeric +// ^^ punctuation.definition.numeric.hexadecimal +// ^^^^^^^^ constant.numeric.integer.hexadecimal +// ^ storage.type.numeric +// ^^ punctuation.definition.numeric.hexadecimal +// ^^^^^^^^^ constant.numeric.integer.hexadecimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^ punctuation.definition.numeric.hexadecimal +// ^^^^^^^^^ constant.numeric.integer.hexadecimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^^ - constant.numeric + +// octal integers + + a = 07 + 0_ + 0_7 + 07_ + 079 + 079_ + 0_79_ - 0a - 0_a; +// ^^ constant.numeric.integer.octal +// ^ punctuation.definition.numeric.octal +// ^ punctuation.definition.numeric.octal +// ^^ constant.numeric.integer.octal +// ^ invalid.illegal.numeric +// ^ punctuation.definition.numeric.octal +// ^^^ constant.numeric.integer.octal +// ^ punctuation.definition.numeric.octal +// ^^^ constant.numeric.integer.octal +// ^ invalid.illegal.numeric +// ^ punctuation.definition.numeric.octal +// ^^^ constant.numeric.integer.octal +// ^^ invalid.illegal.numeric +// ^ punctuation.definition.numeric.octal +// ^^^^ constant.numeric.integer.octal +// ^^^ invalid.illegal.numeric +// ^ punctuation.definition.numeric.octal +// ^^^^^ constant.numeric.integer.octal +// ^^^^ invalid.illegal.numeric +// ^^ - constant.numeric +// ^^^ - constant.numeric + + a = 07l + 0_l + 0_7l + 07_l + 0792l + 079_2_l - 0al - 0_a_l; +// ^ punctuation.definition.numeric.octal +// ^^^ constant.numeric.integer.octal +// ^ storage.type.numeric +// ^ punctuation.definition.numeric.octal +// ^^^ constant.numeric.integer.octal +// ^ invalid.illegal.numeric +// ^ punctuation.definition.numeric.octal +// ^^^^ constant.numeric.integer.octal +// ^ punctuation.definition.numeric.octal +// ^^^^ constant.numeric.integer.octal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^ constant.numeric.integer.octal +// ^ punctuation.definition.numeric.octal +// ^^^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^ punctuation.definition.numeric.octal +// ^^^^^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^ - constant.numeric +// ^^^^^ - constant.numeric + +// decimal integers + + a = 0 + 0L; +// ^ constant.numeric.integer.decimal +// ^^ constant.numeric.integer.decimal +// ^ storage.type.numeric + + a = 12345 + 12_34_5 + 1_____5 + 12_34_5_ - _12_34_5 - 12a45; +// ^^^^^ constant.numeric.integer.decimal +// ^^^^^^^ constant.numeric.integer.decimal +// ^^^^^^^ constant.numeric.integer.decimal +// ^^^^^^^^ constant.numeric.integer.decimal +// ^ invalid.illegal.numeric +// ^^^^^^^^ - constant.numeric +// ^^^^^ - constant.numeric + + a = 12345l + 12345L + 12_34_5_L - _12_34_5L - 12a45L; +// ^^^^^^ constant.numeric.integer.decimal +// ^ storage.type.numeric +// ^^^^^^ constant.numeric.integer.decimal +// ^ storage.type.numeric +// ^^^^^^^^^ constant.numeric.integer.decimal +// ^ invalid.illegal.numeric +// ^ storage.type.numeric +// ^^^^^^^^^ - constant.numeric +// ^^^^^^ - constant.numeric + + a = 123_-_456; +// ^^^^ constant.numeric.integer.decimal +// ^ invalid.illegal.numeric +// ^ keyword.operator +// ^^^^ - constant.numeric + } + + String stringAndChars() { + String doubleQuotes = "String with double quotes"; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double +// ^ punctuation.definition.string.begin +// ^ punctuation.definition.string.end + + char singleQuotes = 'x'; +// ^^^ string.quoted.single +// ^ punctuation.definition.string.begin +// ^ punctuation.definition.string.end + + String escapes = "Here \2 are \n some \t escaped \'\\' characters \""; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double +// ^^ constant.character.escape +// ^^ constant.character.escape +// ^^^^ constant.character.escape +// ^^ constant.character.escape + + char escape = '\t' + '\1' + '\'' + '\\'; +// ^^^^ string.quoted.single +// ^^ constant.character.escape +// ^^^^ string.quoted.single +// ^^ constant.character.escape +// ^^^^ string.quoted.single +// ^^ constant.character.escape +// ^^^^ string.quoted.single +// ^^ constant.character.escape + + String text = "String without closing quote +// ^ invalid.illegal.newline + System.out.println(text); +// ^^^^^^ support.class + + char letter = 'z +// ^ invalid.illegal.newline + System.out.println(letter); +// ^^^^^^ support.class + } + + void varType() { + var x = "String"; +// ^^^ storage.type.var.java + + try (var in = new BufferedReader()) { +// ^^^ storage.type.var.java + var line = in.readLine(); +// ^^^ storage.type.var.java + } + } + + @Test +//^ punctuation.definition.annotation.java + public void someMethod(WithParam foo) throws Exception { +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.java +// ^^^^^^^^^^ meta.method.identifier.java entity.name.function.java +// ^ support.class.java +// ^ variable.parameter.java +// ^^^^^^^^^^^^^^^^ meta.method.throws.java +// ^^^^^^ keyword.declaration.throws.java +// ^^^^^^^^^ support.class.java +// ^ meta.method.java meta.method.body.java punctuation.section.block.begin.java + Object otherFoo = methodInvocation(foo); +// ^ support.class.java +// ^ keyword.operator.assignment.java +// ^ meta.function-call.java variable.function.java +// ^ punctuation.terminator.java + OtherObject bob = new OtherObject(foo); +// ^ keyword.other.storage.new.java +// ^ support.class.java + this.foo = new SubClass[0]; +// ^ keyword.other.storage.new.java +// ^ support.class.java +// ^^^ meta.brackets + + OuterClass.InnerClass foo = new OuterClass.InnerClass(); +// ^^^^^^^^^^ support.class.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^^ support.class.java + + String[][] doubleStringArray; +// ^^^^^^ support.class.java +// ^^^^ storage.modifier.array.java + + String[] stringArray = new String[] {"foo", "bar"}; +// ^^^^^^ support.class.java +// ^^ storage.modifier.array.java +// ^ keyword.operator.assignment.java +// ^^^ keyword.other.storage.new.java +// ^^^^^^ support.class.java +// ^ punctuation.section.brackets.begin.java +// ^ punctuation.section.brackets.end.java +// ^^^^^^^^^^^^^^ meta.braces.array-initialization.java +// ^ punctuation.section.braces.begin.java +// ^^^^^ string.quoted.double.java +// ^ punctuation.separator.comma.java +// ^^^^^ string.quoted.double.java +// ^ punctuation.section.braces.end.java +// ^ punctuation.terminator.java + + int[] data = new int[]{0, 0, 0}; +// ^^^ storage.type.primitive.java +// ^^ storage.modifier.array.java +// ^^^ keyword.other.storage.new.java +// ^^^ storage.type.primitive.java +// ^ punctuation.section.brackets.begin.java +// ^ punctuation.section.brackets.end.java +// ^ punctuation.section.braces.begin.java +// ^ constant.numeric.integer.decimal +// ^ punctuation.separator.comma.java +// ^ constant.numeric.integer.decimal +// ^ punctuation.separator.comma.java +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.braces.end.java + + byte [] foo; +// ^^^^ storage.type.primitive.java +// ^^ storage.modifier.array.java + byte []b=new byte[size]; +// ^^^^ storage.type.primitive.java +// ^^ storage.modifier.array.java +// ^ keyword.operator.assignment.java +// ^^^ keyword.other.storage.new.java +// ^^^^ storage.type.primitive.java + + int[][][] threeDimArr = new int[][][] { +// ^^^ storage.type.primitive.java +// ^^^^^^ storage.modifier.array.java +// ^^^ storage.type.primitive.java +// ^ punctuation.section.brackets.begin.java +// ^ punctuation.section.brackets.end.java +// ^ punctuation.section.brackets.begin.java +// ^ punctuation.section.brackets.end.java +// ^ punctuation.section.brackets.begin.java +// ^ punctuation.section.brackets.end.java +// ^ punctuation.section.braces.begin.java + { { 1, 2 }, { 3, 4 } }, +// ^ constant.numeric.integer.decimal +// ^ punctuation.separator.comma.java +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.braces.begin.java +// ^ punctuation.section.braces.end.java +// ^ punctuation.separator.comma.java + { { 5, 6 }, { 7, 8 } } +// ^ constant.numeric.integer.decimal +// ^ punctuation.separator.comma.java +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.braces.begin.java +// ^ punctuation.section.braces.end.java + }; +// ^ punctuation.section.braces.end.java + + threeDimArr = new int[1][3][4]; +// ^^^ storage.type.primitive.java +// ^^^^^^^^^ meta.brackets.array-initialization.java +// ^ punctuation.section.brackets.begin.java +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.brackets.end.java +// ^ punctuation.section.brackets.begin.java +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.brackets.end.java +// ^ punctuation.section.brackets.begin.java +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.brackets.end.java + + bob = new some.path.to.MyObject[3]; +// ^^^^^^^^^^^^^^^^^^^^^ meta.path.java +// ^^^^^^^^ support.class.java +// ^^^ meta.brackets.array-initialization.java +// ^ punctuation.section.brackets.begin.java +// ^ constant.numeric.integer.decimal +// ^ punctuation.section.brackets.end.java + + foo.forEach((k, v) -> { +// ^ storage.type.function.anonymous.java +// ^ punctuation.section.block.begin + + return; +// ^^^^^^ keyword.control.flow.return.java +// ^ punctuation.terminator + }); +// ^ punctuation.section.block.end.java +// ^ punctuation.terminator + this.foo = new SubClass(new SubClass[0], true); +// ^ keyword.other.storage.new.java +// ^ support.class.java +// ^^^ meta.brackets +// ^ constant.language.java +/* We can't support this yet.*/ + some.other.path. +/* ^^^^^^^^^^^^^^^^ support.class.java */ + foo.MyClass.staticMethod(true); +/* ^^^^^^^^^^^ support.class.java */ + + some.other.path +/* ^^^^^^^^^^^^^^^ support.class.java */ + .foo.MyClass.staticMethod(true); +/* ^^^^^^^^^^^^ support.class.java */ + + @MyAnnotation +// ^ punctuation.definition.annotation.java +// ^^^^^^^^^^^^^ meta.annotation.java + int foo; + } +//^ meta.method.java meta.method.body.java punctuation.section.block.end.java + + void arrayMethod(byte [] [] a, int b, byte[] c) {} +//^^^^ storage.type.void.java +// ^^^^^^^^^^^ entity.name.function.java +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.parameters.java +// ^ - meta.method.parameters.java +// ^^^^ storage.type.primitive.java +// ^^ storage.modifier.array.java +// ^^ storage.modifier.array.java +// ^ variable.parameter.java +// ^^^ storage.type.primitive.java +// ^ variable.parameter.java +// ^^^^ storage.type.primitive.java +// ^^ storage.modifier.array.java +// ^ variable.parameter.java + + int[] arrayMethod2(int a[], String b[]) {} +//^^^ storage.type.primitive.java +// ^^ storage.modifier.array.java +// ^^^ storage.type.primitive.java +// ^ variable.parameter.java +// ^^ storage.modifier.array.java +// ^^^^^^ support.class.java +// ^ variable.parameter.java +// ^^ storage.modifier.array.java + + void arrayOfGenericMethod(Map<Long, Date>[] mapping) {} +// ^^ storage.modifier.array.java +// ^^^^^^^ variable.parameter.java + + void primitiveVarArgs(int... values) {} +// ^^^ storage.type.primitive.java +// ^^^ keyword.operator.variadic.java +// ^^^ variable.parameter.java + + public class Foo<T extends int> {} + // ^^^^^^^^^^^^^^^ meta.generic.declaration.java + // ^ variable.parameter.type.java + // ^^^^^^^ keyword.declaration.extends.java + // ^^^ - storage.type.primitive.java + + @RunWith(JUnit4.class) +//^ punctuation.definition.annotation.java +// ^^^^^^^^^^^^^^ meta.annotation.parameters.java +// ^ support.class.java +// ^ variable.language.java + public void someReallyReallyLongMethodNameThatMakesTheBraceOverflowToTheNextLine( +// ^ meta.method.java meta.method.identifier.java entity.name.function.java +// ^ punctuation.section.parens.begin + WITHSOMEPARAMS foo, +// ^ meta.method.java meta.method.parameters.java support.class.java +// ^ meta.method.java meta.method.parameters.java variable.parameter.java + Generic<Param> bar) +// ^ meta.method.java meta.method.parameters.java support.class.java +// ^^^^^^^ meta.generic.java +// ^ meta.method.java meta.method.parameters.java variable.parameter.java +// ^ punctuation.section.parens.end + throws Exception { +// ^ meta.method.java meta.method.throws.java keyword.declaration.throws.java +// ^ meta.method.java meta.method.throws.java support.class.java + return someMethod(new Function<V, V>() { +// ^ meta.class.body.anonymous.java punctuation.section.braces.begin.java + @Override + public V apply(V input) { +// ^ support.class.java +// ^^^^^^^^^ meta.method.parameters.java +// ^ support.class.java +// ^ variable.parameter.java +// ^ meta.method.body + return input; + } +// ^ meta.method.body + }, executor); +// ^ meta.class.body.anonymous.java punctuation.section.braces.end.java +// ^ meta.function-call.java punctuation.section.parens.end.java + } +//^ meta.method.body.java punctuation.section.block.end.java + + public static <T> T writeAll(Collection<? extends T>, Sink<T>) {} +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.java +// ^^^ meta.generic.declaration.java +// ^ variable.parameter.type.java +// ^ - meta.generic.java +// ^ support.class.java +// ^ support.class.java +// ^^^^^^^^^^^^^ meta.generic.java +// ^ punctuation.definition.generic.begin.java +// ^ keyword.operator.wildcard.java +// ^ keyword.declaration.extends.java +// ^ support.class.java +// ^ punctuation.definition.generic.end.java +// ^ punctuation.separator.comma.java - meta.generic.java +// ^^^ meta.generic.java + + public static <T extends Comparable<? super T>> +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.generic.declaration.java +// ^ variable.parameter.type.java +// ^^^^^^^^^^ support.class.java +// ^ punctuation.definition.generic.begin.java +// ^ keyword.operator.wildcard.java +// ^ keyword.declaration.super.java +// ^ support.class.java +// ^ punctuation.definition.generic.end.java +// ^ punctuation.definition.generic.end.java +// ^^^^^^^^^^^ meta.generic.java + T max(Collection<T> coll); +// ^ support.class.java + + <T> public static Set<T> unmodifiableSet(Set<T> set); +// ^^^ meta.generic.declaration.java +// ^ variable.parameter.type.java + + public void +// ^ storage.type.void.java + methodNameOnDifferentLine(); +// ^ meta.method.identifier.java entity.name.function.java + + void myAbstractMethod(With<GenericParam> foo); +// ^ meta.method.java meta.method.identifier.java entity.name.function.java + + private Long myOtherAbstractMethod(@WithAnnotation Blah blah); +// ^ meta.method.java meta.method.identifier.java entity.name.function.java +// ^ meta.method.java meta.method.parameters.java punctuation.definition.annotation.java + + public MyGeneric<Param, With, Multiple, Types> otherAbstractMethod(Foo<With, Another> bar); +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.generic.java +// ^ - meta.generic.java +// ^ support.class.java +// ^ support.class.java +// ^ support.class.java +// ^ support.class.java +// ^ support.class.java +// ^ meta.method.java meta.method.identifier.java entity.name.function.java + + public static <T extends AutoCloseable> void myGenericMethod(SomeType<T> root) +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.generic.declaration.java +// ^ punctuation.definition.generic.begin.java +// ^ variable.parameter.type.java +// ^ keyword.declaration.extends.java +// ^ support.class.java +// ^ storage.type.void.java +// ^entity.name.function.java + + throws Exception, IOException, SAXException { +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method.throws +// ^ - meta.method.throws + } +}} +// <- meta.class.java meta.class.body.java punctuation.section.block.end.java + //<- invalid.illegal.stray-brace-end + +public +// <- storage.modifier.java +class IOException { } +// <- storage.type.java + +public class Generic<T> implements fully.qualified.Other<T> { +// ^^^^^^^^^^^^^^^^^^^^^ meta.path.java +// ^^^^^ entity.other.inherited-class.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^^ entity.other.inherited-class.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^ entity.other.inherited-class.java +// ^^^ meta.generic.java +// ^ punctuation.definition.generic.begin.java +// ^ support.class.java +// ^ punctuation.definition.generic.end.java +} +// <- punctuation.section.block.end.java + +public class Generic<T> extends iNtf implements iNterface<T> { +// ^^^^ entity.other.inherited-class.java +// ^^^^^^^^^ entity.other.inherited-class.java +// ^^^ meta.generic.java +// ^ punctuation.definition.generic.begin.java +// ^ support.class.java +// ^ punctuation.definition.generic.end.java +} +// <- punctuation.section.block.end.java + +public class Bar { + public void missingSemiColon() { + boolean foo = foo +// ^^^^ meta.assignment.rhs.java + } +//^ punctuation.section.block.end.java + + private SomeClass methodWithBadParens( + CombinedServerSpec vendorManagementServerSpec; +// ^ invalid.illegal.missing-parameter-end + + public void strayParans() { +// ^ punctuation.section.block.begin.java + foo.bar(hello(world); +// ^ invalid.illegal.stray-terminator-end + } +//^ punctuation.section.block.end.java + + public void strayParansInBlock() { +// ^ punctuation.section.block.begin.java + if (hello(world) { +// ^ invalid.illegal +// ^ - meta.parens.java +// ^ meta.block.java + return false; + } + } + + public void strayParansInForLoop() { +// ^ punctuation.section.block.begin.java + for (;; { +// ^ invalid.illegal +// ^ meta.block.java - meta.parens.java + } + } +//^ punctuation.section.block.end.java + + public void strayParansInConstructor() { +// ^ punctuation.section.block.begin.java + return new Foo(; +// ^ invalid.illegal + } +//^ punctuation.section.block.end.java + + private boolean missingSemiColonForStaticAssignment = true +// ^^^^ meta.assignment.rhs.java + + public void strayParansInConstructor() { +//^^^^^^ meta.class.body.java storage.modifier.java - meta.assignment.rhs.java +// ^ meta.method.identifier.java entity.name.function.java +// ^ punctuation.section.block.begin.java + return; + } + + private boolean missingSemiColonForStaticAssignmentPackageProtected = true +// ^^^^ meta.assignment.rhs.java + + void strayParansInConstructor() { +//^^^^ storage.type.void.java - meta.assignment.rhs.java +// ^ meta.method.identifier.java entity.name.function.java +// ^ punctuation.section.block.begin.java + return; + } +//^ punctuation.section.block.end.java +} +// <- punctuation.section.block.end.java + +class Javadoc { + + /** This is javadoc, not a simple comment */ +//^^^ punctuation.definition.comment.begin.javadoc +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation.javadoc +// ^^ punctuation.definition.comment.end.javadoc + + /** +//^^^ comment.block.documentation.javadoc punctuation.definition.comment.begin.javadoc + * Description of some sort. +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation.javadoc + */ +// ^^ comment.block.documentation.javadoc punctuation.definition.comment.end.javadoc + + /** + * <p>Description that starts with tag +// ^^^ text.html.javadoc meta.tag + */ + + /** <b>One-liner with tags</b> */ +// ^^^ text.html.javadoc meta.tag +// ^^^ text.html.javadoc meta.tag + + /** @param onFirstLine @param +// ^^^^^^ keyword.other.documentation.param.javadoc +// ^^^^^^ -keyword.other.documentation.param.javadoc + * @param normal @param +// ^^^^^^ -keyword.other.documentation.param.javadoc +// ^^^^^^ keyword.other.documentation.param.javadoc + * + @param withoutAsterisk @param +// ^^^^^^ -keyword.other.documentation.param.javadoc +// ^^^^^^ keyword.other.documentation.param.javadoc + */ + + /** + * Parameters + * + * @param paramName Some description +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block-tag.javadoc +// ^^^^^^^^^ variable.parameter.javadoc + * that spans <i>several</i> lines. +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block-tag.javadoc +// ^^^ meta.tag +// ^^^^ meta.tag +// ^ punctuation.definition.comment.javadoc + * + * @param + * paramName1 +// ^^^^^^^^^^ variable.parameter.javadoc + * Parameter description +// ^^^^^^^^^^^^^^^^^^^^^ meta.block-tag.javadoc + * + * @param + * paramName2 +// ^^^^^^^^^^ variable.parameter.javadoc + * + * @param + * @param + * paramName3 +// ^^^^^^^^^^ variable.parameter.javadoc + */ +// ^^ punctuation.definition.comment.end.javadoc + + /** Not a @param tag */ +// ^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation.javadoc +// ^^^^^^ -keyword.other.documentation.param.javadoc + + /** + * Code blocks + * + * {@code} {@literal} +// ^^^^^ keyword.other.documentation.code-or-literal.javadoc +// ^ punctuation.definition.keyword.javadoc +// ^^^^^^^^ keyword.other.documentation.code-or-literal.javadoc +// ^ punctuation.definition.keyword.javadoc + + * {@code List<T> lst = new ArrayList<>()} +// ^ punctuation.section.inline-tag.begin.javadoc +// ^^^^^ keyword.other.documentation.code-or-literal.javadoc +// ^ -markup.raw.javadoc +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.raw.javadoc -meta.tag +// ^ punctuation.section.inline-tag.end.javadoc + + * Multiline, line break in content: {@code x + y +// ^^^^^ markup.raw.javadoc +// ^ -markup.raw.javadoc + * = z} +//^^^ -markup.raw.javadoc +// ^^^ markup.raw.javadoc + + * Multiline, line break before content: {@literal +// ^ -markup.raw.javadoc + * x + y = z} +//^^^ -markup.raw.javadoc +// ^^^^^^^^^ markup.raw.javadoc + + * Bracket balancing: {@code int[][] a = {{1, 2, 3}, {4, 5}}} +// ^ punctuation.section.inline-tag.begin.javadoc +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.raw.javadoc +// ^ punctuation.section.inline-tag.end.javadoc + + * Bracket balancing with line break: {@code int[][] a = { +// ^ punctuation.section.inline-tag.begin.javadoc +// ^^^^^^^^^^^^^ markup.raw.javadoc +// ^ -markup.raw.javadoc + * {1, 2, 3}, {4, 5}}} +//^^^ -markup.raw.javadoc +// ^^^^^^^^^^^^^^^^^^ markup.raw.javadoc +// ^ punctuation.section.inline-tag.end.javadoc + */ + + /** + * Inline tags with references + + * {@link} {@linkplain} +// ^^^^^ keyword.other.documentation.link.javadoc +// ^^^^^^^^^^ keyword.other.documentation.link.javadoc + + * {@link Class} {@linkplain org.package.Class} {@link org.package.Class.NestedClass} +// ^^^^^ keyword.other.documentation.link.javadoc +// ^^^^^ markup.underline.link.javadoc +// ^^^^^^^^^ keyword.other.documentation.link.javadoc +// ^^^^^^^^^^^^^^^^^ markup.underline.link.javadoc +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.underline.link.javadoc + + * Method separator: + * {@link package.Class#method} {@linkplain #method} +// ^^^^^^^^^^^^^^^^^^^^ markup.underline.link.javadoc +// ^^^^^^^ markup.underline.link.javadoc + + * Brackets: + * {@link Class#method(Type, Type)} {@link #method(Type, Type) label} +// ^^^^^^^^^^^^^^^^^^^^^^^^ markup.underline.link.javadoc +// ^^^^^^^^^^^^^^^^^^^ markup.underline.link.javadoc +// ^^^^^ meta.label.javadoc -markup.underline.link.javadoc + + * Line breaks: + * {@link Class#method(Type, + * Type, Type) label} +// ^^^^^^^^^^^ markup.underline.link.javadoc +// ^^^^^ meta.label.javadoc +//^^^ -markup.underline.link.javadoc + * {@link + * Class#method(Type, Type, Type) label} +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.underline.link.javadoc +// ^^^^^ meta.label.javadoc + * {@link Class#method(Type, Type, Type) + * label} +// ^^^^^ meta.label.javadoc + * + * Tags in label: + * {@link Class#method(Type, Type, Type) <i>label</i>} +// ^^^^^^^^^^^^ meta.label.javadoc +// ^^^ meta.tag +// ^^^^ meta.tag + * + * {@value} {@value #SOME_CONSTANT} {@value package.Class#SOME_CONSTANT} +// ^^^^^^ keyword.other.documentation.value.javadoc +// ^^^^^^^^^^^ markup.underline.link.javadoc +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.underline.link.javadoc + */ + + /** + * Block tags with reference + * + * @see Class#method(Type, Type) +// ^^^^ keyword.other.documentation.see.javadoc +// ^^^^^^^^^^^^^^^^^^^^^^^^ markup.underline.link.javadoc + * + * @see <a>java.util.stream</a> +// ^^^^ keyword.other.documentation.see.javadoc +// ^^^^^^^^^^^^^^^^^^^^^^^ -markup.underline.link.javadoc +// ^^^ meta.tag +// ^^^ meta.tag + * + * @see 'java.util.stream' +// ^^^^ keyword.other.documentation.see.javadoc +// ^^^^^^^^^^^^^^^^^^ -markup.underline.link.javadoc + * + * @throws IOException +// ^^^^^^^ keyword.other.documentation.throws.javadoc +// ^^^^^^^^^^^ markup.underline.link.javadoc + + * @throws IOException because IOException +// ^^^^^^^ keyword.other.documentation.throws.javadoc +// ^^^^^^^^^^^ markup.underline.link.javadoc +// ^^^^^^^^^^^^^^^^^^^ - markup.underline.link.javadoc + */ + + /** + * Leading asterisk with space +// ^ punctuation.definition.comment.javadoc + *Without space +// ^ punctuation.definition.comment.javadoc + *<p>Before tag +// ^ punctuation.definition.comment.javadoc + *{@value} Before inline tag +// ^ punctuation.definition.comment.javadoc + *@return Before block tag +// ^ punctuation.definition.comment.javadoc + */ + + /** + * Unclosed html tag: <li + */ +// ^^ comment.block.documentation.javadoc punctuation.definition.comment.end.javadoc + + /** + * Unclosed javadoc tag: {@link + */ +// ^^ comment.block.documentation.javadoc punctuation.definition.comment.end.javadoc +} + +module java.base { +//^^^^^^^^^^^^^^^^ meta.module.java +//^^^^^^^^^^^^^^ meta.module.identifier.java +// ^ -meta.module.identifier.java +//^^^^ storage.type.java +// ^^^^^^^^^ entity.name.module.java +// ^ meta.module.body.java punctuation.section.braces.begin.java + + exports java.io; +//^^^^^^^^^^^^^^^^ meta.module.java meta.module.body.java +//^^^^^^^^^^^^^^^ meta.exports.java +//^^^^^^ keyword.other.module.exports.java +// ^^^^^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^ punctuation.terminator.java + + exports jdk.internal.jmod to jdk.compiler, jdk.jlink; +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.exports.java +// ^^ keyword.other.module.to.java +// ^^^^^^^^^^^^ support.type.module.java +// ^ punctuation.separator.comma.java +// ^^^^^^^^^ support.type.module.java +// ^ punctuation.terminator.java + + opens java.io; +//^^^^^^^^^^^^^ meta.opens.java +//^^^^^ keyword.other.module.opens.java +// ^^^^^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^ punctuation.terminator.java + + opens jdk.internal.jmod to jdk.compiler, jdk.jlink; +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.opens.java +// ^^ keyword.other.module.to.java +// ^^^^^^^^^^^^ support.type.module.java +// ^ punctuation.separator.comma.java +// ^^^^^^^^^ support.type.module.java +// ^ punctuation.terminator.java + + opens // incomplete to check if it affects the next statement + + uses java.security.Provider; +//^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.uses.java +//^^^^ keyword.other.module.uses.java +// ^^^^^^^^^^^^^^^^^^^^^^ meta.path.java +// ^^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^ support.type.package.java +// ^ punctuation.accessor.dot.java +// ^^^^^^^^ support.class.java +// ^ punctuation.terminator.java + + provides java.nio.file.spi.FileSystemProvider with jdk.internal.jrtfs.JrtFileSystemProvider; +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.provides.java +//^^^^^^^^ keyword.other.module.provides.java +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.path.java +// ^^^^ keyword.other.module.with.java +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.path.java +// ^ punctuation.terminator.java + + provides incomplete.but.should.not.break.next.Statement; +// ^ punctuation.terminator.java + + provides sun.jvmstat.monitor.MonitoredHostService with + sun.jvmstat.perfdata.monitor.protocol.file.MonitoredHostFileService, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.provides.java meta.path.java +// ^ punctuation.separator.comma.java + sun.jvmstat.perfdata.monitor.protocol.local.MonitoredHostLocalService; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.provides.java meta.path.java + + requires java.xml; +//^^^^^^^^^^^^^^^^^ meta.requires.java +//^^^^^^^^ keyword.other.module.requires.java +// ^^^^^^^^ support.type.module.java +// ^ punctuation.terminator.java + + requires transitive javafx.base; +//^^^^^^^^ keyword.other.module.requires.java +// ^^^^^^^^^^ keyword.other.module.transitive.java +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.requires.java +// ^^^^^^^^^^^ support.type.module.java +// ^ punctuation.terminator.java + +} +//<- meta.module.body.java punctuation.section.braces.end.java + +open module open.module {} +//^^^^^^^^^^^^^^^^^^^^^^^^ meta.module.java +//^^^ -meta.module.identifier.java +//^^ storage.modifier.java +// ^^^^^^ storage.type.java +// ^^^^^^^^^^^^^^^^^^ meta.module.identifier.java +// ^^ meta.module.body.java diff --git a/syntaxes/Java/syntax_test_java_properties.properties b/syntaxes/Java/syntax_test_java_properties.properties @@ -0,0 +1,109 @@ +# SYNTAX TEST "Packages/Java/JavaProperties.sublime-syntax" + +# Comment line 1 +# <- comment.line.java-props punctuation.definition.comment.java-props +#^^^^^^^^^^^^^^^ comment.line.java-props + + # Comment line 2 +# ^ comment.line.java-props punctuation.definition.comment.java-props +# ^^^^^^^^^^^^^^^^ comment.line.java-props + +! Comment line 3 +# <- comment.line.java-props punctuation.definition.comment.java-props +#^^^^^^^^^^^^^^^ comment.line.java-props + + ! Comment line 4 +# ^ comment.line.java-props punctuation.definition.comment.java-props +# ^^^^^^^^^^^^^^^^ comment.line.java-props + +property_name=Value of Property +#^^^^^^^^^^^^ entity.name.key.java-props +# ^ punctuation.separator.java-props +# ^^^^^^^^^^^^^^^^^ string.unquoted.java-props + +property_name = Value of Property +#^^^^^^^^^^^^ entity.name.key.java-props +# ^ -entity.name.key.java-props +# ^ punctuation.separator.java-props +# ^ -entity.name.key.java-props +# ^^^^^^^^^^^^^^^^^ string.unquoted.java-props + +property_name:Value of Property +#^^^^^^^^^^^^ entity.name.key.java-props +# ^ punctuation.separator.java-props +# ^^^^^^^^^^^^^^^^^ string.unquoted.java-props + +property_name : Value of Property +#^^^^^^^^^^^^ entity.name.key.java-props +# ^^^^^ -entity.name.key.java-props +# ^ punctuation.separator.java-props +# ^^^^^ -entity.name.key.java-props +# ^^^^^^^^^^^^^^^^^ string.unquoted.java-props + +property_name Value of Property +#^^^^^^^^^^^^ entity.name.key.java-props +# ^ -entity.name.key.java-props -string.unquoted.java-props +# ^^^^^^^^^^^^^^^^^ string.unquoted.java-props + + +name= +#^^^ entity.name.key.java-props +# ^ punctuation.separator.java-props +value +#^^^^ entity.name.key.java-props -string.unquoted.java-props + +=value +# <- punctuation.separator.java-props +#^^^^^ string.unquoted.java-props + +:value +# <- punctuation.separator.java-props +#^^^^^ string.unquoted.java-props + +name===value +# ^ punctuation.separator.java-props +# ^^ -punctuation.separator.java-props string.unquoted.java-props + +name\ with\=escap\es\:=Value \ with \nescap\es +#^^^^^^^^^^^^^^^^^^^^^ entity.name.key.java-props +# ^^ constant.character.escape.java-props +# ^^ constant.character.escape.java-props +# ^^ constant.character.escape.java-props +# ^^ constant.character.escape.java-props +# ^ punctuation.separator.java-props +# ^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.java-props +# ^^ constant.character.escape.java-props +# ^^ constant.character.escape.java-props +# ^^ constant.character.escape.java-props + + +unicode_\u263A = \u263B unicode \u263c +#^^^^^^^^^^^^^ entity.name.key.java-props +# ^^^^^^ constant.character.escape.unicode.java-props +# ^^^^^^^^^^^^^^^^^^^^^ string.unquoted.java-props +# ^^^^^^ constant.character.escape.unicode.java-props +# ^^^^^^ constant.character.escape.unicode.java-props + +name = First Line \ +# ^^^^^^^^^^^^ string.unquoted.java-props +# ^ punctuation.separator.continuation.java-props + +name = First Line \ + Second Line \ + Third Line +# ^^^^^^^^^^ string.unquoted.java-props + +name=value +#^^^ -string.unquoted.java-props + +name = \ +value +#^^^^ string.unquoted.java-props + +name = \ +# Not a comment +#^^^^^^^^^^^^^^ string.unquoted.java-props + +property_\ +name = value +#^^^ entity.name.key.java-props diff --git a/syntaxes/Java/syntax_test_jsp.jsp b/syntaxes/Java/syntax_test_jsp.jsp @@ -0,0 +1,59 @@ +// SYNTAX TEST "Packages/Java/Java Server Pages (JSP).sublime-syntax" +// <- text.html.jsp - source.java.embedded.html +<!DOCTYPE html> +<html> +<head> + <title></title> +// ^^^^^^^^^^^^^^^ meta.tag +</head> +<body> + <%@ include file="foo.bar" %> +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.directive +// ^^^ punctuation.section.directive +// ^^ punctuation.section.directive + + Plain text +// ^^^^^^^^^^ text.html.jsp - meta + + <%-- This is a comment --%> +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.jsp + <% +// ^^ punctuation.section.embedded.begin.jsp - source.java.embedded.html +// ^ source.java.embedded.html + if (!foo && !bar) { +// ^^ keyword.control.conditional.if.java +// ^ keyword.operator.logical.java +// ^^ keyword.operator.logical.java + %><div style="width: 90%"></div><% +// ^^ punctuation.section.embedded.end.jsp - source.java.embedded.html +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag +// ^^ punctuation.section.embedded.begin.jsp - source.java.embedded.html + if (foot.shouldBe()) { +// ^^ keyword.control.conditional.if.java + boolean test = false; +// ^^^^^^^ storage.type +// ^^^^^ constant + %> +// ^^ punctuation.section.embedded.end.jsp - source.java.embedded.html +// ^ text.html.jsp - source.java.embedded.html + + <%-- This is a comment --%> +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.jsp + <% int aNumber = 0; // this scriptlet should close %> +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-slash.java +// ^^ punctuation.section.embedded.end.jsp + + + <div style="width: 90%"></div> +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag + <% +// ^^ punctuation.section.embedded.begin.jsp - source.java.embedded.html + } +// ^ - invalid.illegal.stray-brace-end + } +// ^ - invalid.illegal.stray-brace-end + %> +// ^^ punctuation.section.embedded.end.jsp - source.java.embedded.html +// ^ text.html.jsp - source.java.embedded.html +</body> +</html> diff --git a/syntaxes/Python/Completion Rules.tmPreferences b/syntaxes/Python/Completion Rules.tmPreferences @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>scope</key> + <string>source.python</string> + <key>settings</key> + <dict> + <key>cancelCompletion</key> + <string>^(.*\b(and|or)$)|(\s*(pass|return|and|or|(class|def|import)\s*[a-zA-Z_0-9]+)$)</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Python/Default.sublime-keymap b/syntaxes/Python/Default.sublime-keymap @@ -0,0 +1,25 @@ +[ + // Auto-pair quotes even after string modifiers. + // Copied over from the default bindings with modifications to `preceding_text` + // and an added selector condition. + { "keys": ["\""], "command": "insert_snippet", "args": {"contents": "\"$0\""}, "context": + [ + { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, + { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }, + { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |\\)|]|\\}|>|$)", "match_all": true }, + { "key": "preceding_text", "operator": "regex_contains", "operand": "(?i)\\b[bfru]+$", "match_all": true }, + { "key": "selector", "operator": "equal", "operand": "source.python" }, + { "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.double - punctuation.definition.string.end", "match_all": true } + ] + }, + { "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'$0'"}, "context": + [ + { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, + { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }, + { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |\\)|]|\\}|>|$)", "match_all": true }, + { "key": "preceding_text", "operator": "regex_contains", "operand": "(?i)\\b[bfru]+$", "match_all": true }, + { "key": "selector", "operator": "equal", "operand": "source.python" }, + { "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.single - punctuation.definition.string.end", "match_all": true } + ] + }, +] diff --git a/syntaxes/Python/Miscellaneous.tmPreferences b/syntaxes/Python/Miscellaneous.tmPreferences @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Miscellaneous</string> + <key>scope</key> + <string>source.python</string> + <key>settings</key> + <dict> + <key>decreaseIndentPattern</key> + <string>^\s*(elif|else|except|finally)\b.*:</string> + <key>increaseIndentPattern</key> + <string>^\s*(class|(\basync\s+)?(def|for|with)|elif|else|except|finally|if|try|while)\b.*:\s*$</string> + <key>disableIndentNextLinePattern</key> + <string></string> + <key>shellVariables</key> + <array> + <dict> + <key>name</key> + <string>TM_COMMENT_START</string> + <key>value</key> + <string># </string> + </dict> + <dict> + <key>name</key> + <string>TM_LINE_TERMINATOR</string> + <key>value</key> + <string>:</string> + </dict> + </array> + </dict> +</dict> +</plist> diff --git a/syntaxes/Python/Python.sublime-build b/syntaxes/Python/Python.sublime-build @@ -0,0 +1,15 @@ +{ + "shell_cmd": "python -u \"$file\"", + "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)", + "selector": "source.python", + + "env": {"PYTHONIOENCODING": "utf-8"}, + + "variants": + [ + { + "name": "Syntax Check", + "shell_cmd": "python -m py_compile \"${file}\"", + } + ] +} diff --git a/syntaxes/Python/Python.sublime-syntax b/syntaxes/Python/Python.sublime-syntax @@ -0,0 +1,2210 @@ +%YAML 1.2 +--- +name: Python +file_extensions: + - py + - py3 + - pyw + - pyi + - pyx + - pyx.in + - pxd + - pxd.in + - pxi + - pxi.in + - rpy + - cpy + - SConstruct + - Sconstruct + - sconstruct + - SConscript + - gyp + - gypi + - Snakefile + - vpy + - wscript + - bazel + - bzl +first_line_match: ^#!\s*/.*\bpython(\d(\.\d)?)?\b +scope: source.python + +variables: + # We support unicode here because Python 3 is the future + identifier_continue: '[[:alnum:]_]' + identifier: '\b[[:alpha:]_]{{identifier_continue}}*\b' + identifier_constant: '\b(?:[\p{Lu}_][\p{Lu}_\d]*)?[\p{Lu}]{2,}[\p{Lu}_\d]*\b' # require 2 consecutive upper-case letters + digits: (?:\d+(?:_\d+)*) + exponent: (?:[eE][-+]?{{digits}}) + path: '({{identifier}}[ ]*\.[ ]*)*{{identifier}}' + sql_indicator: \s*(?:SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER|WITH)\b + illegal_names: (?:and|as|assert|break|class|continue|def|del|elif|else|except|finally|for|from|global|if|import|in|is|lambda|not|or|pass|raise|return|try|while|with|yield) + format_spec: |- + (?x: + (?:.? [<>=^])? # fill align + [ +-]? # sign + \#? # alternate form + # technically, octal and hexadecimal integers are also supported as 'width', but rarely used + \d* # width + ,? # thousands separator + (?:\.\d+)? # precision + [bcdeEfFgGnosxX%]? # type + ) + strftime_spec: '(?:%(?:[aAwdbBGmyYHIpMSfzZjuUVWcxX%]|-[dmHIMSj]))' + # This can be used in look-aheads to parse simple expressions. + # Can't be recursive, because sregex doesn't support that, + # so we're skipping parentheses. + # Can't parse multiple lines as well, for obvious reasons + simple_expression: |- + (?x: + \s+ # whitespace + | [urfb]*"(?:\\.|[^"])*" # strings + | [urfb]*'(?:\\.|[^'])*' # ^ + | [\d.ej]+ # numerics + | [+*/%@-] | // | and | or # operators + | {{path}} # a path + )* + + +contexts: + main: + - include: statements + + statements: + - include: docstrings + - include: line-statements + - include: block-statements + - include: classes + - include: functions + - include: modifiers + - include: assignments + - match: ; + scope: punctuation.terminator.statement.python + - include: expression-as-a-statement + + line-statements: + - include: imports + - include: decorators + - match: \b(raise)\b + scope: keyword.control.flow.raise.python + push: + - meta_scope: meta.statement.raise.python + - include: line-continuation-or-pop + - match: \b(from)\b + scope: keyword.control.flow.raise.from.python + set: + - meta_scope: meta.statement.raise.python + - include: line-continuation-or-pop + - include: expression-in-a-statement + - include: expression-in-a-statement + - match: \b(assert)\b + scope: keyword.control.flow.assert.python + - match: \b(del)\b + scope: keyword.other.del.python + - match: \b(print)\b(?! *([,.()\]}])) + scope: keyword.other.print.python + - match: \b(exec)\b(?! *($|[,.()\]}])) + scope: keyword.other.exec.python + - match: \b(return)\b + scope: keyword.control.flow.return.python + - match: \b(break)\b + scope: keyword.control.flow.break.python + - match: \b(continue)\b + scope: keyword.control.flow.continue.python + - match: \b(pass)\b + scope: keyword.control.flow.pass.python + + imports: + - match: \b(import)\b + scope: keyword.control.import.python + push: + - meta_scope: meta.statement.import.python + - include: line-continuation-or-pop + - match: ',' + scope: punctuation.separator.import-list.python + - match: \. + scope: invalid.illegal.unexpected-relative-import.python + - include: import-alias + - include: qualified-name + - match: (?=\S) + pop: true + - match: \b(from)\b + scope: keyword.control.import.from.python + push: + - meta_scope: meta.statement.import.python + - meta_content_scope: meta.import-source.python + - include: line-continuation-or-pop + - match: \b(import)\b + scope: keyword.control.import.python + set: + - meta_scope: meta.statement.import.python + - include: line-continuation-or-pop + - match: ' *(\()' + captures: + 1: punctuation.section.import-list.begin.python + set: + - meta_scope: meta.statement.import.python + - include: comments + - match: \) + scope: punctuation.section.import-list.end.python + pop: true + - include: import-name-list + - match: (?=\S) + pop: true + - match: '' + set: + - meta_scope: meta.statement.import.python + - include: line-continuation-or-pop + - include: import-name-list + - match: (?=\S) + pop: true + - match: (?=\S) + pop: true + - include: import-from-name + - match: (?=\S) + pop: true + + import-name-list: + - match: ',' + scope: punctuation.separator.import-list.python + - include: import-alias + - include: name + - match: \* + scope: constant.language.import-all.python + - match: \S+ + scope: invalid.illegal.name.import.python + + import-alias: + - match: \b(as)\b + scope: keyword.control.import.as.python + + import-from-name: + - match: \.+ + scope: meta.import-path.python keyword.control.import.relative.python + - match: (?={{path}}) + push: + - meta_scope: meta.import-path.python + - match: '{{illegal_names}}\b' + scope: invalid.illegal.name.python + - match: '{{identifier}}' + scope: meta.import-name.python + - match: \s*(\.) *(?:({{illegal_names}}\b)|({{identifier}})) + captures: + 1: punctuation.accessor.dot.python + 2: invalid.illegal.name.python + 3: meta.import-name.python + - match: \ *(\. *\S+) # matches and consumes the remainder of "abc.123" or "abc.+" + captures: + 1: invalid.illegal.name.python + pop: true + - match: '' + pop: true + + block-statements: + # async for ... in ...: + - match: \b(async +)?(for)\b + captures: + 1: storage.modifier.async.python + 2: keyword.control.loop.for.python + push: + - meta_scope: meta.statement.loop.for.python + - include: line-continuation-or-pop + - match: \bin\b + scope: keyword.control.loop.for.in.python + set: + - meta_content_scope: meta.statement.loop.for.python + - include: line-continuation-or-pop + - match: ':(?!=)' + scope: meta.statement.loop.for.python punctuation.section.block.loop.for.python + pop: true + - include: expression-in-a-statement + - match: ':(?!=)' + scope: invalid.illegal.missing-in.python + pop: true + - include: target-list + # async with ... as ...: + - match: \b(async +)?(with)\b + captures: + 1: storage.modifier.async.python + 2: keyword.control.flow.with.python + push: with-body + # except ... as ...: + - match: \bexcept\b + scope: keyword.control.exception.catch.python + push: + - meta_scope: meta.statement.exception.catch.python + - include: line-continuation-or-pop + - match: ':(?!=)' + scope: punctuation.section.block.exception.catch.python + pop: true + - match: '\bas\b' + scope: keyword.control.exception.catch.as.python + set: + - meta_content_scope: meta.statement.exception.catch.python + - include: line-continuation-or-pop + - match: ':' + scope: meta.statement.exception.catch.python punctuation.section.block.exception.catch.python + pop: true + - include: name + - include: target-list + - match: \bif\b + scope: keyword.control.conditional.if.python + push: + - meta_scope: meta.statement.conditional.if.python + - include: line-continuation-or-pop + - match: ':(?!=)' + scope: punctuation.section.block.conditional.if.python + pop: true + - include: expression-in-a-statement + - match: \bwhile\b + scope: keyword.control.loop.while.python + push: + - meta_scope: meta.statement.loop.while.python + - include: line-continuation-or-pop + - match: ':(?!=)' + scope: punctuation.section.block.loop.while.python + pop: true + - include: expression-in-a-statement + - match: \b(else)\b(?:\s*(:))? + scope: meta.statement.conditional.else.python + captures: + 1: keyword.control.conditional.else.python + 2: punctuation.section.block.conditional.else.python + - match: \b(try)\b(?:\s*(:))? + scope: meta.statement.exception.try.python + captures: + 1: keyword.control.exception.try.python + 2: punctuation.section.block.exception.try.python + - match: \b(finally)\b(?:\s*(:))? + scope: meta.statement.exception.finally.python + captures: + 1: keyword.control.exception.finally.python + 2: punctuation.section.block.exception.finally.python + - match: \belif\b + scope: keyword.control.conditional.elseif.python + push: + - meta_scope: meta.statement.conditional.elseif.python + - match: ':(?!=)' + scope: punctuation.section.block.conditional.elseif.python + pop: true + - match: $\n? + pop: true + - include: expression-in-a-statement + + with-body: + - meta_scope: meta.statement.with.python + - include: line-continuation-or-pop + - match: \b(as)\b + scope: keyword.control.flow.with.as.python + set: with-as + - match: ':(?!=)' + scope: punctuation.section.block.with.python + pop: true + - match: ',' + scope: punctuation.separator.with-resources.python + - include: expression-in-a-statement + + with-as: + - meta_scope: meta.statement.with.python + - include: line-continuation-or-pop + - match: ':' + scope: punctuation.section.block.with.python + pop: true + - match: ',' + scope: punctuation.separator.with-resources.python + set: with-body + - include: name + - include: groups + - include: lists + + expressions-common: + - include: comments + - include: constants + - include: numbers + - include: yields + - include: operators + - include: lambda + - match: \b(await)\b + scope: keyword.other.await.python + - include: inline-if + - include: strings + - include: function-calls + - include: item-access + - include: lists + - include: dictionaries-and-sets + - include: tuples + - include: groups + - match: \) + scope: invalid.illegal.stray.brace.round.python + - match: \] + scope: invalid.illegal.stray.brace.square.python + - match: \} + scope: invalid.illegal.stray.brace.curly.python + - include: line-continuation + + # Always include these last and only one at a time! + expression-as-a-statement: + - include: expressions-common + - include: qualified-name + + expression-in-a-statement: + # Differs from expression-as-a-statement in that: + # - invalid-name matches will pop the current context + # - assignment expressions + - include: expressions-common + - include: illegal-names-pop + - include: qualified-name + - include: assignment-expression + + expression-in-a-group: # Always include this last! + # Differs from expression-in-a-statement in that: + # - accessor matching continues into the next line + - include: expression-in-a-statement + - match: '(\.) *(?={{identifier}})' + captures: + 1: punctuation.accessor.dot.python + push: + - include: magic-function-names + - include: magic-variable-names + - include: illegal-names + - include: generic-names + - match: '' + pop: true + + after-expression: + # direct function call + - match: '\s*(\()' + captures: + 1: punctuation.section.arguments.begin.python + push: + - meta_scope: meta.function-call.arguments.python + - match: \) + scope: punctuation.section.arguments.end.python + pop: true + - include: arguments + # item access + - match: '\s*(\[)' + captures: + 1: meta.item-access.python punctuation.section.brackets.begin.python + push: + - meta_content_scope: meta.item-access.arguments.python + - match: \] + scope: meta.item-access.python punctuation.section.brackets.end.python + pop: true + - include: illegal-assignment-expression + - match: ':' + scope: punctuation.separator.slice.python + - include: expression-in-a-group + # indirect function call following attribute access + - include: function-calls + # arbitrary attribute access + - match: '\s*(\.)' + captures: + 1: punctuation.accessor.dot.python + push: + - include: magic-function-names + - include: magic-variable-names + - include: illegal-names + - include: generic-names + - match: '' + pop: true + - match: '' + pop: true + + comments: + - match: "#" + scope: punctuation.definition.comment.python + push: + - meta_scope: comment.line.number-sign.python + - match: \n + pop: true + + constants: + - match: \b(None|True|False|Ellipsis|NotImplemented|__debug__)\b + scope: constant.language.python + - match: \.{3}(?!\w) + scope: constant.language.python + + numbers: + # https://docs.python.org/3/reference/lexical_analysis.html#numeric-literals + # hexadecimal + - match: \b(?i)(0x)\h*(L) # py2 + scope: constant.numeric.integer.hexadecimal.python + captures: + 1: punctuation.definition.numeric.base.python + 2: storage.type.numeric.python + - match: \b(?i)(0x)(_?\h)+ + scope: constant.numeric.integer.hexadecimal.python + captures: + 1: punctuation.definition.numeric.base.python + # octal + - match: \b(?i)(0o?)(?=o|[0-7])[0-7]*(L) # py2 + scope: constant.numeric.integer.octal.python + captures: + 1: punctuation.definition.numeric.base.python + 2: storage.type.numeric.python + - match: \b(?i)(0)[0-7]+ # py2 + scope: constant.numeric.integer.octal.python + captures: + 1: punctuation.definition.numeric.base.python + - match: \b(?i)(0o)(_?[0-7])+ + scope: constant.numeric.integer.octal.python + captures: + 1: punctuation.definition.numeric.base.python + # binary + - match: \b(?i)(0b)[01]*(L) # py2 + scope: constant.numeric.integer.binary.python + captures: + 1: punctuation.definition.numeric.base.python + 2: storage.type.numeric.python + - match: \b(?i)(0b)(_?[01])* + scope: constant.numeric.integer.binary.python + captures: + 1: punctuation.definition.numeric.base.python + # complex + - match: |- + (?x: + # 1.j, 1.1j, 1.1e1j, 1.1e-1j, 1.e1j, 1.e-1 | 1e1j, 1e-1j + \b{{digits}} (\.)? {{digits}}? {{exponent}}? + # .1j, .1e1j, .1e-1j + | (\.) {{digits}} {{exponent}}? + )([jJ]) + scope: constant.numeric.imaginary.decimal.python + captures: + 1: punctuation.separator.decimal.python + 2: punctuation.separator.decimal.python + 3: storage.type.numeric.python + # floating point + - match: |- + (?x: + # 1., 1.1, 1.1e1, 1.1e-1, 1.e1, 1.e-1 | 1e1, 1e-1 + \b{{digits}} (?: (\.) {{digits}}? {{exponent}}? | {{exponent}} ) + # .1, .1e1, .1e-1 + | (\.) {{digits}} {{exponent}}? + ) + scope: constant.numeric.float.decimal.python + captures: + 1: punctuation.separator.decimal.python + 2: punctuation.separator.decimal.python + # integer + - match: \b(?i)(?:[1-9]\d*|0)(L)\b # py2 + scope: constant.numeric.integer.decimal.python + captures: + 1: storage.type.numeric.python + - match: \b(?i)([1-9][\d_]*|0)\b + scope: constant.numeric.integer.decimal.python + + modifiers: + - match: \b(?:(global)|(nonlocal))\b + captures: + 1: storage.modifier.global.python + 2: storage.modifier.nonlocal.python + push: + - include: line-continuation-or-pop + - match: ',' + scope: punctuation.separator.storage-list.python + - include: name + - match: \S+ + scope: invalid.illegal.name.storage.python + + yields: + - match: \b(yield)(?:\s+(from))?\b + captures: + 1: keyword.control.flow.yield.python + 2: keyword.control.flow.yield-from.python + + assignment-expression: + - match: := + scope: keyword.operator.assignment.inline.python + + illegal-assignment-expression: + - match: := + scope: invalid.illegal.not-allowed-here.python + + assignments: + - include: illegal-assignment-expression + - match: ':' + scope: punctuation.separator.annotation.variable.python + - match: \+=|-=|\*=|/=|//=|%=|@=|&=|\|=|\^=|>>=|<<=|\*\*= + scope: keyword.operator.assignment.augmented.python + - match: '=(?!=)' + scope: keyword.operator.assignment.python + + operators: + - match: <> + scope: invalid.deprecated.operator.python + - match: <\=|>\=|\=\=|<|>|\!\= + scope: keyword.operator.comparison.python + - match: \+|\-|\*|\*\*|/|//|%|<<|>>|&|\||\^|~ + scope: keyword.operator.arithmetic.python + - match: \b(and|in|is|not|or)\b + comment: keyword operators that evaluate to True or False + scope: keyword.operator.logical.python + - match: '@' + scope: keyword.operator.matrix.python + + allow-unpack-operators: + # Match unpacking operators, if present + - include: comments + - match: \*{3,} + scope: invalid.illegal.syntax.python + pop: true + - match: \*\* + scope: keyword.operator.unpacking.mapping.python + pop: true + - match: \* + scope: keyword.operator.unpacking.sequence.python + pop: true + - match: (?=\S) + pop: true + + classes: + - match: '^\s*(class)\b' + captures: + 1: storage.type.class.python keyword.declaration.class.python + push: + - meta_scope: meta.class.python + - include: line-continuation-or-pop + - match: ':' + scope: punctuation.section.class.begin.python + pop: true + - match: "(?={{identifier}})" + push: + - meta_content_scope: entity.name.class.python + - include: entity-name-class + - match: '' + pop: true + - match: \( + scope: punctuation.section.inheritance.begin.python + set: + - meta_scope: meta.class.inheritance.python + - match: \) + scope: punctuation.section.inheritance.end.python + set: + - include: line-continuation-or-pop + - match: ':' + scope: meta.class.python punctuation.section.class.begin.python + pop: true + - match: (?=\S) + pop: true + - match: ':' + scope: invalid.illegal.no-closing-parens.python + pop: true + - match: ',' + scope: punctuation.separator.inheritance.python + - include: illegal-names-pop + - match: ({{identifier}}) *(=) + captures: + 1: variable.parameter.class-inheritance.python + 2: keyword.operator.assignment.python + - match: (?={{path}}) + push: + - meta_scope: entity.other.inherited-class.python + - match: '{{identifier}}(?: *(\.) *)?' + captures: + 1: punctuation.accessor.dot.python + - match: '' + pop: true + - include: expression-in-a-group + + functions: + - match: '^\s*(?:(async)\s+)?(def)\b' + captures: + 1: storage.modifier.async.python + 2: storage.type.function.python keyword.declaration.function.python + push: + - meta_scope: meta.function.python + - include: line-continuation-or-pop + - match: ':' + scope: punctuation.section.function.begin.python + pop: true + - match: "(?={{identifier}})" + push: + - meta_content_scope: entity.name.function.python + - include: entity-name-function + - match: '' + pop: true + - match: '(?=\()' + set: + - match: \( + scope: meta.function.parameters.python punctuation.section.parameters.begin.python + set: [function-parameters, allow-unpack-operators] + + function-parameters: + - meta_content_scope: meta.function.parameters.python + - match: \) + scope: punctuation.section.parameters.end.python + set: function-after-parameters + - include: comments + - match: ',' + scope: punctuation.separator.parameters.python + push: allow-unpack-operators + - match: / + scope: storage.modifier.positional-args-only.python + push: + - match: (?=[,)]) + pop: true + - match: \S + scope: invalid.illegal.expected-comma.python + - match: '(?==)' + set: + - match: '=' + scope: keyword.operator.assignment.python + set: + - meta_scope: meta.function.parameters.default-value.python + - match: '(?=[,)])' + set: [function-parameters, allow-unpack-operators] + - include: illegal-assignment-expression + - include: expression-in-a-group + - match: '(?=:)' + set: + - match: ':' + scope: punctuation.separator.annotation.parameter.python + set: + - meta_scope: meta.function.parameters.annotation.python + - match: '(?=[,)=])' + set: function-parameters + - include: illegal-assignment-expression + - include: expression-in-a-group + - include: function-parameters-tuple + - include: illegal-names + - match: '{{identifier}}' + scope: variable.parameter.python + - include: line-continuation + + function-parameters-tuple: + # python 2 style tuple arguments + # removed from python 3 since PEP-3113 + - match: \( + scope: punctuation.section.group.begin.python + push: + - meta_scope: meta.group.python + - match: \) + scope: punctuation.section.group.end.python + set: after-expression + - include: comments + - match: ',' + scope: punctuation.separator.parameters.python + push: allow-unpack-operators + # default values should follow the argument + - match: '=' + push: + - meta_scope: invalid.illegal.default-value.python + - match: '(?=[,)=])' + pop: true + # python 2 does not support type annotations + - match: '(?=:)' + push: + - meta_scope: invalid.illegal.annotation.python + - match: '(?=[,)=])' + pop: true + - include: illegal-names + - match: '{{identifier}}' + scope: variable.parameter.python + - include: line-continuation + + function-after-parameters: + - meta_content_scope: meta.function.python + - match: '(?=->)' + set: + - meta_content_scope: meta.function.annotation.return.python + - match: -> + scope: punctuation.separator.annotation.return.python + - include: illegal-assignment-expression + - match: '(?=:)' + set: function-after-parameters + - include: line-continuation-or-pop + - include: expression-in-a-statement + - match: ':' + scope: meta.function.python punctuation.section.function.begin.python + pop: true + - include: comments + - match: (?=\S) + pop: true + + decorators: + - match: ^\s*(?=@) + push: + # Due to line continuations, we don't know whether this is a "function call" yet + - meta_content_scope: meta.annotation.python + - match: '@' + scope: punctuation.definition.annotation.python + - match: $ + pop: true + - include: line-continuation-or-pop + - match: (?=\.?\s*{{path}}\s*\() # now we do + set: [decorator-function-call-wrapper, qualified-name-until-leaf] + - match: (?=\.?\s*{{path}}) + push: [decorator-wrapper, qualified-name-until-leaf] + - match: \S + scope: invalid.illegal.character.python + pop: true + + decorator-wrapper: + - match: (\.)\s* + captures: + 1: punctuation.accessor.dot.python + set: + - meta_scope: meta.qualified-name.python + - meta_content_scope: variable.annotation.python + - include: dotted-name-specials + - include: generic-names + - match: '' + pop: true + - match: '' + set: + - meta_scope: meta.qualified-name.python variable.annotation.python + - include: name-specials + - include: generic-names + - match: '' + pop: true + + decorator-function-call-wrapper: + - meta_scope: meta.annotation.function.python + - match: \) + scope: punctuation.section.arguments.end.python + set: after-expression + - match: \( + scope: meta.annotation.function.python punctuation.section.arguments.begin.python + push: + - clear_scopes: 1 + - meta_content_scope: meta.annotation.arguments.python + - match: (?=\)) + pop: true + - include: arguments + - match: (\.)\s* + captures: + 1: punctuation.accessor.dot.python + push: + - meta_scope: meta.qualified-name.python + - meta_content_scope: variable.annotation.function.python + - include: dotted-name-specials + - include: generic-names + - match: '' + pop: true + - match: '' + push: + - meta_scope: meta.qualified-name.python variable.annotation.function.python + - include: name-specials + - include: generic-names + - match: '' + pop: true + + item-access: + - match: '(?={{path}}\s*\[)' + push: + - match: \] + scope: meta.item-access.python punctuation.section.brackets.end.python + set: after-expression + - match: '(?={{path}}\s*\[)' + push: + - meta_content_scope: meta.item-access.python + - match: '(?=\s*\[)' + pop: true + - include: qualified-name + - match: \[ + scope: meta.item-access.python punctuation.section.brackets.begin.python + push: + - meta_content_scope: meta.item-access.arguments.python + - match: '(?=\])' + pop: true + - match: ':' + scope: punctuation.separator.slice.python + - include: expression-in-a-group + + function-calls: + - match: '(?=(\.\s*)?{{path}}\s*\()' + push: [function-call-wrapper, qualified-name-until-leaf] + + function-call-wrapper: + - meta_scope: meta.function-call.python + - match: (?=\() # need to remove meta.function-call.python from opening parens + set: + - match: \( + scope: punctuation.section.arguments.begin.python + set: + - meta_scope: meta.function-call.arguments.python + - match: \) + scope: punctuation.section.arguments.end.python + set: after-expression + - include: arguments + - match: (\.)\s*(?={{identifier}}) + captures: + 1: punctuation.accessor.dot.python + push: + - meta_scope: meta.qualified-name.python + - meta_content_scope: variable.function.python + - include: dotted-name-specials + - include: generic-names + - match: '' + pop: true + - match: (?={{identifier}}) + push: + - meta_scope: meta.qualified-name.python variable.function.python + - include: name-specials + - include: generic-names + - match: '' + pop: true + + arguments: + - include: keyword-arguments + - match: ',' + scope: punctuation.separator.arguments.python + push: allow-unpack-operators + - include: inline-for + - include: expression-in-a-group + + keyword-arguments: + - match: '(?={{identifier}}\s*=(?!=))' + push: + - include: line-continuation-or-pop + - match: '=' + scope: keyword.operator.assignment.python + set: + - include: illegal-assignment-expression + - match: (?=[,):]) + pop: true + - include: expression-in-a-group + - include: illegal-names + - match: '{{identifier}}' + scope: variable.parameter.python + + lambda: + - match: \b(lambda)(?=\s|:|$) + scope: storage.type.function.inline.python keyword.declaration.function.inline.python + push: [lambda-parameters, allow-unpack-operators] + + lambda-parameters: + - meta_scope: meta.function.inline.python + - meta_content_scope: meta.function.inline.parameters.python + - include: line-continuation-or-pop + - match: '\:' + scope: punctuation.section.function.begin.python + set: + # clear meta_scope + - match: '' + set: + - meta_scope: meta.function.inline.body.python + - include: illegal-assignment-expression + # We don't know whether we are within a grouped + # or line-statement context at this point. + # If we're in a group, the underlying context will take over + # at the end of the line. + - match: (?=[,):])|$ + pop: true + - include: expression-in-a-statement + - match: ',' + scope: punctuation.separator.parameters.python + push: allow-unpack-operators + - include: keyword-arguments + - include: function-parameters-tuple + - include: illegal-names + - match: '{{identifier}}' + scope: variable.parameter.python + - match: '\S' + scope: invalid.illegal.expected-parameter.python + + groups: + - match: \( + scope: punctuation.section.group.begin.python + push: + - meta_scope: meta.group.python + - match: \) + scope: punctuation.section.group.end.python + set: after-expression + - match: ',' + scope: punctuation.separator.tuple.python + - include: inline-for + - include: expression-in-a-group + + tuples: + # We don't know for certain, whether a parenthesized expression is a tuple, + # so try looking ahead. + - match: (\()\s*(\)) + scope: meta.sequence.tuple.empty.python + captures: + 1: punctuation.section.sequence.begin.python + 2: punctuation.section.sequence.end.python + push: after-expression + - match: \((?={{simple_expression}},|\s*\*{{path}}) + scope: punctuation.section.sequence.begin.python + push: inside-tuple + # TODO generator + # - match: \((?:{{simple_expression}}for) + + inside-tuple: + - meta_scope: meta.sequence.tuple.python + - match: \) + scope: punctuation.section.sequence.end.python + set: after-expression + - match: ',' + scope: punctuation.separator.sequence.python + push: allow-unpack-operators + - include: inline-for + - include: expression-in-a-group + + lists: + - match: (\[)\s*(\]) + scope: meta.sequence.list.empty.python + captures: + 1: punctuation.section.sequence.begin.python + 2: punctuation.section.sequence.end.python + push: after-expression + - match: \[ + scope: punctuation.section.sequence.begin.python + push: [inside-list, allow-unpack-operators] + + inside-list: + - meta_scope: meta.sequence.list.python + - match: \] + scope: punctuation.section.sequence.end.python + set: after-expression + - match: ',' + scope: punctuation.separator.sequence.python + push: allow-unpack-operators + - include: inline-for + - include: expression-in-a-group + + dictionaries-and-sets: + # Dictionaries and set literals use the same punctuation, + # so we try looking ahead to determine whether we have a dict or a set. + - match: '(\{)\s*(\})' + scope: meta.mapping.empty.python + captures: + 1: punctuation.section.mapping.begin.python + 2: punctuation.section.mapping.end.python + push: after-expression + - match: \{(?={{simple_expression}}:|\s*\*\*) + scope: punctuation.section.mapping.begin.python + push: inside-dictionary + - match: \{(?={{simple_expression}}[,}]|\s*\*) + scope: punctuation.section.set.begin.python + push: inside-set + # If the expression is "more complex" or on the next line, + # fall back to default and determine later. + - match: \{ + scope: punctuation.section.mapping-or-set.begin.python + push: + - meta_scope: meta.mapping-or-set.python + - match: \} + scope: punctuation.section.mapping-or-set.end.python + set: after-expression + - match: (?={{simple_expression}}:|\s*\*\*) + set: inside-dictionary + - match: (?={{simple_expression}}[,}]|\s*\*) + set: inside-set + - match: ',' + scope: punctuation.separator.set.python + set: inside-set + - include: illegal-assignment-expression + - match: ':' + scope: punctuation.separator.mapping.key-value.python + set: inside-directory-value + - include: inline-for + - include: expression-in-a-group + + inside-dictionary: + - meta_scope: meta.mapping.python + - match: \} + scope: punctuation.section.mapping.end.python + set: after-expression + - include: illegal-assignment-expression + - match: ':' + scope: punctuation.separator.mapping.key-value.python + set: inside-directory-value + - match: ',' + scope: invalid.illegal.expected-colon.python + - match: \*\* + scope: keyword.operator.unpacking.mapping.python + push: + - match: (?=\}) + pop: true + - match: ',' + scope: punctuation.separator.mapping.python + pop: true + - include: expression-in-a-group + - include: comments + - match: (?=\S) + push: + - clear_scopes: 1 + - meta_scope: meta.mapping.key.python + - match: \s*(?=\}|,|:) + pop: true + - include: expression-in-a-group + + inside-directory-value: + - meta_content_scope: meta.mapping.python + - match: \} + scope: punctuation.section.mapping.end.python + set: after-expression + - match: (?=,) + set: + # clear meta scope from this match, because 'inside-directory' has it in meta_scope + - match: ',' + scope: punctuation.separator.mapping.python + set: inside-dictionary + - match: (?=for\b) + push: + - match: (?=\}) + pop: true + - match: ',' + scope: invalid.illegal.unexpected-comma.python + - include: inline-for + - include: expression-in-a-group + - include: comments + - match: (?=\S) + push: + - clear_scopes: 1 + - meta_content_scope: meta.mapping.value.python + - match: (?=\s*(\}|,|for\b)) + pop: true + - include: expression-in-a-group + + inside-set: + - meta_scope: meta.set.python + - match: \} + scope: punctuation.section.set.end.python + set: after-expression + - include: illegal-assignment-expression + - match: ':' + scope: invalid.illegal.colon-inside-set.python + - match: ',' + scope: punctuation.separator.set.python + - match: \* + scope: keyword.operator.unpacking.sequence.python + push: + - match: (?=\}) + pop: true + - match: ',' + scope: punctuation.separator.set.python + pop: true + - include: expression-in-a-group + - include: inline-for + - include: expression-in-a-group + + builtin-exceptions: + - match: |- + (?x)\b( + ( + Arithmetic|Assertion|Attribute|BlockingIO|BrokenPipe|Buffer|ChildProcess| + Connection(Aborted|Refused|Reset)?|EOF|Environment|FileExists| + FileNotFound|FloatingPoint|Interrupted|IO|IsADirectoryError| + Import|Indentation|Index|Key|Lookup|Memory|Name|NotADirectory| + NotImplemented|OS|Overflow|Permission|ProcessLookup|Reference| + Runtime|Standard|Syntax|System|Tab|Timeout|Type|UnboundLocal| + Unicode(Encode|Decode|Translate)?|Value|VMS|Windows|ZeroDivision + )Error| + ((Pending)?Deprecation|Runtime|Syntax|User|Future|Import|Unicode|Bytes)?Warning| + (Base)?Exception| + SystemExit|StopIteration|NotImplemented|KeyboardInterrupt|GeneratorExit + )\b + scope: support.type.exception.python + + builtin-functions: + - match: |- + (?x)\b( + __import__|all|abs|any|apply|ascii|bin|breakpoint|callable|chr|classmethod|cmp|coerce| + compile|delattr|dir|divmod|enumerate|eval|exec|execfile|filter|format|getattr| + globals|hasattr|hash|help|hex|id|input|intern|isinstance|issubclass|iter| + len|locals|map|max|min|next|oct|open|ord|pow|print|property|range| + raw_input|reduce|reload|repr|reversed|round|setattr|sorted|staticmethod| + sum|super|type|unichr|vars|zip + )\b + scope: support.function.builtin.python + + builtin-types: + - match: |- + (?x)\b( + basestring|bool|buffer|bytearray|bytes|complex|dict|float|frozenset|int| + list|long|memoryview|object|range|set|slice|str|tuple|unicode|xrange + )\b + scope: support.type.python + + name: + - match: '(?={{identifier}})' + push: + - include: name-specials + - match: '{{identifier_constant}}' + scope: variable.other.constant.python + - include: generic-names + - match: '' + pop: true + + dotted-name: + - match: '\s*(\.)\s*(?={{identifier}})' + captures: + 1: punctuation.accessor.dot.python + push: + - include: dotted-name-specials + - match: '{{identifier_constant}}' + scope: variable.other.constant.python + - include: generic-names + - match: '' + pop: true + + qualified-name: + - match: '(?={{path}})' + push: + - meta_scope: meta.qualified-name.python + - include: name + - include: dotted-name + - match: '' + pop: true + + qualified-name-until-leaf: + # Push this together with another context to match a qualified name + # until the last non-special identifier (if any). + # This allows the leaf to be scoped individually. + - meta_scope: meta.qualified-name.python + # If a line continuation follows, this may or may not be the last leaf (most likley not though) + - match: (?={{identifier}}\s*(\.|\\)) + push: + - include: name-specials + - include: generic-names + - match: '' + pop: true + - match: (\.)\s*(?={{identifier}}\s*(\.|\\)) + captures: + 1: punctuation.accessor.dot.python + push: + - include: dotted-name-specials + - include: generic-names + - match: '' + pop: true + - match: \.(?!\s*{{identifier}}) # don't match last dot + scope: punctuation.accessor.dot.python + - match: (?=\S|$) + pop: true + + name-specials: + - include: builtin-functions + - include: builtin-types + - include: builtin-exceptions + - include: illegal-names + - include: magic-function-names + - include: magic-variable-names + - include: language-variables + + dotted-name-specials: + - include: magic-function-names + - include: magic-variable-names + - include: illegal-names + + entity-name-class: + - include: illegal-names + - include: generic-names + + entity-name-function: + - include: magic-function-names + - include: illegal-names + - include: generic-names + + generic-names: + - match: '{{identifier}}' + scope: meta.generic-name.python + + illegal-names: + - match: \b{{illegal_names}}\b + scope: invalid.illegal.name.python + + illegal-names-pop: + - match: \b{{illegal_names}}\b + scope: invalid.illegal.name.python + pop: true + + language-variables: + - match: \b(self|cls)\b + scope: variable.language.python + - match: _(?!{{identifier_continue}}) + scope: variable.language.python + + line-continuation: + - match: (\\)(.*)$\n? + captures: + 1: punctuation.separator.continuation.line.python + 2: invalid.illegal.unexpected-text.python + # make sure to resume parsing at next line + push: + # This prevents strings after a continuation from being a docstring + - include: strings + - match: (?=\S|^\s*$|\n) # '\n' for when we matched a string earlier + pop: true + + line-continuation-or-pop: + - include: line-continuation + - match: (?=\s*($|;|#)) + pop: true + + magic-function-names: + # https://docs.python.org/2/reference/datamodel.html + # https://docs.python.org/3/reference/datamodel.html + - match: |- + (?x)\b__(?: + # unary operators + invert|neg|pos|abs| + # binary operators + add|and|div|divmod|floordiv|lshift|mod|mul|or|pow|rshift|sub|truediv|xor| + contains| + # right-hand binary operators + radd|rand|rdiv|rdivmod|rfloordiv|rlshift|rmod|rmul|ror|rpow|rrshift|rsub|rtruediv|rxor| + # in-place operator assignments + iadd|iand|idiv|ifloordiv|ilshift|imod|imul|ior|ipow|irshift|isub|itruediv|ixor| + # comparisons + eq|ge|gt|le|lt|ne| + cmp|rcmp| # py2 + # primary coercion + bool|str| + nonzero|unicode| # py2 + # number coercion (converts something to a number) + bytes|complex|float|index|int|round| + long| # py2 + # other "coercion" + format|len|length_hint|hash|repr|reversed| + coerce|hex|oct| # py2 + fspath| + # iterator (and 'await') + iter|next| + aiter|anext| + await| + # attribute and item access + delattr|delitem|delslice| + getattr|getattribute|getitem|getslice| + setattr|setitem|setslice| + dir|missing| + # context manager + enter|exit| + aenter|aexit| + # other class magic + call|del|init|new|init_subclass| + instancecheck|subclasscheck| + # pickling + getnewargs|getnewargs_ex|getstate|setstate|reduce|reduce_ex| + # descriptors + delete|get|set|set_name| + # class-specific + subclasses| + # dataclasses (PEP 557) + post_init| + # for typing core support (PEP 560) + class_getitem|mro_entries + )__\b + comment: these methods have magic interpretation by python and are generally called indirectly through syntactic constructs + scope: support.function.magic.python + + magic-variable-names: + # magic variables which a class/module/object may have. + # https://docs.python.org/3/library/inspect.html#types-and-members + # https://docs.python.org/3/reference/datamodel.html#object.__slots__ + # https://docs.python.org/3/reference/datamodel.html#preparing-the-class-namespace + - match: |- + (?x)\b__(?: + # generic object + class|dict|doc|module|name| + # module-specific / global + all|file|package| + # functions & methods + annotations|closure|code|defaults|func|globals|kwdefaults|self|qualname| + # classes (attributes) + bases|prepare|slots|metaclass|mro| + # Python 2 + members|methods + )__\b + scope: support.variable.magic.python + + docstrings: + - match: ^\s*(?=(?i)(ur|ru|u|r)?("""|''')) + push: + - match: (?i)(u)?("""|''') + captures: + 1: storage.type.string.python + 2: punctuation.definition.comment.begin.python + set: + - meta_scope: comment.block.documentation.python + - include: escaped-unicode-char + - include: escaped-char + - match: '\2' + scope: punctuation.definition.comment.end.python + pop: true + - match: (?i)(u?ru?)("""|''') + captures: + 1: storage.type.string.python + 2: punctuation.definition.comment.begin.python + set: + - meta_scope: comment.block.documentation.python + - match: '\2' + scope: punctuation.definition.comment.end.python + pop: true + + escaped-char: + - match: '(\\x\h{2})|(\\[0-7]{1,3})|(\\[\\"''abfnrtv])' + captures: + 1: constant.character.escape.hex.python + 2: constant.character.escape.octal.python + 3: constant.character.escape.python + - match: \\. # deprecated in 3.6 and will eventually be a syntax error + scope: invalid.deprecated.character.escape.python + + escaped-unicode-char: + - match: '(\\U\h{8})|(\\u\h{4})|(\\N\{[a-zA-Z ]+\})' + captures: + 1: constant.character.escape.unicode.16-bit-hex.python + 2: constant.character.escape.unicode.32-bit-hex.python + 3: constant.character.escape.unicode.name.python + + escaped-fstring-escape: + # special-case the '\{{' sequence because it has higher priority than the deprecated '\{' + - match: (\\)(\{\{|\}\}) + scope: constant.character.escape.backslash.regexp + captures: + 1: invalid.deprecated.character.escape.python + 2: constant.character.escape.python + + line-continuation-inside-string: + - match: (\\)$\n? + captures: + 1: punctuation.separator.continuation.line.python + - match: \n + scope: invalid.illegal.unclosed-string.python + set: after-expression + + line-continuation-inside-block-string: + - match: \\$ + scope: punctuation.separator.continuation.line.python + + constant-placeholder: + - match: |- # printf style + (?x) + % + ( \( ({{identifier}}) \) )? # mapping key + \#? # alternate form + 0? # pad with zeros + \-? # left-adjust + \ ? # implicit sign + [+-]? # sign + (\d*|\*) # width + (\. (\d*|\*))? # precision + [hlL]? # length modifier (but ignored) + [acdeEfFgGiorsuxX%] + scope: constant.other.placeholder.python + captures: + 2: variable.other.placeholder.python + - match: '{{strftime_spec}}' + scope: constant.other.placeholder.python + - match: '\{\{|\}\}' + scope: constant.character.escape.python + - include: formatting-syntax + + formatting-syntax: + # https://docs.python.org/3.6/library/string.html#formatstrings + - match: |- # simple form + (?x) + (\{) + (?: [\w.\[\]]+)? # field_name + ( ! [ars])? # conversion + ( : (?:{{format_spec}}| # format_spec OR + [^}%]*%.[^}]*) # any format-like string + )? + (\}) + scope: constant.other.placeholder.python + captures: + 1: punctuation.definition.placeholder.begin.python + 2: storage.modifier.conversion.python + 3: constant.other.format-spec.python + 4: punctuation.definition.placeholder.end.python + - match: \{(?=[^\}"']+\{[^"']*\}) # complex (nested) form + scope: punctuation.definition.placeholder.begin.python + push: + - meta_scope: constant.other.placeholder.python + - match: \} + scope: punctuation.definition.placeholder.end.python + pop: true + - match: '[\w.\[\]]+' + - match: '![ars]' + scope: storage.modifier.conversion.python + - match: ':' + push: + - meta_scope: meta.format-spec.python constant.other.format-spec.python + - match: (?=\}) + pop: true + - include: formatting-syntax + + f-string-content: + # https://www.python.org/dev/peps/pep-0498/ + # https://docs.python.org/3.6/reference/lexical_analysis.html#f-strings + - match: \{\{|\}\} + scope: constant.character.escape.python + - match: \{\s*\} + scope: invalid.illegal.empty-expression.python + - match: (?=\{) + push: f-string-replacement + - match: \} + scope: invalid.illegal.stray-brace.python + + f-string-content-with-regex: + # Same as f-string-content, but will reset the entire scope stack + # and has an additional match. + - match: \\(\{\{|\}\}) + scope: constant.character.escape.backslash.regexp + captures: + 1: constant.character.escape.python + - match: \{\{|\}\} + scope: constant.character.escape.python + - match: \{\s*\} + scope: invalid.illegal.empty-expression.python + - match: (?=\{) + push: f-string-replacement-reset + - match: \} + scope: invalid.illegal.stray-brace.python + + f-string-replacement: + - clear_scopes: 1 + - match: \} + scope: meta.interpolation.python punctuation.section.interpolation.end.python + pop: true + - match: \{ + scope: punctuation.section.interpolation.begin.python + push: + - meta_scope: meta.interpolation.python + - match: (?=\}) + pop: true + - match: '![ars]' + scope: storage.modifier.conversion.python + - match: = + scope: storage.modifier.debug.python + - match: ':' + push: + - meta_scope: meta.format-spec.python constant.other.format-spec.python + # Because replacements can also be used *within* the format-spec, + # basically any character is valid and matching {{format_spec}} is useless. + # - match: '{{format_spec}}' + - match: (?=\}) + pop: true + - include: f-string-content + - match: '' + push: + - meta_content_scope: source.python.embedded + - match: (?==?(![^=]|:|\})) + pop: true + - match: \\ + scope: invalid.illegal.backslash-in-fstring.python + - include: inline-for + - include: expression-in-a-group + + f-string-replacement-reset: + # Same as f-string-replacement, but with clear_scopes: true + - clear_scopes: true + - meta_scope: source.python meta.string.interpolated.python + - match: \} + scope: meta.interpolation.python punctuation.section.interpolation.end.python + pop: true + - match: \{ + scope: punctuation.section.interpolation.begin.python + push: + - meta_scope: meta.interpolation.python + - match: (?=\}) + pop: true + - match: '![ars]' + scope: storage.modifier.conversion.python + - match: ':' + push: + - meta_scope: meta.format-spec.python constant.other.format-spec.python + - match: (?=\}) + pop: true + - include: f-string-content + - match: '' + push: + - meta_content_scope: source.python.embedded + - match: (?=![^=]|:|\}) + pop: true + - match: \\ + scope: invalid.illegal.backslash-in-fstring.python + - include: inline-for + - include: expression-in-a-group + + string-quoted-double-block: + # Triple-quoted capital R raw string, unicode or not, no syntax embedding + - match: '([uU]?R)(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-unicode-char + # Triple-quoted capital R raw string, bytes, no syntax embedding + - match: '([bB]R|R[bB])(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + # Triple-quoted raw string, unicode or not, will detect SQL, otherwise regex + - match: '([uU]?r)(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '(?={{sql_indicator}})' + set: + - meta_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?=""")' + pop: true + - include: escaped-unicode-char + - include: constant-placeholder + - match: '(?=\S)' + set: + - meta_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?=""")' + pop: true + - include: escaped-unicode-char + # Triple-quoted raw string, bytes, will use regex + - match: '([bB]r|r[bB])(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + embed: scope:source.regexp.python + escape: (?=""") + # Triple-quoted raw f-string + - match: ([fF]R|R[fF])(""") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.begin.python + set: after-expression + - include: f-string-content + # Triple-quoted raw f-string, treated as regex + - match: ([fF]r|r[fF])(""") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.begin.python + set: after-expression + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?=""")' + pop: true + - include: f-string-content-with-regex + # Triple-quoted f-string + - match: ([fF])(""") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.begin.python + set: after-expression + - include: line-continuation-inside-block-string + - include: escaped-fstring-escape + - include: escaped-unicode-char + - include: escaped-char + - include: f-string-content + # Triple-quoted string, unicode or not, will detect SQL + - match: '([uU]?)(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '(?={{sql_indicator}})' + set: + - meta_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?=""")' + pop: true + - include: line-continuation-inside-block-string + - include: escaped-unicode-char + - include: escaped-char + - include: constant-placeholder + - match: '(?=\S)' + set: + - meta_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-block-string + - include: escaped-unicode-char + - include: escaped-char + - include: constant-placeholder + # Triple-quoted string, bytes, no syntax embedding + - match: '([bB])(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-block-string + - include: escaped-char + - include: constant-placeholder + + string-quoted-double: + # Single-line capital R raw string, unicode or not, no syntax embedding + - match: '([uU]?R)(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + # Single-line capital R raw string, bytes, no syntax embedding + - match: '([bB]R|R[bB])(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + # Single-line raw string, unicode or not, starting with a SQL keyword + - match: '([uU]?r)(")(?={{sql_indicator}})' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?="|\n)' + pop: true + - include: constant-placeholder + - include: line-continuation-inside-string + # Single-line raw string, unicode or not, treated as regex + - match: '([uU]?r)(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?="|\n)' + pop: true + - include: line-continuation-inside-string + # Single-line raw string, bytes, treated as regex + - match: '([bB]r|r[bB])(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + embed: scope:source.regexp.python + escape: (?="|\n) + # Single-line raw f-string + - match: (R[fF]|[fF]R)(") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - include: f-string-content + # Single-line raw f-string, treated as regex + - match: (r[fF]|[fF]r)(") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?="|\n)' + pop: true + - include: line-continuation-inside-string + - include: f-string-content-with-regex + # Single-line f-string + - match: ([fF])(") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-fstring-escape + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: f-string-content + # Single-line string, unicode or not, starting with a SQL keyword + - match: '([uU]?)(")(?={{sql_indicator}})' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?="|\n)' + pop: true + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + # Single-line string, unicode or not + - match: '([uU]?)(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + # Single-line string, bytes + - match: '([bB])(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + + string-quoted-single-block: + # Triple-quoted capital R raw string, unicode or not, no syntax embedding + - match: ([uU]?R)(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + # Triple-quoted capital R raw string, bytes, no syntax embedding + - match: ([bB]R|R[bB])(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + # Triple-quoted raw string, unicode or not, will detect SQL, otherwise regex + - match: ([uU]?r)(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: '(?={{sql_indicator}})' + set: + - meta_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.sql + with_prototype: + - match: (?=''') + pop: true + - include: escaped-unicode-char + - include: escaped-char + - include: constant-placeholder + - match: '(?=\S)' + set: + - meta_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: (?=''') + pop: true + - include: escaped-unicode-char + # Triple-quoted raw string, bytes, will use regex + - match: ([bB]r|r[bB])(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + embed: scope:source.regexp.python + escape: (?=''') + # Triple-quoted raw f-string + - match: ([fF]R|R[fF])(''') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.begin.python + set: after-expression + - include: f-string-content + # Triple-quoted raw f-string, treated as regex + - match: ([fF]r|r[fF])(''') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.begin.python + set: after-expression + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: (?=''') + pop: true + - include: f-string-content-with-regex + # Triple-quoted f-string + - match: ([fF])(''') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.begin.python + set: after-expression + - include: line-continuation-inside-block-string + - include: escaped-fstring-escape + - include: escaped-unicode-char + - include: escaped-char + - include: f-string-content + # Triple-quoted string, unicode or not, will detect SQL + - match: ([uU]?)(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: '(?={{sql_indicator}})' + set: + - meta_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.sql + with_prototype: + - match: (?=''') + pop: true + - include: line-continuation-inside-block-string + - include: escaped-unicode-char + - include: escaped-char + - include: constant-placeholder + - match: '(?=\S)' + set: + - meta_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-block-string + - include: escaped-unicode-char + - include: escaped-char + - include: constant-placeholder + # Triple-quoted string, bytes, no syntax embedding + - match: ([bB])(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-block-string + - include: escaped-char + - include: constant-placeholder + + string-quoted-single: + # Single-line capital R raw string, unicode or not, no syntax embedding + - match: '([uU]?R)('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + # Single-line capital R raw string, bytes, no syntax embedding + - match: '([bB]R|R[bB])('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + # Single-line raw string, unicode or not, starting with a SQL keyword + - match: '([uU]?r)('')(?={{sql_indicator}})' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?=''|\n)' + pop: true + - include: line-continuation-inside-string + - include: constant-placeholder + # Single-line raw string, unicode or not, treated as regex + - match: '([uU]?r)('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?=''|\n)' + pop: true + - include: line-continuation-inside-string + # Single-line raw string, bytes, treated as regex + - match: '([bB]r|r[bB])('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?=''|\n)' + pop: true + - include: line-continuation-inside-string + # Single-line raw f-string + - match: ([fF]R|R[fF])(') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - include: f-string-content + # Single-line raw f-string, treated as regex + - match: ([fF]r|r[fF])(') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: (?='|\n) + pop: true + - include: line-continuation-inside-string + - include: f-string-content-with-regex + # Single-line f-string + - match: ([fF])(') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-fstring-escape + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: f-string-content + # Single-line string, unicode or not, starting with a SQL keyword + - match: '([uU]?)('')(?={{sql_indicator}})' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?=''|\n)' + pop: true + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + # Single-line string, unicode or not + - match: '([uU]?)('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + # Single-line string, bytes + - match: '([bB])('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + + strings: + # block versions must be matched first + - include: string-quoted-double-block + - include: string-quoted-double + - include: string-quoted-single-block + - include: string-quoted-single + + inline-for: + - match: \b(?:(async)\s+)?(for)\b + captures: + 1: storage.modifier.async.python + 2: keyword.control.loop.for.generator.python + push: + - include: comments + - meta_scope: meta.expression.generator.python + - match: \bin\b + scope: keyword.control.loop.for.in.python + pop: true + - match: '(?=[)\]}])' + scope: invalid.illegal.missing-in.python + pop: true + - include: illegal-names-pop + - include: target-list + + inline-if: + - match: \bif\b + scope: keyword.control.conditional.if.python + - match: \belse\b + scope: keyword.control.conditional.else.python + + target-list: + - match: ',' + scope: punctuation.separator.target-list.python + - match: \( + scope: punctuation.section.target-list.begin.python + push: + - include: comments + - match: ',' + scope: punctuation.separator.target-list.python + - match: \) + scope: punctuation.section.target-list.end.python + pop: true + - include: target-list + - include: name + - include: name diff --git a/syntaxes/Python/Regular Expressions (Python).sublime-syntax b/syntaxes/Python/Regular Expressions (Python).sublime-syntax @@ -0,0 +1,96 @@ +%YAML 1.2 +--- +name: Regular Expressions (Python) +comment: Matches Python's regular expression syntax. +scope: source.regexp.python +hidden: true +contexts: + main: + - match: (#)[^]\[(){}^$+*?\\|"']*$ + comment: + We are restrictive in what we allow to go after the comment character to avoid + false positives, since the availability of comments depend on regexp flags. + scope: comment.line.number-sign.regexp + captures: + 1: punctuation.definition.comment.regexp + - match: '\\[bBAZzG]|\^|\$' + scope: keyword.control.anchor.regexp + - match: '\\[1-9][0-9]?' + scope: keyword.other.back-reference.regexp + - match: '[?+*][?+]?|\{(\d+,\d+|\d+,|,\d+|\d+)\}\??' + scope: keyword.operator.quantifier.regexp + - match: \| + scope: keyword.operator.or.regexp + - match: '\(\?\#' + scope: punctuation.definition.comment.begin.regexp + push: + - meta_scope: comment.block.regexp + - match: \) + scope: punctuation.definition.comment.end.regexp + pop: true + - match: '\(\?[iLmsux]+\)' + scope: keyword.other.option-toggle.regexp + - match: '(\()(\?P=([a-zA-Z_][a-zA-Z_0-9]*\w*))(\))' + scope: keyword.other.back-reference.named.regexp + - match: (\()((\?=)|(\?!)|(\?<=)|(\?<!)) + captures: + 1: punctuation.definition.group.begin.regexp + 2: constant.other.assertion.regexp + 3: meta.assertion.look-ahead.regexp + 4: meta.assertion.negative-look-ahead.regexp + 5: meta.assertion.look-behind.regexp + 6: meta.assertion.negative-look-behind.regexp + push: + - meta_scope: meta.group.assertion.regexp + - match: \) + scope: punctuation.definition.group.end.regexp + pop: true + - include: main + - match: '(\()(\?\(([1-9][0-9]?|[a-zA-Z_][a-zA-Z_0-9]*)\))' + comment: + We can make this more sophisticated to match the | character that separates + yes-pattern from no-pattern, but it's not really necessary. + captures: + 1: punctuation.definition.group.begin.regexp + 2: punctuation.definition.group.assertion.conditional.regexp + 3: variable.other.back-reference.regexp + push: + - meta_scope: meta.group.assertion.conditional.regexp + - match: \) + scope: punctuation.definition.group.end.regexp + pop: true + - include: main + - match: '(\()((\?P<)([a-z]\w*)(>)|(\?:))?' + captures: + 1: punctuation.definition.group.begin.regexp + 3: punctuation.definition.group.capture.regexp + 4: entity.name.other.group.regexp + 5: punctuation.definition.group.capture.regexp + 6: punctuation.definition.group.no-capture.regexp + push: + - meta_scope: meta.group.regexp + - match: \) + scope: punctuation.definition.group.end.regexp + pop: true + - include: main + - include: character-class + character-class: + - match: '\\[wWsSdDhH]|\.' + scope: constant.character.character-class.regexp + - match: \\. + scope: constant.character.escape.backslash.regexp + - match: '(\[)(\^)?' + captures: + 1: punctuation.definition.character-class.begin.regexp + 2: keyword.operator.negation.regexp + push: + - meta_scope: constant.other.character-class.set.regexp + - match: \] + scope: punctuation.definition.character-class.end.regexp + pop: true + - include: character-class + - match: '((\\.)|.)\-((\\.)|[^\]])' + scope: constant.other.character-class.range.regexp + captures: + 2: constant.character.escape.backslash.regexp + 4: constant.character.escape.backslash.regexp diff --git a/syntaxes/Python/Snippets/New-Class.sublime-snippet b/syntaxes/Python/Snippets/New-Class.sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <content><![CDATA[class ${1:ClassName}(${2:object}): + ${3/.+/"""/}${3:docstring for $1}${3/.+/"""\n/}${3/.+/\t/}def __init__(self${4/([^,])?(.*)/(?1:, )/}${4:arg}): + ${5:super($1, self).__init__()} +${4/(\A\s*,\s*\Z)|,?\s*([A-Za-z_][a-zA-Z0-9_]*)\s*(=[^,]*)?(,\s*|$)/(?2:\t\tself.$2 = $2\n)/g} $0]]></content> + <tabTrigger>class</tabTrigger> + <scope>source.python</scope> + <description>New Class</description> +</snippet> diff --git a/syntaxes/Python/Snippets/New-Property.sublime-snippet b/syntaxes/Python/Snippets/New-Property.sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <content><![CDATA[property +def ${1:foo}(self): + return self.${2:_$1} +$0]]></content> + <tabTrigger>property</tabTrigger> + <scope>source.python meta.annotation</scope> + <description>New Property</description> +</snippet> diff --git a/syntaxes/Python/Snippets/Try-Except-Else-Finally.sublime-snippet b/syntaxes/Python/Snippets/Try-Except-Else-Finally.sublime-snippet @@ -0,0 +1,13 @@ +<snippet> + <content><![CDATA[try: + ${1:pass} +except${2: ${3:Exception} as ${4:e}}: + ${5:raise} +else: + ${6:pass} +finally: + ${7:pass}]]></content> + <tabTrigger>try</tabTrigger> + <scope>source.python</scope> + <description>Try/Except/Else/Finally</description> +</snippet> diff --git a/syntaxes/Python/Snippets/Try-Except-Else.sublime-snippet b/syntaxes/Python/Snippets/Try-Except-Else.sublime-snippet @@ -0,0 +1,11 @@ +<snippet> + <content><![CDATA[try: + ${1:pass} +except ${2:Exception} as ${3:e}: + ${4:raise $3} +else: + ${5:pass}]]></content> + <tabTrigger>try</tabTrigger> + <scope>source.python</scope> + <description>Try/Except/Else</description> +</snippet> diff --git a/syntaxes/Python/Snippets/Try-Except-Finally.sublime-snippet b/syntaxes/Python/Snippets/Try-Except-Finally.sublime-snippet @@ -0,0 +1,11 @@ +<snippet> + <content><![CDATA[try: + ${1:pass} +except ${2:Exception} as ${3:e}: + ${4:raise $3} +finally: + ${5:pass}]]></content> + <tabTrigger>try</tabTrigger> + <scope>source.python</scope> + <description>Try/Except/Finally</description> +</snippet> diff --git a/syntaxes/Python/Snippets/Try-Except.sublime-snippet b/syntaxes/Python/Snippets/Try-Except.sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <content><![CDATA[try: + ${1:pass} +except ${2:Exception} as ${3:e}: + ${4:raise $3}]]></content> + <tabTrigger>try</tabTrigger> + <scope>source.python</scope> + <description>Try/Except</description> +</snippet> diff --git a/syntaxes/Python/Snippets/__magic__.sublime-snippet b/syntaxes/Python/Snippets/__magic__.sublime-snippet @@ -0,0 +1,6 @@ +<snippet> + <content><![CDATA[__${1:init}__]]></content> + <tabTrigger>__</tabTrigger> + <scope>source.python</scope> + <description>__magic__</description> +</snippet> diff --git a/syntaxes/Python/Snippets/for.sublime-snippet b/syntaxes/Python/Snippets/for.sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <tabTrigger>for</tabTrigger> + <scope>source.python</scope> + <description>For Loop</description> + <content><![CDATA[ +for ${1:x} in ${2:xrange(1,10)}: + ${0:pass} +]]></content> +</snippet> diff --git a/syntaxes/Python/Snippets/function.sublime-snippet b/syntaxes/Python/Snippets/function.sublime-snippet @@ -0,0 +1,7 @@ +<snippet> + <tabTrigger>def</tabTrigger> + <scope>source.python</scope> + <description>Function</description> + <content><![CDATA[def ${1:function}($2): + ${0:pass}]]></content> +</snippet> diff --git a/syntaxes/Python/Snippets/if-__name__-==-'__main__'.sublime-snippet b/syntaxes/Python/Snippets/if-__name__-==-'__main__'.sublime-snippet @@ -0,0 +1,7 @@ +<snippet> + <content><![CDATA[if __name__ == '__main__': + ${1:main()}$0]]></content> + <tabTrigger>ifmain</tabTrigger> + <scope>source.python</scope> + <description>if __name__ == '__main__'</description> +</snippet> diff --git a/syntaxes/Python/Snippets/if.sublime-snippet b/syntaxes/Python/Snippets/if.sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <tabTrigger>if</tabTrigger> + <scope>source.python</scope> + <description>If Condition</description> + <content><![CDATA[ +if ${1:$SELECTION}: + ${0:pass} +]]></content> +</snippet> diff --git a/syntaxes/Python/Snippets/method.sublime-snippet b/syntaxes/Python/Snippets/method.sublime-snippet @@ -0,0 +1,7 @@ +<snippet> + <tabTrigger>defs</tabTrigger> + <scope>source.python</scope> + <description>Method</description> + <content><![CDATA[def ${1:function}(self${2}): + ${0:pass}]]></content> +</snippet> diff --git a/syntaxes/Python/Snippets/while.sublime-snippet b/syntaxes/Python/Snippets/while.sublime-snippet @@ -0,0 +1,9 @@ +<snippet> + <tabTrigger>while</tabTrigger> + <scope>source.python</scope> + <description>While Loop</description> + <content><![CDATA[ +while ${1:$SELECTION}: + ${0:pass} +]]></content> +</snippet> diff --git a/syntaxes/Python/Symbol Index.tmPreferences b/syntaxes/Python/Symbol Index.tmPreferences @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol Index</string> + <key>scope</key> + <string>source.python entity.name.function, source.python entity.name.class</string> + <key>settings</key> + <dict> + <key>showInIndexedSymbolList</key> + <integer>1</integer> + </dict> +</dict> +</plist> diff --git a/syntaxes/Python/Symbol List.tmPreferences b/syntaxes/Python/Symbol List.tmPreferences @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Symbol List</string> + <key>scope</key> + <string>source.python meta.function - meta.function.inline, source.python meta.class</string> + <key>settings</key> + <dict> + <key>showInSymbolList</key> + <integer>1</integer> + <key>symbolTransformation</key> + <string> + s/class\s+([[:alpha:]_][[:alnum:]_]*.+?\)?)(\:|$)/$1/g; + s/(?:async\s+)?def\s+([[:alpha:]_][[:alnum:]_]*).*/$1\(…\))/g; + </string> + </dict> +</dict> +</plist> diff --git a/syntaxes/Python/syntax_test_python.py b/syntaxes/Python/syntax_test_python.py @@ -0,0 +1,1459 @@ +# SYNTAX TEST "Packages/Python/Python.sublime-syntax" +# <- source.python comment.line.number-sign punctuation.definition.comment + +r"""This is a syntax test file. +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation +#^^^ punctuation.definition.comment.begin +# <- storage.type.string + +And this right here, where we're writing in, is a docstring. +""" + +ur"""Raw docstring \""" +# <- storage.type.string.python +# ^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation.python +# ^^^ punctuation.definition.comment.end.python + +"""Normal docstring \"""" +# ^^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation.python +# ^^ constant.character.escape.python +# ^^^ punctuation.definition.comment.end.python + +debug = False +""" +This is a variable docstring, as supported by sphinx and epydoc +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation +""" + + +################## +# Imports +################## + +import sys # comment +#^^^^^ keyword.control.import +# ^ comment +from os import path, chdir # comment +#^^^ keyword.control.import.from +# ^^^^^^ keyword.control.import +# ^ punctuation.separator.import-list +# ^ comment +from . import module +# ^ keyword.control.import.relative.python +# ^^^^^^ keyword.control.import +from .import module # yes, this is actually legit +# ^ keyword.control.import.relative.python +# ^^^^^^ keyword.control.import.python +from collections.abc import Iterable +# ^^^^^^ keyword.control.import +from a.b.c.else import module +# ^^^^ invalid.illegal.name.python +# ^^^^^^ keyword.control.import +from .while import module +# ^^^^^ invalid.illegal.name.python +# ^^^^^^ keyword.control.import +from .index import module +# ^^^^^ - invalid +from \ + os \ + import \ + path +# ^^^^ meta.statement.import +from sys import (version, # comment +#^^^^^^^^^^^^^^^^^^^^^^^^ meta.statement.import +# ^ punctuation.section.import-list.begin +# ^ comment + version_info, . ) # comment +# ^^^^^^^^^^^^^ meta.statement.import +# ^ invalid.illegal.name.import +# ^ punctuation.section.import-list.end +# ^ comment +import path from os +# ^^^^ invalid.illegal.name +from .sub import * +# ^ constant.language.import-all.python +import a as b +# ^^ keyword.control.import.as.python +from a import b as c, d as e +# ^^ keyword.control.import.as.python +# ^^ keyword.control.import.as.python +from a import (b as c) +# ^^ keyword.control.import.as.python + +import re; re.compile(r'') +# ^^^^^^^^^^^^^^^^^ - meta.statement.import +# ^ punctuation.terminator.statement + +from unicode.__init__ . 123 import unicode as unicode +# ^^^^^^^^^^^^^^^^^^^^^^ meta.import-source.python meta.import-path.python +# ^^^^^^^ meta.import-name.python - support +# ^ punctuation.accessor.dot.python +# ^^^^^^^^ meta.import-name.python - support +# ^^^^^ invalid.illegal.name.python +# ^^^^^^^ support.type.python +# ^^^^^^^ support.type.python + +import .str +# ^ invalid.illegal.unexpected-relative-import.python +# ^^^ support.type.python + +import str +# ^^^ support.type.python + + +################## +# Identifiers +################## + +identifier +#^^^^^^^^^ meta.qualified-name meta.generic-name + +class +#^^^^ storage.type.class keyword.declaration.class.python +def +#^^ storage.type.function keyword.declaration.function.python + +# async and await are still recognized as valid identifiers unless in an "async" block +async +#^^^^ - invalid.illegal.name + +__all__ +#^^^^^^ meta.qualified-name support.variable.magic - meta.generic-name +__file__ +#^^^^^^^ support.variable.magic +__missing__ +#^^^^^^^^^^ support.function.magic +__bool__ abc.__nonzero__ +#^^^^^^^ support.function.magic +# ^^^^^^^^^^^ support.function.magic + +TypeError module.TypeError +#^^^^^^^^ support.type.exception +# ^^^^^^^^^ - support + +open.open.open +# ^^^^^^^^^ - support + +... Ellipsis __debug__ +#^^ constant.language.python +# ^^^^^^^^ constant.language.python +# ^^^^^^^^^ constant.language.python + +CONSTANT._13_ +#^^^^^^^ meta.qualified-name.python variable.other.constant.python +# ^^^^ - variable.other.constant + + _A_B A1 +#^^^^ - variable.other.constant +# ^^ - variable.other.constant + +some.NO +# ^^ meta.qualified-name.python variable.other.constant.python + +NO_SWEAT NO AA1 +# <- meta.qualified-name.python variable.other.constant.python +# ^^ variable.other.constant +# ^^^ variable.other.constant + +_ self +# <- variable.language.python +# ^^^^ variable.language.python + + +################## +# Function Calls +################## + +identifier() +#^^^^^^^^^^^ meta.function-call +#^^^^^^^^^ meta.qualified-name variable.function +# ^ punctuation.section.arguments.begin +# ^ punctuation.section.arguments.end + +IDENTIFIER() +#^^^^^^^^^ meta.qualified-name variable.function - variable.other.constant + +dotted . identifier(12, True) +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call - meta.function-call meta.function-call +# ^^^^^^^^^^ meta.function-call.arguments +#^^^^^^^^^^^^^^^^^^ meta.qualified-name +#^^^^^^ - variable.function +# ^ punctuation.accessor.dot +# ^^^^^^^^^^ variable.function + +open.__new__(12, \ +#^^^^^^^^^^^^^^^^^^^^^ meta.function-call +#^^^ support.function.builtin +# ^ punctuation.accessor.dot +# ^^^^^^^ variable.function support.function.magic +# ^ punctuation.separator.continuation.line.python + True) + +TypeError() +#^^^^^^^^ support.type.exception +# +module.TypeError() +#^^^^^^^^^^^^^^^ meta.function-call +# ^^^^^^^^^ variable.function - support + +open.open.open() +#^^^ support.function.builtin +# ^ punctuation.accessor.dot +# ^^^^^^^^^ - support +# ^^^^ variable.function + +call(2**10, *range(10), **dict(), * *{}, ***a) +# ^^ keyword.operator.arithmetic +# ^ keyword.operator.unpacking.sequence.python +# ^^ keyword.operator.unpacking.mapping.python +# ^ keyword.operator.unpacking.sequence.python +# ^ - keyword.operator.unpacking +# ^^^ invalid.illegal.syntax.python + +if p.type not in ('NUMBER', 'INTEGER'): +# ^^ keyword.operator - meta.function-call invalid + +call(from='no', from_='yes') +#^^^^^^^^^^^^^^ meta.function-call +# ^^^^ invalid.illegal.name +# ^ keyword.operator.assignment +# ^^^^ string + +################## +# Expressions +################## + +def _(): + yield from +# ^^^^^ keyword.control.flow.yield +# ^^^^ keyword.control.flow.yield-from + + yield fromsomething +# ^^^^ - keyword + + a if b else c +# ^^ keyword.control.conditional.if +# ^^^^ keyword.control.conditional.else + + c = lambda: pass +# ^^^^^^^^^^^^ meta.function.inline +# ^^^^^^ storage.type.function.inline keyword.declaration.function.inline.python +# ^ punctuation.section.function.begin +# ^^^^ invalid.illegal.name.python + + _(lambda x, y: 10) +# ^^^^^^^^^^^^^^^ meta.function.inline +# ^^^^^^ keyword.declaration.function.inline.python +# ^^^^^ meta.function.inline.parameters +# ^ variable.parameter +# ^ punctuation.separator.parameters +# ^ variable.parameter +# ^^ constant.numeric + + lambda \ + a, \ + b=2: True +# ^^^^^^^^^ meta.function.inline +# ^ keyword.operator.assignment +# ^ punctuation.section.function.begin +# ^^^^^ meta.function.inline.body +# ^^^^ constant.language.python + + lambda as, in=2: 0 +# ^^ invalid.illegal.name +# ^^ invalid.illegal.name + + lambda *a, **kwa, ab*, * *: (a, kwa) +# ^ keyword.operator.unpacking.sequence.python +# ^ variable.parameter.python +# ^^^ variable.parameter.python +# ^^ keyword.operator.unpacking.mapping.python +# ^ invalid.illegal.expected-parameter.python +# ^ invalid.illegal.expected-parameter.python + + lambda x +# ^^^^^^ storage.type.function.inline keyword.declaration.function.inline.python + + lambda (x, y): 0 +# ^^^^^^^^^^^^^^^^ meta.function.inline +# ^^^^^^^^ meta.function.inline.parameters.python +# ^^ meta.function.inline.body.python +# ^^^^^^ meta.group.python +# ^ punctuation.section.group.begin.python +# ^ variable.parameter.python +# ^ punctuation.separator.parameters.python +# ^ variable.parameter.python +# ^ punctuation.section.group.end.python +# ^ punctuation.section.function.begin.python + lambda ( +# ^^^^^^^^^ meta.function.inline.python +# ^^^ meta.function.inline.parameters.python +# ^^ meta.group.python +# ^ punctuation.section.group.begin.python + x, +# ^^^^ meta.function.inline.parameters.python meta.group.python +# ^ variable.parameter.python +# ^ punctuation.separator.parameters.python + y +# ^^^^ meta.function.inline.parameters.python meta.group.python +# ^ variable.parameter.python + ): +#^^^^ meta.function.inline.parameters.python meta.group.python +# ^ punctuation.section.group.end.python +# ^ punctuation.section.function.begin.python + pass +# ^^^^ keyword.control.flow.pass.python + + ( 3 - 6 \ +# ^^^^^^^^^ meta.group.python +# ^ punctuation.section.group.begin.python +# ^ constant.numeric.integer.decimal.python +# ^ keyword.operator.arithmetic.python +# ^ constant.numeric.integer.decimal.python +# ^ punctuation.separator.continuation.line.python + ) +#^^^^^ meta.group.python + +################## +# Compound expressions +################## + +myobj.method().attribute +#^^^^^^^^^^^^^ meta.function-call +# ^ punctuation.accessor.dot +# ^^^^^^ variable.function +# ^ punctuation.accessor.dot + +'foo'. upper() +# ^^^^^^^^^ meta.function-call +# ^ punctuation.accessor.dot +# ^^^^^ variable.function + +func()(1, 2) +# <- meta.function-call +#^^^^^^^^^^^ meta.function-call +#^^^^^^^^^^^ - meta.function-call meta.function-call + +myobj[1](True) +#^^^^^^^ meta.item-access +# ^ punctuation.section.brackets.begin - meta.item-access.arguments +# ^ meta.item-access.arguments +# ^ punctuation.section.brackets.end - meta.item-access.arguments +# ^^^^^^ meta.function-call + +myobj[1][2](0) +#^^^^^^^^^^ meta.item-access +# ^ punctuation.section.brackets.begin - meta.item-access.arguments +# ^ meta.item-access.arguments +# ^ punctuation.section.brackets.end - meta.item-access.arguments +# ^ punctuation.section.brackets.begin - meta.item-access.arguments +# ^ meta.item-access.arguments +# ^ punctuation.section.brackets.end - meta.item-access.arguments +# ^^^ meta.function-call + +range(20)[10:2:-2] +# ^ punctuation.separator.slice +# ^ punctuation.separator.slice + +"string"[12] +# ^^^^ meta.item-access - meta.structure + +"string".upper() +# ^^^^^^^^ meta.function-call + +(i for i in range(10))[5] +# ^^^ meta.item-access - meta.structure + +[1, 2, 3][2] +#^^^^^^^^ meta.sequence +# ^^^ meta.item-access - meta.structure + +{True: False}.get(True) +# ^^^^^^^^^^ meta.function-call + +1[12] +#^^^^ - meta.item-access + + +################## +# print & exec +################## + +def _(): + print (file=None) +# ^^^^^ support.function.builtin - keyword + print . __class__ +# ^^^^^ support.function.builtin - keyword + print "keyword" +# ^^^^^ keyword.other.print + print __init__ +# ^^^^^ keyword.other.print +# + exec 123 +# ^^^^ keyword + exec ("print('ok')") +# ^^^^ support.function.builtin - keyword + callback(print , print +# ^^^^^ - keyword +# ^ punctuation.separator.arguments +# ^^^^^ - keyword + , print) +# ^^^^^ - keyword + + some \ + print \ +# ^^^^^ keyword.other.print + + func( + print +# ^^^^^ support.function.builtin - keyword + ) + + print +# ^^^^^ keyword.other.print + + +################## +# Block statements +################## +def _(): + for +# ^^^ keyword.control.loop.for + b = c in d +# ^^ keyword.operator.logical - keyword.control.loop.for.in + + for \ + a \ + in \ + b: +# ^^ meta.statement.loop.for +# ^ punctuation.section.block.loop.for.python + + async for i in myfunc(): +# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.statement.loop.for +# ^^^^^ storage.modifier.async +# ^^^ keyword.control.loop.for +# ^^ keyword.control.loop.for.in +# ^ punctuation.section.block.loop.for + pass + + for i: +# ^ invalid.illegal.missing-in + + a for b in c: # TODO make this invalid (for not at beginning of line) + + + something as nothing: +# ^^ invalid.illegal.name + + with \ + open() \ + as \ + x: +# ^^ meta.statement.with + + with open(), open() as x, open() as y: +# ^^^^ keyword.control.flow.with +# ^^^^ support.function +# ^ punctuation.separator.with-resources +# ^^ keyword.control.flow.with.as +# ^ punctuation.separator.with-resources +# ^^^^ support.function +# ^^ keyword.control.flow.with.as + + with captured() as (out, err): +# ^^^^ keyword.control.flow.with +# ^^^^^^^^ variable.function +# ^ punctuation.section.arguments.begin +# ^ punctuation.section.arguments.end +# ^^ keyword.control.flow.with.as +# ^ punctuation.section.group.begin +# ^^^ meta.generic-name +# ^ punctuation.separator.tuple +# ^^^ meta.generic-name +# ^ punctuation.section.group.end +# ^ punctuation.section.block.with + + with captured() \ + as ( +# ^ punctuation.section.group.begin + out, +# ^^^ meta.generic-name +# ^ punctuation.separator.tuple + err +# ^^^ meta.generic-name + ): +# ^ punctuation.section.group.end +# ^ punctuation.section.block.with + + with captured() as [out, err]: +# ^^^^ keyword.control.flow.with +# ^^^^^^^^ variable.function +# ^ punctuation.section.arguments.begin +# ^ punctuation.section.arguments.end +# ^^ keyword.control.flow.with.as +# ^ punctuation.section.sequence.begin +# ^^^ meta.generic-name +# ^ punctuation.separator.sequence +# ^^^ meta.generic-name +# ^ punctuation.section.sequence.end +# ^ punctuation.section.block.with + + with captured() \ + as [ +# ^ punctuation.section.sequence.begin + out, +# ^^^ meta.generic-name +# ^ punctuation.separator.sequence + err +# ^^^ meta.generic-name + ]: +# ^ punctuation.section.sequence.end +# ^ punctuation.section.block.with + + async with context_manager() as c: +# ^^^^^ storage.modifier.async +# ^^^^ keyword.control.flow.with +# ^^ keyword.control.flow.with.as +# ^ punctuation.section.block.with + await something() +# ^^^^^ keyword.other.await + + assert foo == bar +# ^^^^^^ keyword.control.flow.assert.python + + try: +# ^^^^ meta.statement.exception.try.python +# ^^^ keyword.control.exception.try.python +# ^ punctuation.section.block.exception.try.python + raise +# ^^^^^ meta.statement.raise.python keyword.control.flow.raise.python + except Exception as x: +# ^^^^^^^^^^^^^^^^^^^^^^ meta.statement.exception.catch.python - meta.statement.exception.catch.python meta.statement.exception.catch.python +# ^^^^^^ keyword.control.exception.catch.python +# ^^^^^^^^^ support.type.exception.python +# ^^ keyword.control.exception.catch.as.python +# ^ meta.generic-name.python +# ^ punctuation.section.block.exception.catch.python + pass + finally : +# ^^^^^^^^^ meta.statement.exception.finally.python +# ^^^^^^^ keyword.control.exception.finally.python +# ^ punctuation.section.block.exception.finally.python + try_except_raise: +# ^^^ - keyword + + while ( +# ^^^^^^^^ meta.statement.loop.while.python +# ^^^^^ keyword.control.loop.while.python +# ^ meta.statement.loop.while.python meta.group.python punctuation.section.group.begin.python + a is b +# ^^^^^^ meta.statement.loop.while.python +# ^^ keyword.operator.logical.python + ): +# ^ meta.statement.loop.while.python punctuation.section.block.loop.while.python + sleep() + if a: + break +# ^^^^^ keyword.control.flow.break.python + elif b: + continue +# ^^^^^^^^ keyword.control.flow.continue.python + + if 213 is 231: +# ^^^^^^^^^^^^^^ meta.statement.conditional.if.python +# ^^ keyword.control.conditional.if.python +# ^^^ constant.numeric.integer.decimal.python +# ^^ keyword.operator.logical.python +# ^ punctuation.section.block.conditional.if.python + pass + elif: +# ^^^^^ meta.statement.conditional.elseif.python +# ^ punctuation.section.block.conditional.elseif.python + pass + elif False : +# ^^^^^^^^^^^^ meta.statement.conditional.elseif.python +# ^^^^^ constant.language +# ^ punctuation.section.block.conditional.elseif.python + pass + else : +# ^^^^^^^ meta.statement.conditional.else.python +# ^ punctuation.section.block.conditional.else.python + pass + + if \ + True: +# ^^^^^ meta.statement.conditional.if.python +# ^^^^ constant.language.python +# ^ punctuation.section.block.conditional.if.python +# + + # verify that keywords also work when they are bare (useful when typing) + for +# ^^^ keyword.control.loop.for.python + with +# ^^^^ keyword.control.flow.with.python + if +# ^^ keyword.control.conditional.if.python + finally +# ^^^^^^^ keyword.control.exception.finally.python + else +# ^^^^ keyword.control.conditional.else.python + while +# ^^^^^ keyword.control.loop.while.python + return +# ^^^^^^ keyword.control.flow.return.python + raise +# ^^^^^ keyword.control.flow.raise.python + + +################## +# Function definitions +################## + +def abc(): + global from, for, variable, . +# ^^^^^^ storage.modifier.global +# ^^^^ invalid.illegal.name +# ^^^ invalid.illegal.name +# ^ invalid.illegal.name.storage + + +def my_func(param1, # Multi-line function definition +# ^ punctuation.separator.parameters +# ^ comment.line.number-sign + # This is defaulted +# ^ comment.line.number-sign + param2='#1' \ +# ^ punctuation.separator.continuation.line.python +): +# <- punctuation.section.parameters.end + print('Hi!') + + +def func(from='me'): +# ^^^^ invalid.illegal.name + pass + +def type_annotations(param1: int, param2: MyType, param3: max(2, 3), param4: "string" = "default") -> int: +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters +# ^^^^^^ meta.function.annotation.return +# ^ - meta.function meta.function.parameters +# ^^^^^^ variable.parameter +# ^^^^^ meta.function.parameters.annotation +# ^ punctuation.separator.annotation +# ^^^ support.type +# ^ punctuation.separator.parameters +# ^^^^^^ variable.parameter +# ^ punctuation.separator.annotation +# ^ punctuation.separator.parameters +# ^^^^^^ variable.parameter +# ^ punctuation.separator.annotation +# ^^^^^^^^^ meta.function-call +# ^ punctuation.section.arguments.begin +# ^ constant.numeric +# ^ constant.numeric +# ^ punctuation.section.arguments.end +# ^ punctuation.separator.parameters +# ^^^^^^ variable.parameter +# ^ punctuation.separator.annotation +# ^^^^^^^^ string.quoted.double +# ^^^^^^^^^^^ meta.function.parameters.default-value +# ^ keyword.operator.assignment +# ^^^^^^^^^ string.quoted.double +# ^ punctuation.section.parameters.end +# ^^ punctuation.separator.annotation +# ^^^ support.type +# ^ punctuation.section.function.begin + pass + + +async def coroutine(param1): +#^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function +# ^^^^^^^^ meta.function.parameters - meta.function meta.function +# <- storage.modifier.async +# ^ storage.type +# ^ entity.name.function + pass + +def func(*args, other_arg=2**10, **kwargs): +# ^ keyword.operator.unpacking.sequence.python +# ^^ keyword.operator.arithmetic.python +# ^^ keyword.operator.unpacking.mapping.python + pass + +def func( + *args, +# ^ keyword.operator.unpacking.sequence + other_arg=2**10, +# ^^ keyword.operator.arithmetic + **kwargs +# ^^ keyword.operator.unpacking.mapping +): + pass + +def func(args, (x, y)=(0,0)): +# ^^^^^^^^^^^^^ meta.function.parameters.python +# ^^^^^^ meta.function.parameters.default-value.python +# ^ meta.function.parameters.python +# ^^^^^^ meta.group.python +# ^ - meta.group.python +# ^^^^^ meta.sequence.tuple.python +# ^ - meta.group.python +# ^ punctuation.section.parameters.begin.python +# ^ punctuation.separator.parameters.python +# ^ punctuation.section.group.begin.python +# ^ variable.parameter.python +# ^ punctuation.separator.parameters.python +# ^ variable.parameter.python +# ^ punctuation.section.group.end.python +# ^ keyword.operator.assignment.python +# ^ punctuation.section.sequence.begin.python +# ^ constant.numeric.integer.decimal.python +# ^ punctuation.separator.sequence.python +# ^ constant.numeric.integer.decimal.python +# ^ punctuation.section.sequence.end.python +# ^ punctuation.section.parameters.end.python + pass + +def foo(arg: int = 0, (x: float, y=20) = (0.0, "default")): +# ^^^^^^^^^^^^^^^^ meta.group.python +# ^^^ - meta.group.python +# ^^^^^^^^^^^^^^^^ meta.sequence.tuple.python +# ^ punctuation.section.group.begin.python +# ^ variable.parameter.python +# ^^^^^^^ invalid.illegal.annotation.python +# ^ punctuation.separator.parameters.python +# ^ variable.parameter.python +# ^^^ invalid.illegal.default-value.python +# ^ punctuation.section.group.end.python +# ^ keyword.operator.assignment.python +# ^ punctuation.section.sequence.begin.python +# ^ punctuation.section.sequence.end.python + pass + +def name(p1, p2=None, /, p_or_kw=None, *, kw): pass +# ^ storage.modifier.positional-args-only.python +# ^ punctuation.separator.parameters.python +# ^ keyword.operator.unpacking.sequence.python +def name(p1, p2, /): pass +# ^ storage.modifier.positional-args-only.python +# ^ punctuation.section.parameters.end.python + + +################## +# Class definitions +################## + +class MyClass(): +#^^^^^^^^^^^^^^^ meta.class +# ^^ meta.class.inheritance +# ^ punctuation.section.class.begin + def my_func(self, param1, # Multi-line function definition +# ^ comment.line.number-sign + # This is defaulted +# ^ comment.line.number-sign + param2='#1'): +# ^ punctuation.section.parameters.end + print('Hi!') + + +class UnicødeIdentifier(): +# ^^^^^^^^^^^^^^^^^ entity.name.class + def résumé(): +# ^^^^^^ entity.name.function + """ +# ^^^ punctuation.definition.comment.begin + A function-level docstring +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.documentation.python + """ +# ^^^ punctuation.definition.comment.end + + yield from range(100) +# ^^^^^ keyword.control.flow +# ^ - keyword +# ^^^^ keyword.control.flow + + +class MyClass(Inherited, \ +# ^^^^^^^ entity.name.class +# ^^^^^^^^^ entity.other.inherited-class +# ^ punctuation.separator.inheritance +# ^ punctuation.separator.continuation.line.python + module . Inherited2, metaclass=ABCMeta): +# ^^^^^^^^^^^^^^^^^^^ entity.other.inherited-class +# ^ punctuation.accessor.dot +# ^ punctuation.separator.inheritance +# ^^^^^^^^^ variable.parameter.class-inheritance +# ^ keyword.operator.assignment + ur''' +# ^^ storage.type.string + This is a test of docstrings + ''' +# ^^^ comment.block.documentation.python + pass + + +class Unterminated(Inherited: +# ^ invalid.illegal + + +################## +# Decorators +################## + +@ normal . decorator +# <- meta.annotation punctuation.definition.annotation +#^^^^^^^^^^^^^^^^^^^ meta.annotation +# ^^^^^^^^^^^^^^^^^^ meta.qualified-name +# ^^^^^^ meta.generic-name - variable.annotation +# ^^^^^^^^^ variable.annotation +# ^ punctuation.accessor.dot - variable +# ^ - meta.annotation +class Class(): + + @functools.wraps(method, 12, kwarg=None)# comment +#^^^ - meta.annotation +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.annotation - meta.annotation meta.annotation +# ^^^^^^^^^^^^^^^^^^^^^^ meta.annotation.arguments +# ^ punctuation.definition.annotation +# ^^^^^^^^^^^^^^^^ meta.annotation.function +# ^^^^^^^^^^^^^^^ meta.qualified-name +# ^^^^^^^^^ meta.generic-name - variable.annotation +# ^ punctuation.accessor.dot +# ^^^^^ variable.annotation.function meta.generic-name +# ^ punctuation.section.arguments.begin +# ^ punctuation.separator.arguments +# ^^ constant.numeric +# ^^^^^ variable.parameter +# ^ keyword.operator +# ^^^^ constant.language +# ^ punctuation.separator.arguments +# ^ meta.annotation.function punctuation.section.arguments.end +# ^^^^^^^^^ comment - meta.annotation + def wrapper(self): + return self.__class__(method) + + @deco #comment +#^^^ - meta.annotation +# ^^^^^ meta.annotation +# ^^^^ meta.qualified-name variable.annotation +# ^^ - meta.annotation +# ^^^^^^^^ comment + + @staticmethod +# ^^^^^^^^^^^^^ meta.annotation +# ^^^^^^^^^^^^ variable.annotation support.function.builtin +# ^ - meta.annotation + + @not_a.staticmethod +# ^^^^^^^^^^^^^^^^^^^ meta.annotation +# ^^^^^^^^^^^^ variable.annotation - support +# ^ punctuation.accessor.dot + + @not_a.__init__() +# ^^^^^^^^^^^^^^^ meta.annotation +# ^^^^^^^^ variable.annotation support.function.magic +# ^ punctuation.accessor.dot + + @deco[4] +# ^ invalid.illegal.character + + @deco \ + . rator +# ^^^^^^^ meta.annotation +# ^ punctuation.accessor.dot + + @ deco \ + . rator() +# ^^^^^^^^^ meta.annotation.function +# ^^^^^ variable.annotation.function + + @ deco \ +# ^^^^ meta.qualified-name meta.generic-name - variable.annotation +# ^ punctuation.separator.continuation.line + + @deco \ + + def f(): pass +# ^^^ storage.type.function keyword.declaration.function.python - meta.decorator + + +class AClass: + # `def` immediately after a line-continued string within a class + x = "Type help() for interactive help, " \ + "or help(object) for help about object." + def __call__(self, *args, **kwds): +# ^^^ - invalid.illegal + pass + + +################## +# Collection literals and generators +################## + +mytuple = ("this", 'is', 4, tuple) +# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.sequence.tuple.python +# ^ punctuation.section.sequence.begin +# ^^^^^^ string.quoted.double +# ^ punctuation.separator.sequence +# ^^^^ string.quoted.single +# ^ punctuation.separator.sequence +# ^ constant.numeric +# ^ punctuation.separator.sequence +# ^^^^^ support.type +# ^ punctuation.section.sequence.end + +also_a_tuple = ()[-1] +# ^^ meta.sequence.tuple.empty.python +# ^^^^ meta.item-access + +not_a_tuple = (a = 2, b += 3) +# ^^^^^^^^^^^^^^^ - meta.sequence +# ^ - keyword +# ^ - keyword + +just_a_group = (1) +# ^^^ meta.group.python + +mylist = [] +# ^^ meta.sequence.list.empty.python +# ^ punctuation.section.sequence.begin +# ^ punctuation.section.sequence.end + +mylist = [1, "testing", ["sublist", True]] +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.sequence +# ^ punctuation.section.sequence.begin +# ^ constant.numeric +# ^ punctuation.separator.sequence +# ^^^^^^^^^ string.quoted.double +# ^ punctuation.separator +# ^^^^^^^^^^^^^^^^^ meta.sequence meta.sequence +# ^ punctuation.section.sequence.begin +# ^^^^^^^^^ string.quoted.double +# ^ punctuation.separator.sequence +# ^^^^ constant.language +# ^ punctuation.section.sequence.end +# ^ punctuation.section.sequence.end + +mydict = {} +# ^^ meta.mapping.empty.python +# ^ punctuation.section.mapping.begin +# ^ punctuation.section.mapping.end + +key2 = "my_key" +mydict = {"key": True, key2: (1, 2, [-1, -2]), ,} +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping - meta.mapping meta.mapping +# ^ punctuation.section.mapping.begin +# ^^^^^ meta.mapping.key.python string.quoted.double +# ^ punctuation.separator.mapping.key-value +# ^^^^ meta.mapping.value.python constant.language +# ^ punctuation.separator.mapping +# ^^^^ meta.mapping.key.python meta.qualified-name +# ^ punctuation.separator.mapping +# ^^^^^^^^^^^^^^^^ meta.sequence.tuple +# ^ punctuation.section.sequence.begin +# ^ constant.numeric +# ^ constant.numeric +# ^^^^^^^^ meta.sequence.list +# ^ punctuation.separator.sequence +# ^ punctuation.section.sequence.end +# ^ punctuation.separator.mapping.python +# ^ invalid.illegal.expected-colon.python +# ^ punctuation.section.mapping.end - meta.mapping.key + +mydict = { 'a' : xform, 'b' : form, 'c' : frm } +# ^ meta.mapping.python punctuation.separator.mapping.python +# ^ punctuation.separator.mapping.key-value.python + +myset = {"key", True, key2, [-1], {}:1} +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.set +# ^ punctuation.section.set.begin.python +# ^^^^^ string.quoted.double +# ^ punctuation.separator.set +# ^^^^ constant.language +# ^ punctuation.separator.set +# ^ punctuation.separator.set +# ^^^^ meta.sequence +# ^ constant.numeric +# ^ punctuation.separator.set +# ^^ meta.mapping.empty.python +# ^ invalid.illegal.colon-inside-set.python +# ^ punctuation.section.set.end.python + +mapping_or_set = { +# ^ meta.mapping-or-set.python punctuation.section.mapping-or-set.begin.python + 1: True +# ^ meta.mapping.key.python constant.numeric.integer.decimal.python +# ^ punctuation.separator.mapping.key-value.python +} +# <- meta.mapping.python punctuation.section.mapping.end.python + +complex_mapping = {(): "value"} +# ^^^ meta.mapping-or-set.python +# ^^^^^^^^^^ meta.mapping - meta.mapping-or-set + +more_complex_mapping = {**{1: 1}, 2: 2} +# ^ meta.mapping.python +# ^ meta.mapping.python punctuation.separator.mapping.python +# ^ meta.mapping.python punctuation.separator.mapping.key-value.python + +more_complex_set = { +# ^ meta.mapping-or-set.python + *{1}, 2: 2} +# ^ meta.set.python +# ^ meta.set.python punctuation.separator.set.python +# ^ meta.set.python invalid.illegal.colon-inside-set.python + +generator = (i for i in range(100)) +# ^^^^^^^^^^^^^^^^^^^^^^^ meta.group +# ^^^^^^^^ meta.expression.generator +# ^^^ keyword.control.loop.for.generator +# ^^ keyword.control.loop.for.in +list_ = [i for i in range(100)] +# ^^^^^^^^^^^^^^^^^^^^^^^ meta.sequence +# ^^^^^^^^ meta.expression.generator +# ^^^ keyword.control.loop.for.generator +# ^^ keyword.control.loop.for.in +set_ = {i for i in range(100)} +# ^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping-or-set +# ^^^^^^^^ meta.expression.generator +# ^^^ keyword.control.loop.for.generator +# ^^ keyword.control.loop.for.in +dict_ = {i: i for i in range(100)} +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping - meta.mapping meta.mapping +# ^ meta.mapping.key.python +# ^^^^^^^^^^^^^^^^^^^^^^^^ - meta.mapping.key.python +# ^ meta.mapping.value.python +# ^^^^^^^^^^^^^^^^^^^^^ - meta.mapping.value +# ^^^^^^^^ meta.expression.generator +# ^^^ keyword.control.loop.for.generator +# ^^ keyword.control.loop.for.in +list_ = [i for i in range(100) if i > 0 else -1] +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.sequence +# ^^^^^^^^ meta.expression.generator +# ^^ keyword.control.conditional.if +# ^^^^ keyword.control.conditional.else + +list2_ = [i in range(10) for i in range(100) if i in range(5, 15)] +# ^^ keyword.operator.logical +# ^^ keyword.control.loop.for.in +# ^^ keyword.operator.logical + +generator = ((k1, k2, v) for ((k1, k2), v) in xs) +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group.python +# ^^^^^^^^^^^ meta.sequence.tuple.python +# ^ punctuation.section.group.begin.python +# ^ punctuation.section.sequence.begin.python +# ^ punctuation.section.sequence.end.python +# ^^ punctuation.section.target-list.begin.python +# ^ punctuation.section.target-list.end.python +# ^ punctuation.section.target-list.end.python +# ^ punctuation.section.group.end.python + +list_ = [(k1, k2, v) for ((k1, k2), v) in xs] +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.sequence.list.python +# ^^^^^^^^^^^ meta.sequence.tuple.python +# ^ - meta.sequence.tuple.python - meta.expression.generator.python +# ^ punctuation.section.sequence.begin.python +# ^ punctuation.section.sequence.begin.python +# ^ punctuation.section.sequence.end.python +# ^^ punctuation.section.target-list.begin.python +# ^ punctuation.section.target-list.end.python +# ^ punctuation.section.target-list.end.python +# ^ punctuation.section.sequence.end.python + +dict_ = {k1: (k2, v) for ((k1, k2), v) in xs} +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping - meta.mapping meta.mapping +# ^ punctuation.section.mapping.begin.python +# ^^^^^^^ meta.sequence.tuple.python +# ^ punctuation.section.sequence.begin.python +# ^ punctuation.section.sequence.end.python +# ^^ punctuation.section.target-list.begin.python +# ^ punctuation.section.target-list.end.python +# ^ punctuation.section.target-list.end.python +# ^ punctuation.section.mapping.end.python + +list(i for i in generator) +# ^^^^^^^^ meta.expression.generator +list((i for i in generator), 123) +# ^^^^^^^^ meta.expression.generator +# ^^^^^^^ - meta.expression.generator +# ^ punctuation.separator.arguments + +_ = [m + for cls in self.__class__.mro() +# ^^^ keyword.control.loop.for.generator +# ^^ keyword.control.loop.for.in + for m in cls.__dict__] +# ^^^ keyword.control.loop.for.generator +# ^^ keyword.control.loop.for.in + +result = [i async for i in aiter() if i % 2] +# ^^^^^ storage.modifier.async +result = [await fun() for fun in funcs] +# ^^^^^ keyword.other.await.python + + +t = (*tuple(), *[1, 2], 3*1) +# ^^^^^^^^^^^^^^^^^^^^^^ meta.sequence.tuple.python +# ^ keyword.operator.arithmetic.python +# ^^^^^ support.type.python +# ^ keyword.operator.unpacking.sequence.python +# ^ keyword.operator.arithmetic.python + +l = [1 * 2, 2**10, *result] +# ^ keyword.operator.arithmetic.python +# ^^ keyword.operator.arithmetic.python +# ^ keyword.operator.unpacking.sequence.python + +l = [*l] +# ^ keyword.operator.unpacking.sequence.python + +d = {1: 3**4, **dict_} +# ^^ keyword.operator.arithmetic.python +# ^^ keyword.operator.unpacking.mapping.python + +d = {**d, **dict()} +# ^^^^^^^^^^^^^^^ meta.mapping.python +# ^^^ - meta.mapping.key +# ^^ keyword.operator.unpacking.mapping.python +# ^ meta.qualified-name.python +# ^ punctuation.separator.mapping.python +# ^^^^^^^^ - meta.mapping.key +# ^^ keyword.operator.unpacking.mapping.python +# ^^^^ support.type.python + +s = {*d, *set()} +# ^^^^^^^^^^^^ meta.set.python +# ^ keyword.operator.unpacking.sequence.python +# ^ meta.qualified-name.python +# ^ punctuation.separator.set.python +# ^ keyword.operator.unpacking.sequence.python +# ^^^ support.type.python + +generator = ( + i + for +# ^^^ keyword.control.loop.for.generator + i + in +# ^^ keyword.control.loop.for.in + range(100) +) + + +################## +# Exception handling +################## + +except Exception: +#^^^^^^^^^^^^^^^^ meta.statement.exception.catch +#^^^^^ keyword.control.exception.catch +# ^^^^^^^^^ support.type.exception +# ^ punctuation.section.block +except (KeyError, NameError) as e: +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.statement.exception.catch +#^^^^^ keyword.control.exception.catch +# ^^^^^^^^ support.type.exception +# ^ punctuation.separator.target-list +# ^^^^^^^^^ support.type.exception +# ^^ keyword.control.exception.catch.as +# ^ punctuation.section.block +except \ + StopIteration \ + as \ + err: +# ^^^^ meta.statement.exception.catch + +except StopIteration + as +# ^^ invalid.illegal.name - meta.statement.exception.catch + +except +#^^^^^ keyword.control.exception.catch + +raise +#^^^^ meta.statement.raise keyword.control.flow.raise +raise Ellipsis +#^^^^^^^^^^^^^ meta.statement.raise +#^^^^ keyword.control.flow.raise +# ^^^^^^^^ constant.language +raise KeyError() from z +#^^^^^^^^^^^^^^^^^^^^^^ meta.statement.raise +#^^^^ keyword.control.flow.raise +# ^^^^^^^^ support.type.exception +# ^^^^ keyword.control.flow.raise.from + + + +################## +# Stray braces +################## + +) +# <- invalid.illegal.stray.brace.round +] +# <- invalid.illegal.stray.brace.square +} +# <- invalid.illegal.stray.brace.curly + + + +################## +# Integral numbers +################## + +decimal = 1234567890 + 9876543210L + -1 + -42L * 0000 +# ^^^^^^^^^^ constant.numeric.integer.decimal.python +# ^^^^^^^^^^^ constant.numeric.integer.decimal.python +# ^ storage.type.numeric.python +# ^ keyword.operator.arithmetic.python - constant.numeric +# ^ keyword.operator.arithmetic.python - constant.numeric +# ^ storage.type.numeric.python +# ^^^^ constant.numeric.integer + +floating = 0.1 - .1 * 10e-20 - 0.0e2 % 2. +# ^^^ constant.numeric.float.decimal.python +# ^ punctuation.separator.decimal.python +# ^^ constant.numeric.float.decimal.python +# ^^^^^^ constant.numeric.float.decimal.python +# ^ punctuation.separator.decimal.python +# ^^^^^ constant.numeric.float.decimal.python +# ^^ constant.numeric.float.decimal.python +# ^ punctuation.separator.decimal.python + +binary = 0b1010011 | 0b0110110L +# ^^^^^^^^^ constant.numeric.integer.binary.python +# ^^ punctuation.definition.numeric.base.python +# ^^^^^^^^^^ constant.numeric.integer.binary.python +# ^^ punctuation.definition.numeric.base.python +# ^ storage.type.numeric.python + +octal = 0o755 ^ 0o644L +# ^^^^^ constant.numeric.integer.octal.python +# ^^ punctuation.definition.numeric.base.python +# ^ storage.type.numeric.python +# ^^^^^^ constant.numeric.integer.octal.python +# ^^ punctuation.definition.numeric.base.python + +old_style_octal = 010 + 007 - 012345670L +# ^^^ constant.numeric.integer.octal.python +# ^ punctuation.definition.numeric.base.python +# ^^^ constant.numeric.integer.octal.python +# ^ punctuation.definition.numeric.base.python +# ^^^^^^^^^^ constant.numeric.integer.octal.python +# ^ punctuation.definition.numeric.base.python +# ^ storage.type.numeric.python + +hexadecimal = 0x100af - 0XDEADF00L +# ^^^^^^^ constant.numeric.integer.hexadecimal.python +# ^^ punctuation.definition.numeric.base.python +# ^^^^^^^^^^ constant.numeric.integer.hexadecimal.python +# ^^ punctuation.definition.numeric.base.python +# ^ storage.type.numeric.python + +unintuitive = 0B101 + 0O101 + 10l +# ^^^^^ constant.numeric.integer.binary.python +# ^^ punctuation.definition.numeric.base.python +# ^^^^^ constant.numeric.integer.octal.python +# ^^ punctuation.definition.numeric.base.python +# ^^^ constant.numeric.integer.decimal.python +# ^ storage.type.numeric.python + +illegal = 1LL << 08 | 0b010203 | 0xAbraCadabra +# ^ - constant.numeric +# ^ - constant.numeric +# ^^^ - constant.numeric +# ^^^^^^^^^ - constant.numeric + +amount = 10_000_000.0_2e2_0 + .e2 + 2_2._2 +# ^^^^^^^^^^^^^^^^^^ constant.numeric.float.decimal.python +# ^ punctuation.separator.decimal.python +# ^^^ - constant +# ^^ - constant + +very_complex = 23_2.2e2_0J + 2_1j +# ^^^^^^^^^^^ constant.numeric.imaginary.decimal.python +# ^ punctuation.separator.decimal.python +# ^^^^ constant.numeric.imaginary.decimal.python +# ^ storage.type.numeric.python +# ^ storage.type.numeric.python + +addr = 0xCAFE_F00D +# ^^^^^^^^^^^ constant.numeric +# ^^ punctuation.definition.numeric.base.python + +flags = 0b_0011_1111_0100_1110 | 0b_1 & 0b_0_ +# ^^^^^^^^^^^^^^^^^^^^^^ constant.numeric +# ^^ punctuation.definition.numeric.base.python +# ^^^^ constant.numeric.integer.binary.python +# ^ - constant + +octoct = 0o_2 ^ 0o_ +# ^^^^ constant.numeric.integer.octal.python +# ^^^ - constant + +################## +# Operators +################## + +# This is to test the difference between the assignment operator (=) and +# the comparison operator (==) +foo = bar() +# ^ keyword.operator.assignment.python +foo == bar() +# ^^ keyword.operator.comparison.python +# +foo <<= bar +# ^^^ keyword.operator.assignment.augmented.python + +matrix @ multiplication +# ^ keyword.operator.matrix.python + +a @= b +# ^^ keyword.operator.assignment.augmented.python + + +################## +# Context "Fail Early" +################## + +# Pop contexts gracefully +def func(unclosed, parameters: if else + pass +# ^^^^ invalid.illegal.name + +# The following function should be matched as normal +# despite the above definition not being closed correctly +def another_func(): +#^^ -invalid + pass + + +x = [ +for x in y: + break +# ^^^^^ invalid.illegal.name +# ^ - meta.sequence + + +with open(x) as y: +#^^^ -invalid +# ^^ - invalid + +] +#<- invalid.illegal.stray.brace.square + +class Class(object + def __init__(self): +# ^^^ invalid.illegal.name +# ^ - meta.class + +# "Hang on, I'm still typing" + +foo.'bar' +# ^^^^^^^ - invalid + +foo.bar(baz., True) +# ^^^^^ - invalid + +################## +# Variable annotations +################## + +primes: List[int] = [] +# ^ punctuation.separator.annotation.variable.python +# ^ keyword.operator.assignment + +captain: str # Note: no initial value! +# ^ punctuation.separator.annotation.variable.python + +class Starship: + stats: ClassVar[Dict[str, int]] = {} +# ^ punctuation.separator.annotation.variable.python +# ^ keyword.operator.assignment + + +################## +# Assignment Expressions +################## + +# Examples from https://www.python.org/dev/peps/pep-0572/ + +y := f(x) +# ^^ invalid.illegal.not-allowed-here.python + +(y := f(x)) +# ^^ keyword.operator.assignment.inline.python + +y0 = y1 := f(x) +# ^^ invalid.illegal.not-allowed-here.python + +y0 = (y1 := f(x)) +# ^^ keyword.operator.assignment.inline.python + +foo(x=(y := f(x))) +# ^^ keyword.operator.assignment.inline.python + +if (match := pattern.search(data)) is not None: +# ^^ keyword.operator.assignment.inline.python + pass + +if tz := self._tzstr(): +# ^^ keyword.operator.assignment.inline.python + s += tz + +while chunk := file.read(8192): +# ^^ keyword.operator.assignment.inline.python + process(chunk) + +[y := f(x), y**2, y**3] +# ^^ keyword.operator.assignment.inline.python + +filtered_data = [y for x in data if (y := f(x)) is not None] +# ^^ keyword.operator.assignment.inline.python + +def foo(answer=(p := 42)): +# ^^ keyword.operator.assignment.inline.python + +lambda: (x := 1) +# ^^ keyword.operator.assignment.inline.python + +lambda line: (m := re.match(pattern, line)) and m.group(1) # Valid +# ^^ keyword.operator.assignment.inline.python + +f'{(x:=10)}' +# ^^ keyword.operator.assignment.inline.python + +f'{x:=10}' +# ^^ - keyword.operator.assignment.inline.python + + +if any(len(longline := line) >= 100 for line in lines): +# ^^ keyword.operator.assignment.inline.python + print("Extremely long line:", longline) + +# These are all invalid. We could let linters handle them, +# but these weren't hard to implement. +def foo(x: y:=f(x)) -> a:=None: pass +# ^^ invalid.illegal.not-allowed-here.python +# ^^ invalid.illegal.not-allowed-here.python +foo(x = y := f(x), y=x:=2) +# ^^ invalid.illegal.not-allowed-here.python +# ^^ invalid.illegal.not-allowed-here.python +{a := 1: 2} +# ^^ invalid.illegal.not-allowed-here.python +{1, b := 2} +# ^^ invalid.illegal.not-allowed-here.python +[1][x:=0] +# ^^ invalid.illegal.not-allowed-here.python +def foo(answer = p := 42): pass +# ^^ invalid.illegal.not-allowed-here.python +(lambda: x := 1) +# ^^ invalid.illegal.not-allowed-here.python + + +# <- - meta +# ensure we're not leaking a context diff --git a/syntaxes/Python/syntax_test_python_strings.py b/syntaxes/Python/syntax_test_python_strings.py @@ -0,0 +1,702 @@ +# SYNTAX TEST "Packages/Python/Python.sublime-syntax" + +############################### +# Strings and embedded syntaxes +############################### + +var = "\x00 \xaa \xAF \070 \0 \r \n \t \\ \a \b \' \v \f \u0aF1 \UFe0a182f \N{SPACE}" +# ^ meta.string.python +# ^^^^ constant.character.escape.hex +# ^^^^ constant.character.escape.hex +# ^^^^ constant.character.escape.hex +# ^^^^ constant.character.escape.octal +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^^^^^ constant.character.escape.unicode +# ^^^^^^^^^^ constant.character.escape.unicode +# ^^^^^^^^^ constant.character.escape.unicode + +invalid_escapes = "\. \-" +# ^^ invalid.deprecated.character.escape.python +# ^^ invalid.deprecated.character.escape.python + +conn.execute("SELECT * FROM foobar") +# ^ meta.string.python keyword.other.DML.sql + +conn.execute('SELECT * FROM foobar') +# ^ keyword.other.DML.sql + +conn.execute(U"SELECT * FROM foobar") +# ^ keyword.other.DML.sql + +conn.execute(U'SELECT * FROM foobar') +# ^ keyword.other.DML.sql + +# In this example, the Python string is not raw, so \t is a python escape +conn.execute(u"SELECT * FROM foobar WHERE foo = '\t'") +# ^ keyword.other.DML.sql +# ^ constant.character.escape.python + +conn.execute(u'SELECT * FROM foobar') +# ^ keyword.other.DML.sql + +# In this example, the Python string is raw, so the \b should be a SQL escape +conn.execute(r"SELECT * FROM foobar WHERE baz = '\b") +# ^ meta.string.python keyword.other.DML.sql +# ^ constant.character.escape.sql + +# This tests to ensure the Python placeholder will be highlighted even in a raw SQL string +conn.execute(r'SELECT * FROM foobar WHERE %s') +# ^ keyword.other.DML.sql +# ^ constant.other.placeholder.python + +conn.execute(r"SELECT * FROM foobar") +# ^ keyword.other.DML.sql + +conn.execute(r'SELECT * FROM foobar') +# ^ keyword.other.DML.sql + +conn.execute(r"""SELECT * FROM foobar WHERE %s and foo = '\t'""") +# ^ keyword.other.DML.sql +# ^ constant.other.placeholder.python +# ^ constant.character.escape.sql + +# Capital R prevents all syntax embedding +conn.execute(R'SELECT * FROM foobar') +# ^ meta.string.python - keyword.other.DML.sql + +conn.execute(R"SELECT * FROM foobar") +# ^ - keyword.other.DML.sql + +conn.execute(R"""SELECT * FROM foobar""") +# ^ - keyword.other.DML.sql + +conn.execute(r'''SELECT * FROM foobar''') +# ^ keyword.other.DML.sql + +conn.execute(u"""SELECT * FROM foobar WHERE %s and foo = '\t'""") +# ^ keyword.other.DML.sql +# ^ constant.other.placeholder.python +# ^ constant.character.escape.python + +regex = r'\b ([fobar]*){1}(?:a|b)?' +# ^ meta.string.python keyword.control.anchor.regexp +# ^ keyword.operator.quantifier.regexp + +regex = r'.* # Not a comment (yet)' +# ^^^^^^^^^^^^^^^^^^^^^ - comment +# ^ punctuation.definition.string.end.python - comment +# ^ - invalid + +regex = r".* # Not a comment (yet)" +# ^^^^^^^^^^^^^^^^^^^^^ - comment +# ^ punctuation.definition.string.end.python - comment +# ^ - invalid + +regex = r'''\b ([fobar]*){1}(?:a|b)?''' +# ^ keyword.control.anchor.regexp +# ^ keyword.operator.quantifier.regexp + +regex = r"""\b ([fobar]*){1}(?:a|b)?""" +# ^ keyword.control.anchor.regexp +# ^ keyword.operator.quantifier.regexp + +# Capital R prevents all syntax embedding +regex = R'\b ([fobar]*){1}(?:a|b)?' +# ^ - keyword.control.anchor.regexp +# ^ - keyword.operator.quantifier.regexp + +regex = R"\b ([fobar]*){1}(?:a|b)?" +# ^ - keyword.control.anchor.regexp +# ^ - keyword.operator.quantifier.regexp + +bad_string = 'SELECT * FROM users +# ^ invalid.illegal.unclosed-string + +more_bad_string = r" +# ^ invalid.illegal.unclosed-string.python + +string = ''' + +# <- string.quoted.single.block +''' + +string = """ + +# <- string.quoted.double.block +""" + +string = """ +# ^^^ string.quoted.double.block - string string +\ +# <- punctuation.separator.continuation.line.python +""" + +string = r""" +# ^^^ meta.string.python string.quoted.double.block +\ +# <- - punctuation +""" + +string = r""" + # An indented comment. +# ^ - comment +# ^ comment.line.number-sign.regexp +### <<This comment>> @includes some &punctutation. +# <- comment.line.number-sign.regexp +""" + +string = ''' +# ^^^ string.quoted.single.block +''' + +string = r''' +# ^^^ string.quoted.single.block +''' + +string = r''' + # An indented comment. +# ^ - comment +# ^ comment.line.number-sign.regexp +### <<This comment>> @includes some &punctutation. +# <- comment.line.number-sign.regexp +''' + +string = r''' + [set] +# ^^^^^ constant.other.character-class.set.regexp +# ^ punctuation.definition.character-class.begin.regexp +# ^ punctuation.definition.character-class.end.regexp + (group) +# ^^^^^^^ meta.group.regexp +# ^ punctuation.definition.group.begin.regexp +# ^ punctuation.definition.group.end.regexp + (?<!group) +# ^^^^^^^^^^ meta.group.assertion.regexp +# ^ punctuation.definition.group.begin.regexp +# ^^^ constant.other.assertion.regexp +# ^ punctuation.definition.group.end.regexp +''' + +query = \ + """ + SELECT + ( + SELECT CASE field + WHEN 1 + THEN -- comment's say that +# ^ source.sql comment.line.double-dash + EXISTS( + select 1) + ELSE NULL + ) as result + """ + +query = \ + r""" + + SELECT + ( + SELECT CASE field + WHEN 1 + THEN -- comment's say that +# ^ source.sql comment.line.double-dash + EXISTS( + select 1) + ELSE NULL + ) as result + """ + +query = \ +''' +SELECT + ( + SELECT CASE field + WHEN 1 + THEN -- comment's say that +# ^ source.sql comment.line.double-dash + EXISTS( + select 1) + ELSE NULL + ) as result +''' + +sql = 'SELECT * FROM foo -- bar baz' +# ^ source.sql +# ^ source.sql comment.line.double-dash +# ^ punctuation.definition.string.end.python - source.sql + + +# There are many variations of making a byte string +(b'', B'', br'', bR'', BR'', Br'', rb'', Rb'', RB'', rB'') +#^ storage.type.string +# ^ storage.type.string +# ^^ storage.type.string +# ^^ storage.type.string +# ^^ storage.type.string +# ^^ storage.type.string +# ^^ storage.type.string +# ^^ storage.type.string +# ^^ storage.type.string +# ^^ storage.type.string + +# Bytes by defaut support placeholders and character escapes, but not unicode +b'This is a \n test, %s no unicode \uDEAD' +# <- storage.type.string +#^ string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape +# ^^ constant.other.placeholder +# ^^^^^^ - constant +B'This is a \n test, %s no unicode \uDEAD' +# <- storage.type.string +#^ string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape +# ^^ constant.other.placeholder +# ^^^^^^ - constant +b'''This is a \n test, %s no unicode \uDEAD''' +# <- storage.type.string +#^^^ string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape +# ^^ constant.other.placeholder +# ^^^^^^ - constant +B'''This is a \n test, %s no unicode \uDEAD''' +# <- storage.type.string +#^^^ string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape +# ^^ constant.other.placeholder +# ^^^^^^ - constant + +# Uppercase R raw bytes don't allow anything +bR'This is a \n test, %s no unicode \uDEAD' +# <- storage.type.string +# ^ string.quoted.single punctuation.definition.string.begin +# ^^ - constant.character.escape +# ^^ - constant.other.placeholder +# ^^^^^^ - constant +BR'This is a \n test, %s no unicode \uDEAD' +# <- storage.type.string +# ^ string.quoted.single punctuation.definition.string.begin +# ^^ - constant.character.escape +# ^^ - constant.other.placeholder +# ^^^^^^ - constant +Rb'This is a \n test, %s no unicode \uDEAD' +# <- storage.type.string +# ^ string.quoted.single punctuation.definition.string.begin +# ^^ - constant.character.escape +# ^^ - constant.other.placeholder +# ^^^^^^ - constant +RB'This is a \n test, %s no unicode \uDEAD' +# <- storage.type.string +# ^ string.quoted.single punctuation.definition.string.begin +# ^^ - constant.character.escape +# ^^ - constant.other.placeholder +# ^^^^^^ - constant +bR'''This is a \n test, %s no unicode \uDEAD''' +# <- storage.type.string +# ^^^ string.quoted.single punctuation.definition.string.begin +# ^^ - constant.character.escape +# ^^ - constant.other.placeholder +# ^^^^^^ - constant +BR'''This is a \n test, %s no unicode \uDEAD''' +# <- storage.type.string +# ^^^ string.quoted.single punctuation.definition.string.begin +# ^^ - constant.character.escape +# ^^ - constant.other.placeholder +# ^^^^^^ - constant +Rb'''This is a \n test, %s no unicode \uDEAD''' +# <- storage.type.string +# ^^^ string.quoted.single punctuation.definition.string.begin +# ^^ - constant.character.escape +# ^^ - constant.other.placeholder +# ^^^^^^ - constant +RB'''This is a \n test, %s no unicode \uDEAD''' +# <- storage.type.string +# ^^^ string.quoted.single punctuation.definition.string.begin +# ^^ - constant.character.escape +# ^^ - constant.other.placeholder +# ^^^^^^ - constant + +# Lowercase r raw bytes are interpreted as regex +br'This is a \n (test|with), %s no unicode \uDEAD' +# <- storage.type.string +# ^ string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape.backslash.regexp +# ^ keyword.operator.or.regexp +# ^^ - constant +# ^^ constant.character.escape.backslash.regexp +# ^^^^ - constant +Br'This is a \n (test|with), %s no unicode \uDEAD' +# <- storage.type.string +# ^ string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape.backslash.regexp +# ^ keyword.operator.or.regexp +# ^^ - constant +# ^^ constant.character.escape.backslash.regexp +# ^^^^ - constant +rb'This is a \n (test|with), %s no unicode \uDEAD' +# <- storage.type.string +# ^ string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape.backslash.regexp +# ^ keyword.operator.or.regexp +# ^^ - constant +# ^^ constant.character.escape.backslash.regexp +# ^^^^ - constant +rB'This is a \n (test|with), %s no unicode \uDEAD' +# <- storage.type.string +# ^ string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape.backslash.regexp +# ^ keyword.operator.or.regexp +# ^^ - constant +# ^^ constant.character.escape.backslash.regexp +# ^^^^ - constant +br'''This is a \n (test|with), %s no unicode \uDEAD''' +# <- storage.type.string +# ^^^ string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape.backslash.regexp +# ^ keyword.operator.or.regexp +# ^^ - constant +# ^^ constant.character.escape.backslash.regexp +# ^^^^ - constant +Br'''This is a \n (test|with), %s no unicode \uDEAD''' +# <- storage.type.string +# ^^^ string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape.backslash.regexp +# ^ keyword.operator.or.regexp +# ^^ - constant +# ^^ constant.character.escape.backslash.regexp +# ^^^^ - constant +rb'''This is a \n (test|with), %s no unicode \uDEAD''' +# <- storage.type.string +# ^^^ string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape.backslash.regexp +# ^ keyword.operator.or.regexp +# ^^ - constant +# ^^ constant.character.escape.backslash.regexp +# ^^^^ - constant +rB'''This is a \n (test|with), %s no unicode \uDEAD''' +# <- storage.type.string +# ^^^ meta.string.python string.quoted.single punctuation.definition.string.begin +# ^^ constant.character.escape.backslash.regexp +# ^ keyword.operator.or.regexp +# ^^ - constant +# ^^ constant.character.escape.backslash.regexp +# ^^^^ - constant + +datetime.strptime('2011227', '%Y%V%u') +# ^^^^^^^^ string.quoted.single.python +# ^^^^^^ constant.other.placeholder.python +datetime.strftime(datetime.now(), '%Y%V%uT') +# ^^^^^^^^^ string.quoted.single.python +# ^^^^^^ constant.other.placeholder.python +# ^ - constant.other.placeholder.python + +'{0:%Y%m%d}'.format(datetime.date.today()) +# ^^^^^^^^^^ string.quoted.single.python +# ^^^^^^^^ constant.other.placeholder.python +# ^^^^^^ constant.other.format-spec.python +'{0:%Y-%m-%d}'.format(datetime.date.today()) +# ^^^^^^^^^^^^ string.quoted.single.python +# ^^^^^^^^^^ constant.other.placeholder.python +# ^^^^^^^^ constant.other.format-spec.python +'{0:%Y-%m-%dT}'.format(datetime.date.today()) +# ^^^^^^^^^^^^ string.quoted.single.python +# ^^^^^^^^^^^ constant.other.placeholder.python +# ^^^^^^^^^ constant.other.format-spec.python +'{0:T}'.format(datetime.date.today()) # This is legal but uninteresting +# ^^^^^ string.quoted.single.python +'{0:%Y}-{0:%m}-{0:%d}'.format(datetime.date.today()) +# ^^^^^^^^^^^^^^^^^^^ string.quoted.single.python +# ^^^^^ constant.other.placeholder.python +# ^^^ constant.other.format-spec.python +# ^ - constant.other.placeholder.python +# ^^^^^^ constant.other.placeholder.python +# ^^ constant.other.format-spec.python +# ^ - constant.other.placeholder.python +# ^^^^^^ constant.other.placeholder.python +# ^^ constant.other.format-spec.python +'{0:%Y}-{0:%m +# ^^^^^^^^^^^ string.quoted.single.python +# ^^^^^ constant.other.placeholder.python +# ^^^ constant.other.format-spec.python +# ^^^^ - constant.other.placeholder.python +# ^ invalid.illegal.unclosed-string.python +'{0:%Y}-{0:% +# ^^^^^^^^^^^ string.quoted.single.python +# ^^^^^ constant.other.placeholder.python +# ^^^ constant.other.format-spec.python +# ^^^^^ - constant.other.placeholder.python +# ^ invalid.illegal.unclosed-string.python + +x = "hello \ +# ^^^^^^^^^ string.quoted.double.python - invalid.illegal.unclosed-string.python, \ +# ^ punctuation.separator.continuation.line.python, \ +world" +#^^^^^ string.quoted.double.python +# ^ - string.quoted.double.python +# ^ punctuation.definition.string.end.python + +x = 'hello \ +# ^^^^^^^^^ string.quoted.single.python - invalid.illegal.unclosed-string.python, \ +# ^ punctuation.separator.continuation.line.python, \ +world' +#^^^^^ string.quoted.single.python +# ^ - string.quoted.single.python +# ^ punctuation.definition.string.end.python + +x = 'hello\s world' +# ^^ - punctuation.separator.continuation.line.python +# ^^^^^^^^ - invalid.illegal.unexpected-text.python + +sql = "SELECT `name` FROM `users` \ + WHERE `password` LIKE 'abc'" +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double source.sql +# ^ punctuation.definition.string.end.python + +sql = Ur"SELECT `name` FROM `users` \ + WHERE `password` LIKE 'abc'" +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double source.sql +# ^ punctuation.definition.string.end.python + +sql = b'just some \ +# ^^^^^^^^^^^^^ string.quoted.single.python - invalid.illegal.unclosed-string.python, \ +# ^ punctuation.separator.continuation.line.python, \ + string' +#^^^^^^^^^^ string.quoted.single +# ^ punctuation.definition.string.end.python + +# https://docs.python.org/3/library/string.html#formatspec +"First, thou shalt count to {0}" # References first positional argument +# ^^^ constant.other.placeholder.python +"Bring me a {}" # Implicitly references the first positional argument +# ^^ constant.other.placeholder.python +"From {} to {}" # Same as "From {0} to {1}" +# ^^ constant.other.placeholder.python +# ^^^^ - constant.other.placeholder.python +# ^^ constant.other.placeholder.python +"My quest is {name}" # References keyword argument 'name' +# ^^^^^^ constant.other.placeholder.python +"Weight in tons {0.weight}" # 'weight' attribute of first positional arg +# ^^^^^^^^^^ constant.other.placeholder.python +"Units destroyed: {players[0]}" # First element of keyword argument 'players'. +# ^^^^^^^^^^^^ constant.other.placeholder.python +"Harold's a clever {0!s}" # Calls str() on the argument first +# ^^^^^ constant.other.placeholder.python +# ^^ storage.modifier.conversion.python +"Bring out the holy {name!r}" # Calls repr() on the argument first +# ^^^^^^^^ constant.other.placeholder.python +"More {!a}" # Calls ascii() on the argument first +# ^^^^ constant.other.placeholder.python +"More {!a: <10s}" # Calls ascii() on the argument first, then formats +# ^^^^^^^^^^ constant.other.placeholder.python +"Escaped {{0}}" # outputs: "Escaped {0}" +# ^^^^^ - constant.other.placeholder.python +# ^^ constant.character.escape.python +# ^^ constant.character.escape.python +"Escaped {{}} {} {}" # outputs: "Escaped {} arg1 arg2" +# ^^^^ constant.character.escape.python - constant.other.placeholder.python +# ^^ constant.other.placeholder.python +# ^ - constant.other.placeholder.python +# ^^ constant.other.placeholder.python + +datetime.datetime.utcnow().strftime("%Y%m%d%H%M") +# ^^^^^^^^^^ constant.other.placeholder + +"My String %% %s" +# ^^ constant.other.placeholder +# ^^ constant.other.placeholder + +"My String %(s)s %s" +# ^^^^^ constant.other.placeholder +# ^ variable.other.placeholder +# ^^ constant.other.placeholder + +"Testing {:,.2f}".format(1000) +# ^^^^^^^ constant.other.placeholder +# ^ punctuation.definition.placeholder.begin +# ^ punctuation.definition.placeholder.end + +"Testing {0:>9,}".format(1000) +# ^^^^^^^ constant.other.placeholder + +"Testing {:j^9,}".format(1000) +# ^^^^^^^ constant.other.placeholder +# ^^^^^ constant.other.format-spec + +"result: {value:{width}.{precision}}" +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant.other.placeholder +# ^^^^^^^^^^^^^^^^^^^^ meta.format-spec.python +# ^ punctuation.definition.placeholder.begin +# ^^^^^^^ constant.other.placeholder constant.other.placeholder +# ^ punctuation.definition.placeholder.begin +# ^^^^^^^^^^^ constant.other.placeholder constant.other.placeholder +# ^^ punctuation.definition.placeholder.end + +a=["aaaa{", "bbbb{"] +# ^ - constant.other.placeholder +# ^ punctuation.definition.string.end.python + +foo = "{text{" # Comment +# ^^^^^^ - constant.other.placeholder +# ^ punctuation.definition.string.end +bar = "}}" # Comment +# ^^ constant.character.escape + +f"string" +# <- storage.type.string +#^^^^^^^^ string.quoted.double + + RF"""string""" +#^^ storage.type.string - string +# ^^^^^^^^^^^^ meta.string.interpolated string.quoted.double.block + +F'''string''' +# <- storage.type.string +#^^^^^^^^^^^^ meta.string.interpolated string.quoted.single.block + + rf'string' +#^^ storage.type.string - string +# ^^^^^^^^ meta.string.interpolated string.quoted.single + +rf'\r\n' f'\r\n' Rf'\r\n' +# ^^^^ source.regexp constant.character.escape.backslash.regexp +# ^^^^ constant.character.escape.python +# ^^^^ - constant + +rf"\r\n" f"\r\n" Rf'\r\n' +# ^^^^ source.regexp constant.character.escape.backslash.regexp +# ^^^^ constant.character.escape.python +# ^^^^ - constant + +expr = fr"^\s*({label}|{notlabel})" +# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.python +# ^ meta.string.interpolated.python string.quoted.double.python source.regexp.python keyword.control.anchor.regexp +# ^ source.regexp.python meta.group.regexp punctuation.definition.group.begin.regexp +# ^^^^^^^ source.python meta.string.interpolated.python meta.interpolation.python +# ^^^^^ source.python.embedded meta.qualified-name.python meta.generic-name.python +# ^ source.regexp.python meta.group.regexp punctuation.definition.group.end.regexp + +line = re.sub(rf" ?\{{\\i.?\}}({x})\{{\\i.?\}}", r"\1", line) +# ^^^^^ constant.character.escape.backslash.regexp +# ^^ constant.character.escape.python +# ^^^ constant.character.escape.backslash.regexp +# ^^ constant.character.escape.python +# ^ punctuation.section.interpolation.begin.python + +f"\{{{x}\}} test" +# ^ invalid.deprecated.character.escape.python +# ^^ constant.character.escape.python +# ^ punctuation.section.interpolation.begin.python + +f"{something}" +#^^^^^^^^^^^^ meta.string.interpolated +# <- storage.type.string +#^ punctuation.definition.string.begin +# ^ punctuation.section.interpolation.begin +# ^ punctuation.section.interpolation.end +# ^ punctuation.definition.string.end +# ^^^^^^^^^ source source.python.embedded +# ^ source - meta, string, source source + +f"{True!a:02f}" +#^^^^^^^^^^^^^^ meta.string.interpolated +# ^ - source source.python.embedded +# ^^^^ source source.python.embedded constant.language +# ^^^^^^^ - source source.python.embedded +# ^^ storage.modifier.conversion - constant.other.format-spec +# ^^^^ constant.other.format-spec +# ^ punctuation.section.interpolation.end +# ^ punctuation.definition.string.end +# ^ source - meta, string, source source + +f"result: {value:{width}.{precision}}\n" +# ^ punctuation.section.interpolation.begin.python - source source +# ^^^^^ source source.python.embedded +# ^^ - source source +# ^ punctuation.section.interpolation.begin.python +# ^^^^^ source source.python.embedded +# ^ punctuation.section.interpolation.end.python +# ^ - source source +# ^ punctuation.section.interpolation.begin.python +# ^^^^^^^^^ source source.python.embedded +# ^^ punctuation.section.interpolation.end.python - source source +# ^^ constant.character.escape +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.interpolation.python +# ^^^^^^^^^^^^^^^^^^^^ meta.format-spec.python +# ^^^^^^ - meta.interpolation.python meta.interpolation.python +# ^^^^^^^ meta.interpolation.python meta.interpolation.python +# ^ - meta.interpolation.python meta.interpolation.python +# ^^^^^^^^^^^ meta.interpolation.python meta.interpolation.python +# ^^^ - meta.interpolation.python meta.interpolation.python +rf"{value:{width!s:d}}" +# <- storage.type.string.python - string +# ^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated +# ^^^^^ source source.python.embedded +# ^^ storage.modifier.conversion +# ^^ constant.other.format-spec + +F""" {} {\} } +#^^^^^^^^^^^ meta.string.interpolated +#^^^ punctuation.definition.string.begin +# ^^ invalid.illegal.empty-expression +# ^ invalid.illegal.backslash-in-fstring +# ^ invalid.illegal.stray-brace +""" + +fr''' +# ^ - invalid +''' + +# Most of these were inspired by +# https://github.com/python/cpython/commit/9a4135e939bc223f592045a38e0f927ba170da32 +f'{x=:}' +# ^ storage.modifier.debug.python +f'{x=:.2f}' +# ^ storage.modifier.debug.python +f'{x=!r}' +# ^ storage.modifier.debug.python +f'{x=!a}' +# ^ storage.modifier.debug.python +f'{x=!s:*^20}' +# ^ storage.modifier.debug.python +# ^^ storage.modifier.conversion.python +# ^^^^^ meta.format-spec.python +f'{"Σ"=}' +# ^ storage.modifier.debug.python +f'{0==1}' +# ^^ -storage.modifier.debug.python +f'{0!=1}' +# ^ -storage.modifier.debug.python +f'{0<=1}' +# ^ -storage.modifier.debug.python +f'{0>=1}' +# ^ -storage.modifier.debug.python +f'{f(a="3=")}' +# ^^^^ -storage.modifier.debug.python + +f" { +% ^ invalid.illegal.unclosed-string + # TODO make this test pass + }" + +f' \ + {1 + 2!a:02f}' +#^^^^^^^^^^^^^^ meta.string.interpolated +# ^^^^^ source source.python.embedded + +f"{d for d in range(10)}" # yes, this doesn't make sense +# ^^^ keyword.control.loop.for.generator.python + +f' +# ^ invalid.illegal.unclosed-string + + +# <- - meta +# this test is to ensure we're not matching anything here anymore diff --git a/syntaxes/SQL/Comments.tmPreferences b/syntaxes/SQL/Comments.tmPreferences @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Comments</string> + <key>scope</key> + <string>source.sql</string> + <key>settings</key> + <dict> + <key>shellVariables</key> + <array> + <dict> + <key>name</key> + <string>TM_COMMENT_START</string> + <key>value</key> + <string>-- </string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_START_2</string> + <key>value</key> + <string>/*</string> + </dict> + <dict> + <key>name</key> + <string>TM_COMMENT_END_2</string> + <key>value</key> + <string>*/</string> + </dict> + </array> + </dict> +</dict> +</plist> diff --git a/syntaxes/SQL/Miscellaneous.tmPreferences b/syntaxes/SQL/Miscellaneous.tmPreferences @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plist version="1.0"> +<dict> + <key>name</key> + <string>Miscellaneous</string> + <key>scope</key> + <string>source.sql</string> + <key>settings</key> + <dict> + <key>decreaseIndentPattern</key> + <string>\)(?!=.*\()</string> + <key>increaseIndentPattern</key> + <string>^\s*(create|grant|insert|delete|update)\b|\((?!.*\))</string> + </dict> +</dict> +</plist> diff --git a/syntaxes/SQL/SQL.sublime-syntax b/syntaxes/SQL/SQL.sublime-syntax @@ -0,0 +1,240 @@ +%YAML 1.2 +--- +name: SQL +file_extensions: + - sql + - ddl + - dml +scope: source.sql + +variables: + end_identifier: (?=[ \t]*(?:[^\w'"`. \t]|$)) + +contexts: + main: + - include: comments + - match: |- + (?xi) + \b(create(?:\s+or\s+replace)?)\s+ + (aggregate|conversion|database|domain|function|group|(?:unique\s+)?index|language|operator class|operator|procedure|rule|schema|sequence|table(?:space)?|trigger|type|user|view) + \b\s* + scope: meta.create.sql + captures: + 1: keyword.other.create.sql + 2: keyword.other.sql + push: identifier_create + - match: (?i:\s*\b(drop)\s+(aggregate|conversion|database|domain|function|group|index|language|operator class|operator|procedure|rule|schema|sequence|table|tablespace|trigger|type|user|view)) + scope: meta.drop.sql + captures: + 1: keyword.other.create.sql + 2: keyword.other.sql + - match: (?i:\s*(drop)\s+(table)\s+(\w+)(\s+cascade)?\b) + scope: meta.drop.sql + captures: + 1: keyword.other.create.sql + 2: keyword.other.table.sql + 3: entity.name.function.sql + 4: keyword.other.cascade.sql + - match: (?i:\s*\b(alter)\s+(aggregate|conversion|database|domain|function|group|index|language|operator class|operator|procedure|rule|schema|sequence|table|tablespace|trigger|type|user|view)\s+) + scope: meta.alter.sql + captures: + 1: keyword.other.create.sql + 2: keyword.other.table.sql + - match: |- + (?xi) + + # normal stuff, capture 1 + \b(bigint|bigserial|bit|boolean|box|bytea|cidr|circle|date|datetime|double\sprecision|inet|int|integer|line|lseg|macaddr|money|ntext|oid|path|point|polygon|real|serial|smallint|sysdate|sysname|text)\b + + # numeric suffix, capture 2 + 3i + |\b(bit\svarying|character\s(?:varying)?|tinyint|var\schar|float|interval)\((\d+)\) + + # optional numeric suffix, capture 4 + 5i + |\b(char|number|nvarchar|varbinary|varchar\d?)\b(?:\((\d+)\))? + + # special case, capture 6 + 7i + 8i + |\b(numeric|decimal)\b(?:\((\d+),(\d+)\))? + + # special case, captures 9, 10i, 11 + |\b(times?)\b(?:\((\d+)\))?(\swith(?:out)?\stime\szone\b)? + + # special case, captures 12, 13, 14i, 15 + |\b(timestamp)(?:(s|tz))?\b(?:\((\d+)\))?(\s(with|without)\stime\szone\b)? + + + captures: + 1: storage.type.sql + 2: storage.type.sql + 3: constant.numeric.sql + 4: storage.type.sql + 5: constant.numeric.sql + 6: storage.type.sql + 7: constant.numeric.sql + 8: constant.numeric.sql + 9: storage.type.sql + 10: constant.numeric.sql + 11: storage.type.sql + 12: storage.type.sql + 13: storage.type.sql + 14: constant.numeric.sql + 15: storage.type.sql + - match: (?i:\b((?:primary|foreign)\s+key|references|on\sdelete(\s+cascade)?|on\supdate(\s+cascade)?|check|constraint|default)\b) + scope: storage.modifier.sql + - match: \b\d+\b + scope: constant.numeric.sql + - match: (?i:\b(true|false)\b) + scope: constant.boolean.sql + - match: (?i:\b(select(\s+(distinct|top))?|insert(\s+(ignore\s+)?into)?|update|delete|truncate|from|set|where|group\s+by|with|case|when|then|else|end|union(\s+all)?|using|order\s+by|limit|(inner|cross)\s+join|join|straight_join|(left|right)(\s+outer)?\s+join|natural(\s+(left|right)(\s+outer)?)?\s+join)\b) + scope: keyword.other.DML.sql + - match: (?i:\b(?:(is)\s+)?(?:(not)\s+)?(null)\b) + captures: + 1: keyword.operator.logical.sql + 2: keyword.operator.logical.sql + 3: constant.language.sql + - match: (?i:\b(and|or|like|having|exists|between|in)\b) + scope: keyword.operator.logical.sql + - match: (?i:\bvalues\b) + scope: keyword.other.DML.II.sql + - match: (?i:\b(begin(\s+work)?|start\s+transaction|commit(\s+work)?|rollback(\s+work)?)\b) + scope: keyword.other.LUW.sql + - match: (?i:\b(grant(\swith\sgrant\soption)?|revoke)\b) + scope: keyword.other.authorization.sql + - match: (?i:\s*\b(comment\s+on\s+(table|column|aggregate|constraint|database|domain|function|index|operator|rule|schema|sequence|trigger|type|view))\s+.*?\s+(is)\s+) + scope: keyword.other.object-comments.sql + - match: (?i)\bas\b + scope: keyword.operator.assignment.alias.sql + - match: (?i)\b(asc|desc)\b + scope: keyword.other.order.sql + - match: \* + scope: variable.language.star.sql + - match: "<=>|[!<>]?=|<>|<|>" + scope: keyword.operator.comparison.sql + - match: '-|\+|/' + scope: keyword.operator.math.sql + - match: \|\| + scope: keyword.operator.concatenator.sql + - match: (?i)\b(CURRENT_(DATE|TIME(STAMP)?|USER)|(SESSION|SYSTEM)_USER)\b + comment: List of SQL99 built-in functions from http://www.oreilly.com/catalog/sqlnut/chapter/ch04.html + scope: support.function.scalar.sql + - match: (?i)\b(AVG|COUNT|MIN|MAX|SUM)(?=\s*\() + comment: List of SQL99 built-in functions from http://www.oreilly.com/catalog/sqlnut/chapter/ch04.html + scope: support.function.aggregate.sql + - match: (?i)\b(CONCATENATE|CONVERT|LOWER|SUBSTRING|TRANSLATE|TRIM|UPPER)\b + scope: support.function.string.sql + - match: \b(\w+?)\.(\w+)\b + captures: + 1: constant.other.database-name.sql + 2: constant.other.table-name.sql + - include: strings + - include: regexps + - match: (\()(\)) + comment: Allow for special ↩ behavior + scope: meta.block.sql + captures: + 1: punctuation.section.scope.begin.sql + 2: punctuation.section.scope.end.sql + comments: + - match: "--" + scope: punctuation.definition.comment.sql + push: + - meta_scope: comment.line.double-dash.sql + - match: \n + pop: true + - match: "#" + scope: punctuation.definition.comment.sql + push: + - meta_scope: comment.line.number-sign.sql + - match: \n + pop: true + - match: /\* + scope: punctuation.definition.comment.sql + push: + - meta_scope: comment.block.c + - match: \*/ + pop: true + - match: ^\s*(\*)(?!/) + captures: + 1: punctuation.definition.comment.sql + regexps: + - match: /(?=\S.*/) + scope: punctuation.definition.string.begin.sql + push: + - meta_scope: string.regexp.sql + - match: / + scope: punctuation.definition.string.end.sql + pop: true + - include: string_interpolation + - match: \\/ + scope: constant.character.escape.slash.sql + - match: '%r\{' + comment: We should probably handle nested bracket pairs!?! -- Allan + scope: punctuation.definition.string.begin.sql + push: + - meta_scope: string.regexp.modr.sql + - match: '\}' + scope: punctuation.definition.string.end.sql + pop: true + - include: string_interpolation + string_escape: + - match: \\. + scope: constant.character.escape.sql + string_interpolation: + - match: '(#\{)([^\}]*)(\})' + scope: string.interpolated.sql + captures: + 1: punctuation.definition.string.begin.sql + 3: punctuation.definition.string.end.sql + strings: + - match: "'" + scope: punctuation.definition.string.begin.sql + push: + - meta_scope: string.quoted.single.sql + - match: "''" + scope: constant.character.escape.sql + - match: "'" + scope: punctuation.definition.string.end.sql + pop: true + - include: string_escape + - match: "`" + scope: punctuation.definition.string.begin.sql + push: + - meta_scope: string.quoted.other.backtick.sql + - match: "`" + scope: punctuation.definition.string.end.sql + pop: true + - include: string_escape + - match: '"' + scope: punctuation.definition.string.begin.sql + push: + - meta_scope: string.quoted.double.sql + - match: '""' + scope: constant.character.escape.sql + - match: '"' + scope: punctuation.definition.string.end.sql + pop: true + - include: string_interpolation + - match: '%\{' + scope: punctuation.definition.string.begin.sql + push: + - meta_scope: string.other.quoted.brackets.sql + - match: '\}' + scope: punctuation.definition.string.end.sql + pop: true + - include: string_interpolation + identifier_create: + - meta_content_scope: meta.toc-list.full-identifier.sql + - match: '(?:(\w+)|''([^'']+)''|"([^"]+)"|`([^`]+)`){{end_identifier}}' + scope: meta.toc-list.full-identifier.sql + captures: + 1: entity.name.function.sql + 2: entity.name.function.sql + 3: entity.name.function.sql + 4: entity.name.function.sql + pop: true + # Schema identifiers + - match: (?:\w+|'[^']+'|"[^"]+"|`[^`]+`)\s*(\.) + captures: + 1: punctuation.accessor.dot.sql + # Handle situations where the schema and . + - match: '{{end_identifier}}' + pop: true diff --git a/syntaxes/SQL/syntax_test_sql.sql b/syntaxes/SQL/syntax_test_sql.sql @@ -0,0 +1,98 @@ +-- SYNTAX TEST "Packages/SQL/SQL.sublime-syntax" + +SELECT 'Foo '' Bar'; +-- ^ constant.character.escape.sql + +SELECT "My "" Crazy Column Name" FROM my_table; +-- ^ constant.character.escape.sql + +;CREATE TABLE foo (id INTEGER PRIMARY KEY); + -- <- keyword.other.create +--^^^^^ keyword.other.create +-- ^^^^^ keyword.other +-- ^^^ entity.name.function +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - entity.name.function + +create table some_schema.test2( id serial ); +--^^^^ meta.create keyword.other.create +-- ^^^^^ meta.create keyword.other +-- ^^^^^^^^^^^^ - entity.name.function +-- ^ punctuation.accessor.dot +-- ^^^^^ entity.name.function +-- ^^^^^^^^^^^^^^ - entity.name.function + +create table some_schema . test2 ( id serial ); +--^^^^ meta.create keyword.other.create +-- ^^^^^ meta.create keyword.other +-- ^^^^^^^^^^^^^^ - entity.name +-- ^ punctuation.accessor.dot +-- ^^^^^ entity.name.function +-- ^^^^^^^^^^^^^^^ - entity.name.function + +create table "testing123" (id integer); +--^^^^ meta.create keyword.other.create +-- ^^^^^ meta.create keyword.other +-- ^ - entity.name.function +-- ^^^^^^^^^^ entity.name.function +-- ^^^^^^^^^^^^^^^^ - entity.name.function + +create table `dbo`."testing123" (id integer); +--^^^^ meta.create keyword.other.create +-- ^^^^^ meta.create keyword.other +-- ^^^^^^^ - entity.name.function +-- ^ punctuation.accessor.dot +-- ^^^^^^^^^^ entity.name.function +-- ^^^^^^^^^^^^^^^^ - entity.name.function + +select * +from some_table +where exists(select * from other_table where id = some_table.id) +-- ^^^^^^ keyword.operator.logical + +SELECT +( +SELECT CASE field +USING a +-- <- keyword.other.DML + WHEN 1 + THEN -- comment's say that +-- ^ comment.line.double-dash + EXISTS( + select 1) + ELSE NULL + END +) as result + + +/* +This is a +multiline comment +-- ^ source.sql comment.block.c +*/ + +/** + * +-- ^ punctuation.definition.comment.sql +*/ + +select + + + <=> +-- ^^^ keyword.operator.comparison.sql + +SELECT *, +-- ^^^ keyword.other.DML.sql +-- ^ variable.language.star.sql + f.id AS database_id +-- ^^ keyword.operator.assignment.alias.sql +FROM foo +WHERE f.a IS NULL +-- ^^ keyword.other.DML.sql +-- ^^ keyword.operator.logical.sql +-- ^^^^ constant.language.sql + AND f.b IS NOT NULL +-- ^^^ keyword.operator.logical.sql +-- ^^ keyword.operator.logical.sql +-- ^^^ keyword.operator.logical.sql +-- ^^^^ constant.language.sql