diff --git a/RustEnhanced.sublime-syntax b/RustEnhanced.sublime-syntax index 4ded3af5..b1b40155 100644 --- a/RustEnhanced.sublime-syntax +++ b/RustEnhanced.sublime-syntax @@ -292,6 +292,74 @@ contexts: - match: '(?=\S)' pop: true + pattern-param: + - include: comments + - match: '&' + scope: keyword.operator.rust + - match: \b(mut|ref)\b + scope: storage.modifier.rust + - match: '@' + scope: keyword.operator.rust + - match: '\b{{identifier}}\b(?!\s*(?:::|\{|\[|\())' + scope: variable.parameter.rust + + - match: '\{' + # Struct pattern. + scope: punctuation.section.block.begin.rust + push: + - meta_scope: meta.block.rust + - match: '\}' + scope: punctuation.section.block.end.rust + pop: true + - match: '(\d+)\s*(:)' + # Tuple struct field specifier. + captures: + 1: constant.numeric.integer.decimal.rust + 2: punctuation.separator.rust + - match: '{{identifier}}\s*(:)' + # Struct field specifier. + captures: + 1: punctuation.separator.rust + - match: '\.\.' + scope: keyword.operator.rust + - include: pattern-param + + - match: '\(' + # Tuple or tuple struct pattern. + scope: punctuation.section.group.begin.rust + push: + - meta_scope: meta.group.rust + - match: '\)' + scope: punctuation.section.group.end.rust + pop: true + - match: '\.\.' + scope: keyword.operator.rust + - include: pattern-param + + - match: '\[' + # Slice pattern. + scope: punctuation.section.brackets.begin.rust + push: + - meta_scope: meta.brackets.rust + - match: '\]' + scope: punctuation.section.brackets.end.rust + pop: true + - include: pattern-param + + # Path for struct patterns. + - match: '\bself\b|\bsuper\b' + scope: keyword.other.rust + - match: '\b{{identifier}}\b' + - match: '::' + + - match: ':(?!:)' + # Type + scope: punctuation.separator.rust + push: + - match: '(?=,|\)|\]|\}|\|)' + pop: true + - include: type-any-identifier + closure: - meta_content_scope: meta.function.closure.rust - match: '\|' @@ -300,33 +368,16 @@ contexts: closure-parameters: - meta_scope: meta.function.parameters.rust + - match: '\|' + scope: punctuation.definition.parameters.end.rust + pop: true + - include: pattern-param # If the user has just typed a |, exit the params # scope as soon as we hit something that it not a # valid part so the whole rest of the document isn't # highlighted using the params scope - - include: comments - - match: '(?=\()' - push: group - - match: '(?=[};)\]])' - pop: true - - match: '\|' - scope: punctuation.definition.parameters.end.rust + - match: '(?=[=};)\]])' pop: true - - match: \bself\b - scope: variable.parameter.rust - - match: '({{identifier}})\s*(?:(:(?!:))|(?=\||,))' - captures: - 1: variable.parameter.rust - 2: punctuation.separator.rust - push: - - match: (?=,|\|) - pop: true - - include: type-any-identifier - - match: '&' - scope: keyword.operator.rust - - match: \b(mut|ref)\b - scope: storage.modifier.rust - - include: lifetime closure-return: - meta_content_scope: meta.function.closure.rust @@ -414,7 +465,7 @@ contexts: scope: keyword.operator.rust - match: \b(mut|ref|const|unsafe)\b scope: storage.modifier.rust - - match: \b(fn)\b(\() + - match: \b(fn)\b\s*(\() captures: 1: storage.type.function.rust 2: meta.group.rust punctuation.definition.group.begin.rust @@ -921,13 +972,7 @@ contexts: - include: comments - match: '(?=\))' pop: true - - match: \bself\b - scope: variable.parameter.rust - - match: '({{identifier}})\s*(:(?!:))' - captures: - 1: variable.parameter.rust - 2: punctuation.separator.rust - - include: type-any-identifier + - include: pattern-param fn-return: - meta_scope: meta.function.rust diff --git a/tests/syntax-rust/syntax_test_closures.rs b/tests/syntax-rust/syntax_test_closures.rs index 2c16dad5..74fca101 100644 --- a/tests/syntax-rust/syntax_test_closures.rs +++ b/tests/syntax-rust/syntax_test_closures.rs @@ -31,13 +31,6 @@ call_func(|c| 1 + 2 + c); // ^^^^^^^^^^^^^ meta.function.closure // ^^^ meta.function.parameters -// TODO: x and y should be parameters! -// Looks like tuples use meta.group so we'll use that for tuple arguments too -// fixes https://github.com/rust-lang/sublime-rust/issues/164 -let f = |(x, y)| { x + y }; -// ^ punctuation.definition.parameters.begin -// ^^^^^^ meta.group - fn lambdas() { let c = |foo, // ^ meta.function.closure meta.function.parameters punctuation.definition.parameters.begin @@ -53,3 +46,136 @@ fn lambdas() { // ^^^ meta.function.parameters variable.parameter // ^ meta.function.closure meta.function.parameters punctuation.definition.parameters.end } + + +let x = |self, _, _foo, foo: 'static str| {}; +// ^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^ variable.parameter +// ^^^^ variable.parameter +// ^^^ variable.parameter +// ^ punctuation.separator +// ^^^^^^^ storage.modifier.lifetime +// ^^^ storage.type +let x = |&a, &mut b, ref c, mut d, ref mut e| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^ keyword.operator +// ^ variable.parameter +// ^ keyword.operator +// ^^^ storage.modifier +// ^ variable.parameter +// ^^^ storage.modifier +// ^ variable.parameter +// ^^^ storage.modifier +// ^ variable.parameter +// ^^^ storage.modifier +// ^^^ storage.modifier +// ^ variable.parameter +let x = |foo @ Some{}| {}; +// ^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^ variable.parameter +// ^ keyword.operator +// ^ meta.block punctuation.section.block.begin +// ^ meta.block punctuation.section.block.end +let x = |path :: to :: Struct{a, b, ..}, +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^ meta.block +// ^ punctuation.section.block.begin +// ^ variable.parameter +// ^ variable.parameter +// ^^ keyword.operator +// ^ punctuation.section.block.end + self::Struct{c}, super::Struct{d}| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^ keyword.other +// ^^^ meta.block +// ^ variable.parameter +// ^^^^^ keyword.other +// ^^^ meta.block +// ^ variable.parameter +let x = |Struct{ref mut a}| {}; +// ^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^ meta.block +// ^^^ storage.modifier +// ^^^ storage.modifier +// ^ variable.parameter +let x = |Struct{0: (x, y), 1: z}| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^^^^^^^ meta.block +// ^ constant.numeric.integer.decimal +// ^ punctuation.separator +// ^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^ variable.parameter +// ^ variable.parameter +// ^ punctuation.section.group.end +// ^ constant.numeric.integer.decimal +// ^ punctuation.separator +// ^ variable.parameter +let x = |Struct{field: (x, y), field2: z}| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block +// ^^^^^^ meta.group +// ^ variable.parameter +// ^ variable.parameter +// ^ variable.parameter +let x = |path::to::TupleStruct(x, (y, z), ..)| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^^^^^ meta.group +// ^ variable.parameter +// ^^^^^^ meta.group meta.group +// ^ variable.parameter +// ^ variable.parameter +// ^^ keyword.operator +let x = |(x, (y, z)), (Foo{&mut i, ..}, foo @ Some{})| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^ meta.group +// ^ variable.parameter +// ^^^^^^ meta.group meta.group +// ^ variable.parameter +// ^ meta.group variable.parameter +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group +// ^^^^^^^^^^^^ meta.block +// ^ keyword.operator +// ^^^ storage.modifier +// ^ variable.parameter +// ^^ keyword.operator +// ^^^ variable.parameter +// ^ keyword.operator +let x = |[ref mut a, (x, y)]| {}; +// ^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^^^^^^^^^ meta.brackets +// ^ punctuation.section.brackets.begin +// ^^^ storage.modifier +// ^^^ storage.modifier +// ^ variable.parameter +// ^^^^^^ meta.group +// ^ variable.parameter +// ^ variable.parameter +let x = |a: i32, b: Foo, c: Option, d: extern "C" fn (), e: *const u8| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^ variable.parameter +// ^^^ storage.type +// ^ variable.parameter +// ^ variable.parameter +// ^^^^^^ meta.generic support.type +// ^^^ meta.generic storage.type +// ^ variable.parameter +// ^^^^^^ keyword.other +// ^^^ string.quoted.double +// ^^ storage.type.function +// ^^ meta.group +// ^ variable.parameter +// ^^^^^^ storage.modifier +// ^^ storage.type +let x = |/*comment*/(/*c*/a, [b/*c*/], S{/*c*/f: c})| {}; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.closure meta.function.parameters +// ^^^^^^^^^^^ comment.block +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group +// ^^^^^ comment.block +// ^ variable.parameter +// ^^^^^^^^ meta.brackets +// ^ variable.parameter +// ^^^^^ comment.block +// ^^^^^^^^^^^ meta.block +// ^^^^^ comment.block +// ^ variable.parameter diff --git a/tests/syntax-rust/syntax_test_functions.rs b/tests/syntax-rust/syntax_test_functions.rs index aaff0f5b..9a943cf3 100644 --- a/tests/syntax-rust/syntax_test_functions.rs +++ b/tests/syntax-rust/syntax_test_functions.rs @@ -73,3 +73,36 @@ fn f(a: *const u8, b: *mut i8) {} // ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters // ^^^^^ storage.modifier // ^^^ storage.modifier + +// Test irrefutable patterns in params. Most of these tests are in `syntax_test_closure.rs`. +fn f(self, +// ^^^^^^^ meta.function meta.function.parameters +// ^^^^ variable.parameter + (a, b): Tuple, +// ^^^^^^ meta.group +// ^ punctuation.section.group.begin +// ^ variable.parameter +// ^ variable.parameter +// ^ punctuation.section.group.end +// ^ punctuation.separator + Struct{field: c}: Struct, +// ^^^^^^^^^^ meta.block +// ^ punctuation.section.block.begin +// ^ variable.parameter +// ^ punctuation.section.block.end +// ^ punctuation.separator + TupleStruct{0: d}: TupleStruct, +// ^^^^^^ meta.block +// ^ punctuation.section.block.begin +// ^ constant.numeric.integer.decimal +// ^ variable.parameter +// ^ punctuation.section.block.end +// ^ punctuation.separator + [e, f]: Slice) +// ^^^^^^ meta.brackets +// ^ punctuation.section.brackets.begin +// ^ variable.parameter +// ^ variable.parameter +// ^ punctuation.section.brackets.end +// ^ punctuation.separator +{}