Skip to content

Commit

Permalink
[Rust] Add C-string literals (#3882)
Browse files Browse the repository at this point in the history
This commit adds support for C-string literals for Rust 1.76+
  • Loading branch information
ehuss authored Dec 9, 2023
1 parent 65dde23 commit 9ff949b
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 11 deletions.
53 changes: 42 additions & 11 deletions Rust/Rust.sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ variables:
identifier: '(?:(?:(?:r\#)?{{non_raw_ident}})\b)'
camel_ident: '\b_*[A-Z][a-zA-Z0-9_]*[a-z][a-zA-Z0-9_]*\b'
lifetime: '''(?:_|{{non_raw_ident}})(?!\'')\b'
escaped_byte: '\\([nrt0\"''\\]|x\h{2})'
escaped_char: '\\([nrt0\"''\\]|x[0-7]\h|u\{(?:\h_*){1,6}\})'
int_suffixes: '[iu](?:8|16|32|64|128|size)'
float_suffixes: 'f(32|64)'
Expand Down Expand Up @@ -1269,6 +1268,8 @@ contexts:
- include: raw-byte-string
- include: string
- include: raw-string
- include: c-string
- include: raw-c-string

chars:
- include: char
Expand All @@ -1289,8 +1290,7 @@ contexts:
# not valid syntax.
- match: '\n'
pop: true
- match: '{{escaped_byte}}'
scope: constant.character.escape.rust
- include: escaped-byte
set: byte-tail
- match: ''
set: byte-tail
Expand All @@ -1315,10 +1315,8 @@ contexts:
- match: '"'
scope: punctuation.definition.string.end.rust
pop: true
- match: '{{escaped_byte}}'
scope: constant.character.escape.rust
- match: '(\\)$'
scope: punctuation.separator.continuation.line.rust
- include: escaped-byte
- include: line-continuation
- match: '\\.'
scope: invalid.illegal.character.escape.rust

Expand All @@ -1334,6 +1332,14 @@ contexts:
scope: punctuation.definition.string.end.rust
pop: true

line-continuation:
- match: '\\$'
scope: punctuation.separator.continuation.line.rust

escaped-byte:
- match: '\\([nrt0\"''\\]|x\h{2})'
scope: constant.character.escape.rust

escaped-char:
- match: '{{escaped_char}}'
scope: constant.character.escape.rust
Expand Down Expand Up @@ -1378,8 +1384,7 @@ contexts:
scope: punctuation.definition.string.end.rust
pop: true
- include: escaped-char
- match: '(\\)$'
scope: punctuation.separator.continuation.line.rust
- include: line-continuation

raw-string:
- match: (r)((#*)")
Expand All @@ -1393,6 +1398,33 @@ contexts:
scope: punctuation.definition.string.end.rust
pop: true

c-string:
- match: '(c)(")'
captures:
1: storage.type.string.rust
2: punctuation.definition.string.begin.rust
push:
- meta_include_prototype: false
- meta_scope: string.quoted.double.rust
- match: '"'
scope: punctuation.definition.string.end.rust
pop: true
- include: escaped-byte
- include: line-continuation
- include: escaped-char

raw-c-string:
- match: (cr)((#*)")
captures:
1: storage.type.string.rust
2: punctuation.definition.string.begin.rust
push:
- meta_include_prototype: false
- meta_scope: string.quoted.double.raw.rust
- match: '"\3'
scope: punctuation.definition.string.end.rust
pop: true

format-string:
- match: '"'
scope: punctuation.definition.string.begin.rust
Expand All @@ -1404,8 +1436,7 @@ contexts:
pop: true
- include: escaped-char
- include: format-escapes
- match: '(\\)$'
scope: punctuation.separator.continuation.line.rust
- include: line-continuation

format-raw-string:
- match: (r)(#*)"
Expand Down
49 changes: 49 additions & 0 deletions Rust/tests/syntax_test_literals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,55 @@ let s_uni_esc_under3 = "\u{10__FFFF}";
let s_uni_esc_extra = "\u{1234567}";
// ^^^^^^^^^^^ string.quoted.double invalid.illegal.character.escape

let cstr_empty = c"";
// ^ string.quoted.double storage.type.string
// ^^^ string.quoted.double
// ^ punctuation.definition.string.begin
// ^ punctuation.definition.string.end
// ^ punctuation.terminator
let cstr_unicode = c"æ";
// ^ string.quoted.double storage.type.string
// ^^^^ string.quoted.double
let cstr_byte_escape = c"\xFF\xC3\xA6\n\r\t\0\"\'\\";
// ^ storage.type.string
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double
// ^^^^^^^^^^^^^^^^^^^^^^^^^^ constant.character.escape
let cstr_byte_escape_invalid = c"\a";
// ^^^^^ string.quoted.double
// ^ storage.type.string
// ^ punctuation.definition.string.begin
// ^^ invalid.illegal.character.escape
// ^ punctuation.definition.string.end
let cstr_unicode_escape = c"\u{00E6}";
// ^^^^^^^^^^^ string.quoted.double
// ^^^^^^^^ constant.character.escape
let cstr_continue = c"\
\xFF";
// ^^^^ string.quoted.double constant.character.escape

let raw_cstr_empty = cr"";
// ^^^^ string.quoted.double.raw
// ^^ storage.type.string
// ^ punctuation.definition.string.begin
// ^ punctuation.definition.string.end
let raw_cstr_unicode = cr"東京";
// ^^^^^^ string.quoted.double.raw
// ^^ storage.type.string
let raw_cstr_hash = cr#"text with "quote" in it."#;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.raw
// ^^ storage.type.string
// ^^ punctuation.definition.string.begin
// ^^ punctuation.definition.string.end
let raw_cstr_multiline = cr##"
// ^^ string.quoted.double.raw storage.type.string
// ^^^^^^ string.quoted.double.raw
This text has "multiple lines"
"##;
// ^^ string.quoted.double.raw punctuation.definition.string.end
let raw_cstr_escape_ignore = cr"\n\x01\u{0123}\";
// ^^^^^^^^^^^^^^^^^^^ string.quoted.double.raw
// ^^^^^^^^^^^^^^^ -constant.character.escape

0;
// <- constant.numeric.integer.decimal
1_000u32;
Expand Down

0 comments on commit 9ff949b

Please sign in to comment.