From f96a0907cac9ba9e14d6c1f64631325da78c75b1 Mon Sep 17 00:00:00 2001 From: deathaxe Date: Tue, 23 Dec 2025 14:41:22 +0100 Subject: [PATCH] Fix format string placeholders This commit... 1. separates double- and single-quoted format string contexts to enable quotation marks in format-strings. 2. scopes format-spec as python 3. restricts format placeholders to brace+digit `{\d+}` to avoid false positives --- PowerShell.sublime-syntax | 90 ++++++++++++++++++++++++----- tests/syntax_test_strings.ps1 | 103 +++++++++++++++++++++++++--------- 2 files changed, 152 insertions(+), 41 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 40149c47..17b88637 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -315,10 +315,10 @@ contexts: - meta_scope: meta.string.interpolated.powershell string.quoted.double.powershell meta.function-call.powershell variable.function.powershell - match: '{{double_quote}}{2}' scope: constant.character.escape.powershell - - include: escape-sequences - match: '{{double_quote}}' scope: punctuation.definition.string.end.powershell pop: 1 + - include: escape-sequences - include: string-interpolations - include: path-punctuation @@ -1043,7 +1043,7 @@ contexts: - match: '{{single_quote}}' scope: punctuation.definition.string.end.powershell pop: 1 - - include: string-placeholders + - include: single-quoted-string-placeholders double-quoted-strings: - match: '{{double_quote}}' @@ -1055,12 +1055,12 @@ contexts: - meta_scope: meta.string.interpolated.powershell string.quoted.double.powershell - match: '{{double_quote}}{2}' scope: constant.character.escape.powershell - - include: escape-sequences - match: '{{double_quote}}' scope: punctuation.definition.string.end.powershell pop: 1 + - include: escape-sequences - include: string-interpolations - - include: string-placeholders + - include: double-quoted-string-placeholders single-quoted-heredoc-strings: - match: \@{{single_quote}}(?=$) @@ -1088,7 +1088,7 @@ contexts: pop: 1 - match: '{{single_quote}}{2}' scope: constant.character.escape.powershell - - include: string-placeholders + - include: single-quoted-string-placeholders double-quoted-heredoc-strings: - match: \@{{double_quote}}(?=$) @@ -1104,8 +1104,8 @@ contexts: scope: punctuation.definition.string.end.powershell pop: 1 - include: escape-sequences - - include: string-placeholders - include: string-interpolations + - include: double-quoted-string-placeholders inside-double-quoted-heredoc-string.syntax: - meta_include_prototype: false @@ -1137,20 +1137,84 @@ contexts: - include: variables-without-members - include: immediately-pop - string-placeholders: - - match: \{ - scope: punctuation.definition.placeholder.begin.powershell - push: inside-string-placeholder + double-quoted-string-placeholders: + - match: \{\{|\}\} + scope: constant.character.escape.powershell + - match: (\{)(\d+) + captures: + 1: punctuation.definition.placeholder.begin.powershell + 2: meta.number.integer.decimal.powershell constant.numeric.value.powershell + push: inside-double-quoted-string-placeholder - inside-string-placeholder: + inside-double-quoted-string-placeholder: - meta_include_prototype: false - meta_scope: constant.other.placeholder.powershell - match: \} scope: punctuation.definition.placeholder.end.powershell pop: 1 - - match: (?={{single_quote}}|{{double_quote}}) + - match: (?={{double_quote}}) pop: 1 - - match: '[:,;]' + - match: ':' + scope: punctuation.separator.format-spec.powershell + push: inside-double-quoted-string-placeholder-formatspec + - include: string-placeholder-separators + - include: string-placeholder-numbers + + inside-double-quoted-string-placeholder-formatspec: + - meta_include_prototype: false + - meta_content_scope: meta.format-spec.powershell constant.other.format-spec.powershell + - match: \} + scope: punctuation.definition.placeholder.end.powershell + pop: 2 + - match: '{{double_quote}}{2}' + scope: constant.character.escape.powershell + - match: (?={{double_quote}}) + pop: 2 + - include: escape-sequences + - include: string-placeholder-separators + + single-quoted-string-placeholders: + - match: \{\{|\}\} + scope: constant.character.escape.powershell + - match: (\{)(\d+) + captures: + 1: punctuation.definition.placeholder.begin.powershell + 2: meta.number.integer.decimal.powershell constant.numeric.value.powershell + push: inside-single-quoted-string-placeholder + + inside-single-quoted-string-placeholder: + - meta_include_prototype: false + - meta_scope: constant.other.placeholder.powershell + - match: \} + scope: punctuation.definition.placeholder.end.powershell + pop: 1 + - match: (?={{single_quote}}) + pop: 1 + - match: ':' + scope: punctuation.separator.format-spec.powershell + push: inside-single-quoted-string-placeholder-formatspec + - include: string-placeholder-separators + - include: string-placeholder-numbers + + inside-single-quoted-string-placeholder-formatspec: + - meta_include_prototype: false + - meta_content_scope: meta.format-spec.powershell constant.other.format-spec.powershell + - match: \} + scope: punctuation.definition.placeholder.end.powershell + pop: 2 + - match: '{{single_quote}}{2}' + scope: constant.character.escape.powershell + - match: (?={{single_quote}}) + pop: 2 + - include: escape-sequences + - include: string-placeholder-separators + + string-placeholder-numbers: + - match: \d+ + scope: meta.number.integer.decimal.powershell constant.numeric.value.powershell + + string-placeholder-separators: + - match: '[,;]' scope: punctuation.separator.powershell string-wildcards: diff --git a/tests/syntax_test_strings.ps1 b/tests/syntax_test_strings.ps1 index 05962bb2..4bfcdbea 100644 --- a/tests/syntax_test_strings.ps1 +++ b/tests/syntax_test_strings.ps1 @@ -416,7 +416,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -429,7 +430,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -442,7 +444,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -455,7 +458,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -468,7 +472,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -506,7 +511,8 @@ # ^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -544,7 +550,8 @@ # ^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -558,7 +565,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -578,7 +586,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -591,7 +600,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -604,7 +614,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^ constant.other.format-spec.powershell # ^ punctuation.separator.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell @@ -618,7 +629,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^ constant.other.format-spec.powershell # ^^ punctuation.separator.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell @@ -627,11 +639,8 @@ # ^^^^^^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell "{this is not a #comment}" -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - comment +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - comment - constant.other.placeholder # ^ punctuation.definition.string.begin.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^ constant.other.placeholder.powershell -# ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell "{0:##.#E000}" -f 2.71828 @@ -639,7 +648,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -647,25 +657,55 @@ # ^^^^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell # ^ punctuation.separator.decimal.powershell - # TODO: Let placeholders contain quotes "{0:#.00'##'}" -f 2.71828 # ^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell -# ^^^^^^^ constant.other.placeholder.powershell +# ^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell # ^^^^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell # ^ punctuation.separator.decimal.powershell + "{0:#.00""##""}" -f 2.71828 +# ^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^^^ constant.other.format-spec.powershell +# ^^ constant.character.escape.powershell +# ^^ constant.character.escape.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^ punctuation.definition.string.end.powershell + + "{0:#.00`u{00b5}}" -f 2.54 +# ^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^^^^^ meta.format-spec.powershell constant.other.format-spec.powershell +# ^^^^^^^^ constant.character.escape.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell + "{0:POS;NEG;ZERO}" -f -14 # ^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^^^^^ constant.other.format-spec.powershell # ^ punctuation.separator.powershell # ^ punctuation.separator.powershell # ^ punctuation.definition.placeholder.end.powershell @@ -680,7 +720,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -693,7 +734,8 @@ # ^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -707,19 +749,23 @@ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -742,7 +788,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell