Skip to content

Commit 463760e

Browse files
keith-hallmichaelblyonsdeathaxe
authored
[C#] support SQL inside triple quoted strings (#4406)
Resolves #3720 This commit adds support for SQL syntax highlighting within various string literals. Co-authored-by: Michael <[email protected]> Co-authored-by: deathaxe <[email protected]>
1 parent be7e6d7 commit 463760e

File tree

2 files changed

+141
-9
lines changed

2 files changed

+141
-9
lines changed

C#/C#.sublime-syntax

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ variables:
5353

5454
method_param_type_modifier: \b(?:out|ref|this|params|in)\b
5555

56+
sql_indicator: |-
57+
(?x: \s* (?:
58+
# dml statements
59+
SELECT | INSERT | REPLACE | DELETE | TRUNCATE | UPDATE | MERGE\s+INTO
60+
# ddl statements
61+
| ADD | ALTER | CREATE | DROP
62+
# conditional
63+
| IF \s+ (?: NOT \s+ )? EXISTS
64+
# declaration
65+
| DECLARE | WITH | BEGIN
66+
) \s )
67+
5668
contexts:
5769
prototype:
5870
- include: comments
@@ -1825,9 +1837,14 @@ contexts:
18251837
- include: strings
18261838

18271839
strings:
1828-
- match: '("""+)'
1840+
- match: '(""""+)'
18291841
scope: punctuation.definition.string.begin.cs
18301842
push: inside_raw_string_literal
1843+
- match: '"""'
1844+
scope: punctuation.definition.string.begin.cs
1845+
push:
1846+
- inside_triple_quoted_raw_string_literal
1847+
- inside_triple_quoted_raw_string_literal_syntax
18311848
- match: '"'
18321849
scope: punctuation.definition.string.begin.cs
18331850
push: inside_string
@@ -1850,22 +1867,46 @@ contexts:
18501867
# multi-line strings
18511868
- match: '@"'
18521869
scope: punctuation.definition.string.begin.cs
1853-
push: inside_long_string
1870+
push:
1871+
- inside_long_string
1872+
- inside_long_string_syntax
18541873
# interpolated multi-line strings
18551874
- match: '(@\$|\$@)"'
18561875
scope: punctuation.definition.string.begin.cs
1857-
push: inside_long_format_string
1876+
push:
1877+
- inside_long_format_string
1878+
- inside_long_format_string_syntax
18581879

18591880
inside_raw_string_literal:
18601881
- meta_include_prototype: false
1861-
- meta_scope: string.quoted.triple.cs
1862-
- include: string_escaped
1882+
- meta_scope: meta.string.cs string.quoted.triple.cs
18631883
- match: '\1'
18641884
scope: punctuation.definition.string.end.cs
18651885
pop: true
1886+
- include: string_escaped
18661887
- include: string_placeholders
18671888
- include: extended_string_placeholders
18681889

1890+
inside_triple_quoted_raw_string_literal:
1891+
- meta_include_prototype: false
1892+
- meta_scope: meta.string.cs string.quoted.triple.cs
1893+
- match: '"""'
1894+
scope: punctuation.definition.string.end.cs
1895+
pop: true
1896+
- include: string_escaped
1897+
- include: string_placeholders
1898+
- include: extended_string_placeholders
1899+
1900+
inside_triple_quoted_raw_string_literal_syntax:
1901+
- meta_include_prototype: false
1902+
- match: (?={{sql_indicator}})
1903+
set: scope:source.sql
1904+
with_prototype:
1905+
- match: (?=""")
1906+
pop: true
1907+
- match: (?=\S)
1908+
pop: true
1909+
18691910
inside_string:
18701911
- meta_include_prototype: false
18711912
- meta_scope: meta.string.cs string.quoted.double.cs
@@ -1972,6 +2013,21 @@ contexts:
19722013
scope: punctuation.section.interpolation.begin.cs
19732014
push: inside_long_format_string_interpolation
19742015

2016+
inside_long_format_string_syntax:
2017+
- meta_include_prototype: false
2018+
- match: (?={{sql_indicator}})
2019+
set: scope:source.sql
2020+
with_prototype:
2021+
- include: long_string_escaped
2022+
- match: (?=")
2023+
pop: true
2024+
- include: string_placeholder_escape
2025+
- match: \{
2026+
scope: punctuation.section.interpolation.begin.cs
2027+
push: inside_long_format_string_interpolation
2028+
- match: (?=\S)
2029+
pop: true
2030+
19752031
inside_long_format_string_interpolation:
19762032
- clear_scopes: 1
19772033
- meta_scope: meta.interpolation.cs
@@ -2082,14 +2138,27 @@ contexts:
20822138

20832139
inside_long_string:
20842140
- meta_include_prototype: false
2085-
- meta_scope: string.quoted.double.raw.cs
2141+
- meta_scope: meta.string.cs string.quoted.double.raw.cs
20862142
- include: long_string_escaped
20872143
- match: '"'
20882144
scope: punctuation.definition.string.end.cs
20892145
pop: true
20902146
- include: string_placeholders
20912147
- include: extended_long_string_placeholders
20922148

2149+
inside_long_string_syntax:
2150+
- meta_include_prototype: false
2151+
- match: (?={{sql_indicator}})
2152+
set: scope:source.sql
2153+
with_prototype:
2154+
- include: long_string_escaped
2155+
- match: (?=")
2156+
pop: true
2157+
- include: string_placeholders
2158+
- include: extended_long_string_placeholders
2159+
- match: (?=\S)
2160+
pop: true
2161+
20932162
escaped:
20942163
- match: '{{escaped_char}}'
20952164
scope: constant.character.escape.cs

C#/tests/syntax_test_Strings.cs

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
/// SYNTAX TEST "Packages/C#/C#.sublime-syntax"
22

3+
var character = 'y';
4+
/// ^^^^^^^^^ variable.other.cs
5+
/// ^ keyword.operator.assignment.variable.cs
6+
/// ^^^ meta.string.cs string.quoted.single.cs
7+
/// ^ punctuation.definition.string.begin.cs
8+
/// ^ constant.character.literal.cs
9+
/// ^ punctuation.definition.string.end.cs
10+
/// ^ punctuation.terminator.statement.cs
11+
var character_too_long = 'no';
12+
/// ^^^^^^^^^^^^^^^^^^ variable.other.cs
13+
/// ^ keyword.operator.assignment.variable.cs
14+
/// ^^^^ invalid.illegal.not_a_char.cs
15+
/// ^ punctuation.terminator.statement.cs
16+
317
"short unicode \u1234";
418
///<- string.quoted.double.cs
519
/// ^^^^^^ constant.character.escape.cs
@@ -27,20 +41,20 @@
2741
/// ^^ constant.character.escape.cs
2842

2943
var literal = "foo";
30-
/// ^^^^^ string.quoted.double
44+
/// ^^^^^ string.quoted.double - meta.string.interpolated
3145
var interpolated_none = $"foo";
3246
/// ^^^^^^ meta.string.interpolated.cs string.quoted.double.cs
3347
var interpolated_yes = $"foo {bar} foo";
3448
/// ^^^^^^^^^^^^^^^^ meta.string.interpolated.cs
3549
var verbatim_singleline = @"foo";
36-
/// ^^^^^^ string.quoted.double.raw.cs
50+
/// ^^^^^^ meta.string.cs string.quoted.double.raw.cs - meta.string.interpolated
3751
var verbatim_singleline_interpolated_none = $@"foo bar";
3852
/// ^^^^^^^^^^^ meta.string.interpolated.cs string.quoted.double.raw.cs
3953
var verbatim_singleline_interpolated_yes = $@"foo {bar} foo";
4054
/// ^^^^^^^ string.quoted.double.raw.cs
4155
/// ^^^^^^^^^^^^^^^^^ meta.string.interpolated.cs
4256
var verbatim_multiline = @"foo bar
43-
/// ^^^^^^^^^^ string.quoted.double.raw.cs
57+
/// ^^^^^^^^^^ meta.string.cs string.quoted.double.raw.cs - meta.string.interpolated
4458
baz";
4559
var verbatim_multiline_interpolated_none = $@"foo bar
4660
/// ^^^^^^^^^^^ meta.string.interpolated.cs string.quoted.double.raw.cs
@@ -50,7 +64,56 @@
5064
/// ^^^^^^^^^^^^ meta.string.interpolated.cs
5165
baz";
5266

67+
var verbatim_singleline_sql = @"
68+
SELECT *
69+
FROM foo
70+
WHERE SQLi='{0}'";
71+
///^^^^^^^^^^^^^^^^^^^^ meta.string.cs string.quoted.double.raw.cs - meta.string.interpolated
72+
///^^^^^^^^^^^^^^^^^^^ source.sql
73+
/// ^^^^^ keyword.other.dml.sql
74+
/// ^^^^ meta.column-name.sql
75+
/// ^ keyword.operator.comparison.sql
76+
/// ^^^^^ meta.string.sql string.quoted.single.sql
77+
/// ^ punctuation.definition.string.begin.sql
78+
/// ^^^ constant.other.placeholder.cs
79+
/// ^ punctuation.definition.placeholder.begin.cs
80+
/// ^ meta.number.integer.decimal.cs constant.numeric.value.cs
81+
/// ^ punctuation.definition.placeholder.end.cs
82+
/// ^ punctuation.definition.string.end.sql
83+
/// ^ punctuation.definition.string.end.cs
84+
/// ^ punctuation.terminator.statement.cs
85+
86+
var verbatim_singleline_sql_interpolated = $@"
87+
SELECT *
88+
FROM foo
89+
WHERE SQLi='{bar}'";
90+
///^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.cs string.quoted.double.raw.cs
91+
///^^^^^^^^^^^^^^^^^^^^^ source.sql
92+
/// ^^^^^ keyword.other.dml.sql
93+
/// ^^^^ meta.column-name.sql
94+
/// ^ keyword.operator.comparison.sql
95+
/// ^^^^^^^ meta.string.sql
96+
/// ^ string.quoted.single.sql punctuation.definition.string.begin.sql
97+
/// ^^^^^ meta.interpolation.cs
98+
/// ^ punctuation.section.interpolation.begin.cs
99+
/// ^^^ source.cs variable.other.cs
100+
/// ^ punctuation.section.interpolation.end.cs
101+
/// ^ string.quoted.single.sql punctuation.definition.string.end.sql
102+
/// ^ punctuation.definition.string.end.cs
103+
/// ^ punctuation.terminator.statement.cs
104+
53105
"{32F31D43-81CC-4C15-9DE6-3FC5453562B6}"
54106
/// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double
55107
/// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant.other.guid
56108

109+
"""
110+
SELECT *
111+
FROM some_table
112+
/// ^^^^ meta.string.cs string.quoted.triple.cs source.sql keyword.other.dml.sql
113+
""";
114+
/// <- meta.string.cs string.quoted.triple.cs punctuation.definition.string.end.cs
115+
116+
"""
117+
no sql here
118+
/// ^^^^^^^^^^^^ meta.string.cs string.quoted.triple.cs - source.sql
119+
""";

0 commit comments

Comments
 (0)