From 9ff949b9d00dd485e1ccb0a06ba5d84854f04b1f Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 9 Dec 2023 10:45:34 -0800 Subject: [PATCH] [Rust] Add C-string literals (#3882) This commit adds support for C-string literals for Rust 1.76+ --- Rust/Rust.sublime-syntax | 53 +++++++++++++++++++++++------- Rust/tests/syntax_test_literals.rs | 49 +++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 11 deletions(-) diff --git a/Rust/Rust.sublime-syntax b/Rust/Rust.sublime-syntax index e696d6c50d..53b4af4aa6 100644 --- a/Rust/Rust.sublime-syntax +++ b/Rust/Rust.sublime-syntax @@ -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)' @@ -1269,6 +1268,8 @@ contexts: - include: raw-byte-string - include: string - include: raw-string + - include: c-string + - include: raw-c-string chars: - include: char @@ -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 @@ -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 @@ -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 @@ -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)((#*)") @@ -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 @@ -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)(#*)" diff --git a/Rust/tests/syntax_test_literals.rs b/Rust/tests/syntax_test_literals.rs index fa19c787fd..b0b4627efe 100644 --- a/Rust/tests/syntax_test_literals.rs +++ b/Rust/tests/syntax_test_literals.rs @@ -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;