Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Default.sublime-keymap
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@
{ "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.double - punctuation.definition.string.end", "match_all": true }
]
},
// r# will expand to r#""#
// r#" will expand to r#""#
// Additional # characters will be duplicated on both sides.
{ "keys": ["#"], "command": "insert_snippet", "args": {"contents": "#$1\"$0\"${1/[^#]/$1/}#"}, "context":
{ "keys": ["\""], "command": "insert_snippet", "args": {"contents": "\"$0\"${TM_CURRENT_WORD/[^#]/$1/}"}, "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": "r$", "match_all": true },
{ "key": "preceding_text", "operator": "regex_contains", "operand": "r#+$", "match_all": true },
{ "key": "selector", "operator": "equal", "operand": "source.rust" },
{ "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.double - punctuation.definition.string.end", "match_all": true }
]
Expand Down
24 changes: 13 additions & 11 deletions RustEnhanced.sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ file_extensions:
- rs
scope: source.rust
variables:
identifier: '(?:[[:alpha:]][_[:alnum:]]*|_[_[:alnum:]]+)'
non_raw_ident: '[[:alpha:]][_[:alnum:]]*|_[_[:alnum:]]+'
identifier: '(?:(?:r\#)?{{non_raw_ident}})'
camel_ident: '\b_*[A-Z][a-zA-Z0-9_]*[a-z][a-zA-Z0-9_]*\b'
lifetime: '''(?:_|{{identifier}})(?!\'')\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)'
Expand All @@ -32,7 +33,7 @@ contexts:
- match: ';'
scope: punctuation.terminator.rust

- match: '(''{{identifier}})\s*(:)'
- match: '(''(?:{{non_raw_ident}}))\s*(:)'
captures:
1: entity.name.label.rust
2: punctuation.separator.rust
Expand Down Expand Up @@ -114,14 +115,14 @@ contexts:
2: storage.modifier.rust
3: entity.name.constant.rust

- match: '\b(break|continue)(?:\s+(''{{identifier}}))?'
- match: '\b(break|continue)(?:\s+(''{{non_raw_ident}}))?'
captures:
1: keyword.control.rust
2: entity.name.label.rust

- include: type

- match: '\b(macro_rules!)\s+([[:alpha:]_][[:alnum:]_]*)\b'
- match: '\b(macro_rules!)\s+({{identifier}})\b'
captures:
1: support.function.rust
2: entity.name.macro.rust
Expand Down Expand Up @@ -167,7 +168,7 @@ contexts:
# is more performant as the below
# - match: '\b((?:debug_)?assert_(?:eq|ne)!)\s*(\()'

- match: '\b[[:lower:]_][[:lower:][:digit:]_]*!(?=\s*(\(|\{|\[))'
- match: '\b{{identifier}}!(?=\s*(\(|\{|\[))'
scope: support.macro.rust

- include: support-type
Expand All @@ -193,9 +194,12 @@ contexts:
- include: return-type
- include: symbols
- include: keywords

- match: '\b[[:lower:]_][[:lower:][:digit:]_]*(?=\()'
scope: support.function.rust

- match: '{{identifier}}'

visibility:
- match: '\b(pub)\s*(\()'
captures:
Expand Down Expand Up @@ -472,6 +476,7 @@ contexts:
scope: keyword.operator.rust
- match: '!'
scope: keyword.operator.rust
- match: '{{identifier}}'

raw-pointer:
- match: '\*\s*(?:const|mut)\b'
Expand Down Expand Up @@ -1229,21 +1234,18 @@ contexts:
scope: storage.modifier.lifetime.rust

basic-identifiers:
- match: '\b([[:upper:]_][[:upper:][:digit:]_]+)\b'
- match: '\b(?:(?:r#)?[[:upper:]_][[:upper:][:digit:]_]+)\b'
scope: constant.other.rust
- match: '\b(c_[[:lower:][:digit:]_]+|[[:lower:]_][[:lower:][:digit:]_]*_t)\b'
scope: storage.type.rust
- match: '\b_*[A-Z][a-zA-Z0-9_]*[a-z][a-zA-Z0-9_]*\b'
- match: '\b(?:r#)?_*[A-Z][a-zA-Z0-9_]*[a-z][a-zA-Z0-9_]*\b'
scope: storage.type.source.rust
- match: '(?={{identifier}}::)'
push:
- meta_scope: meta.path.rust
- include: no-path-identifiers
- match: '::'
set: no-type-names
- match: '{{identifier}}::'
scope: meta.path.rust
push: no-type-names
- match: '::(?={{identifier}})'
scope: meta.path.rust
push: no-type-names
Expand Down
106 changes: 106 additions & 0 deletions tests/syntax-rust/syntax_test_raw.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// SYNTAX TEST "Packages/Rust Enhanced/RustEnhanced.sublime-syntax"
// Raw identifiers in various positions.

use r#foo::bar as r#alias_foo;
// ^^^^^^^ meta.path
// ^^^^^^^^^^^ source -keyword

fn main() {
#[r#attr]
// ^^^^^^^^^ meta.annotation -keyword
r#foo::r#bar();
// ^^^^^^^ meta.path -keyword
// ^^^^^ -keyword

let r#local = r#Struct { r#struct: () };
// ^^^^^^^^ -keyword
// ^^^^^^^^ storage.type.source -keyword
// ^^^^^^^^ -keyword
let r#async = r#foo(r#local);
// ^^^^^^^^ -keyword
// ^^^^^ -keyword
// ^^^^^^^ -keyword
r#macro!();
// ^^^^^^^^ support.macro -keyword -invalid
somecall(r#foo);
// ^^^^^ meta.function meta.block meta.group

if let r#sub_pat @ Foo(_) = r#Foo(3) {}
// ^^^^^^^^^^ -keyword
// ^^^^^ storage.type.source

match r#async {
// ^^^^^^^^ -keyword
r#Foo | r#Bar => r#foo(),
// ^^^^^ storage.type.source -keyword
// ^^^^^ storage.type.source -keyword
// ^^^^^ -keyword
}
}

fn r#bar<'a, r#T>(r#x: &'a r#T) {}
// ^^^^^ meta.function entity.name.function -keyword
// ^^^ meta.generic -keyword
// ^^^ meta.function meta.function.parameters variable.parameter -keyword
// ^^^ meta.function meta.function.parameters -keyword

struct Generic<r#T>(T);
// ^^^ meta.struct meta.generic meta.generic -keyword

mod r#foo {
// ^^^^^ meta.module entity.name.module -keyword
pub fn r#bar() {}
// ^^^^^ meta.module meta.block meta.function entity.name.function -keyword
}

enum r#Foo {
// ^^^^^ meta.enum meta.enum entity.name.enum
r#Bar {},
// ^^^^^^ meta.enum -keyword
}

struct r#Struct {
// ^^^^^^^^ meta.struct entity.name.struct -keyword
r#field: r#FieldType,
// ^^^^^^^ meta.struct meta.block variable.other.member -keyword
// ^^^^^^^^^^^^^ meta.struct meta.block -keyword
}

trait r#Trait {
// ^^^^^^^ meta.trait entity.name.trait -keyword
type r#Type;
// ^^^^^^ meta.trait meta.block entity.name.type -keyword
}

impl r#Trait for r#Impl {
// ^^^^^^^^ meta.impl -keyword
// ^^^^^^ meta.impl entity.name.impl -keyword
type r#Type = r#u32;
// ^^^^^^ meta.impl meta.block entity.name.type
// ^^^^^ meta.impl meta.block -keyword -storage
fn r#xxx(r#fjio: r#u32) {}
// ^^^^^ meta.impl meta.block meta.function entity.name.function -keyword
// ^^^^^^ meta.impl meta.block meta.function meta.function.parameters variable.parameter -keyword
// ^^^^^ meta.impl meta.block meta.function meta.function.parameters -keyword -storage
}

extern "C" {
type r#ccc;
// ^^^^^ meta.block entity.name.type -keyword
static r#static_val: u32;
// ^^^^^^^^^^^^ meta.block -keyword
}

macro_rules! r#macro {
// ^^^^^^^ meta.macro entity.name.macro -keyword -invalid
() => {};
}

macro_rules! foo {
($x:expr) => {
let r#catch = $x + 1;
// ^^^^^^^^ meta.macro meta.macro.transcribers -keyword
r#println!("{}", r#catch);
// ^^^^^^^ meta.macro meta.macro.transcribers meta.group -keyword
};
}