如何语法高亮 VSCode tmlanguage.json 中的嵌套项?

How to syntax highlight nested items in VSCode tmlanguage.json?

如何在下图中用语法突出显示这部分:

function foo
  input x, default 123
  input y

  call z, x, y

基本上,任何嵌套在 中的东西都应该是黑色的,而“父”对象应该是其他颜色(理想情况下是灰色,但也可以是任何其他颜色)。我如何告诉它“模式:[#terms.gray 后跟#terms.black 或#strings]”之类的东西?

到目前为止我有这个:

鉴于此语法:

{
  "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
  "name": "myscript",
  "patterns": [
    {
      "include": "#terms"
    },
    {
      "include": "#punctuations"
    },
    {
      "include": "#strings"
    },
    {
      "include": "#numbers"
    },
    {
      "include": "#codes"
    }
  ],
  "repository": {
    "codes": {
      "patterns": [
        {
          "name": "constant.character.escape.language.myscript",
          "match": "\#\w+"
        }
      ]
    },
    "terms": {
      "patterns": [
        {
          "name": "term.language.myscript",
          "match": "([a-z][a-z0-9]*(?:-[a-z0-9]+)*)"
        }
      ]
    },
    "numbers": {
      "patterns": [
        {
          "name": "constant.numeric.integer.myscript",
          "match": "\b(\d+)\b"
        },
        {
          "name": "constant.numeric.decimal.myscript",
          "match": "\b(\d+\.\d+)\b"
        }
      ]
    },
    "punctuations": {
      "patterns": [
        {
          "name": "punctuation.separator.parameter.myscript",
          "match": ","
        },
        {
          "name": "punctuation.curly.open.myscript",
          "match": "\{"
        },
        {
          "name": "punctuation.curly.close.myscript",
          "match": "\}"
        }
      ]
    },
    "strings": {
      "name": "template.myscript",
      "begin": "\<",
      "beginCaptures": {
        "0": {
          "name": "string.quoted.other.myscript"
        }
      },
      "end": "\>",
      "endCaptures": {
        "0": {
          "name": "string.quoted.other.myscript"
        }
      },
      "patterns": [
        {
          "name": "constant.character.escape.myscript",
          "match": "\\."
        },
        {
          "include": "#codes"
        },
        {
          "name": "punctuation.term.myscript",
          "begin": "\{",
          "beginCaptures": {
            "0": {
              "name": "string.quoted.other.myscript"
            }
          },
          "end": "\}",
          "endCaptures": {
            "0": {
              "name": "string.quoted.other.myscript"
            }
          },
          "patterns": [
            {
              "include": "#terms"
            },
            {
              "include": "#numbers"
            },
            {
              "include": "#strings"
            },
            {
              "include": "#punctuations"
            },
            {
              "include": "#codes"
            }
          ]
        },
        {
          "name": "string.quoted.other",
          "match": "[^\#\{\}\>]+"
        }
      ]
    }
  },
  "scopeName": "source.myscript"
}

我可以这样开始:

"terms": {
  "patterns": [
    {
      "name": "term.language.myscript",
      "match": "([a-z][a-z0-9]*(?:-[a-z0-9]+)*) ([a-z][a-z0-9]*(?:-[a-z0-9]+)*)",
      "captures": {
        "1": {
          "name": "entity.name.function.myscript"
        },
        "2": {
          "name": "term.language.myscript"
        }
      }
    },
    {
      "name": "term.language.myscript",
      "match": "([a-z][a-z0-9]*(?:-[a-z0-9]+)*) (\d+)",
      "captures": {
        "1": {
          "name": "entity.name.function.myscript"
        },
        "2": {
          "name": "constant.numeric.integer.myscript"
        }
      }
    },

但这感觉就像一个 hack,我到处都在复制代码。

这似乎还可以:

{
  "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
  "name": "myscript",
  "patterns": [
    {
      "include": "#nestedtermsexternal"
    },
    {
      "include": "#nestedterms"
    },
    {
      "include": "#terms"
    },
    {
      "include": "#punctuations"
    },
    {
      "include": "#strings"
    },
    {
      "include": "#numbers"
    },
    {
      "include": "#codes"
    },
    {
      "include": "#comments"
    }
  ],
  "repository": {
    "comments": {
      "patterns": [
        {
          "name": "comment.line.number-sign.myscript",
          "match": "\# .+"
        }
      ]
    },
    "codes": {
      "patterns": [
        {
          "name": "constant.character.escape.language.myscript",
          "match": "\#\w+"
        }
      ]
    },
    "nestedtermsexternal": {
      "patterns": [
        {
          "name": "entity.language.myscript",
          "begin": "([a-z][a-z0-9]*(?:-[a-z0-9]+)*) ",
          "beginCaptures": {
            "1": {
              "name": "string.quoted.double.myscript"
            }
          },
          "end": "[,\n]",
          "patterns": [
            {
              "include": "#terms"
            },
            {
              "include": "#strings"
            },
            {
              "include": "#numbers"
            },
            {
              "include": "#codes"
            },
            {
              "include": "#comments"
            }
          ]
        }
      ]
    },
    "nestedterms": {
      "patterns": [
        {
          "name": "term.language.myscript",
          "begin": "([a-z][a-z0-9]*(?:-[a-z0-9]+)*)(\()",
          "beginCaptures": {
            "1": {
              "name": "string.quoted.double.myscript"
            },
            "2": {
              "name": "string.quoted.double.myscript"
            }
          },
          "end": "\)",
          "endCaptures": {
            "0": {
              "name": "string.quoted.double.myscript"
            }
          },
          "patterns": [
            {
              "include": "#comments"
            },
            {
              "include": "#terms"
            },
            {
              "include": "#strings"
            },
            {
              "include": "#numbers"
            },
            {
              "include": "#codes"
            }
          ]
        }
      ]
    },
    "terms": {
      "patterns": [
        {
          "name": "term.language.myscript",
          "match": "([a-z][a-z0-9]*(?:-[a-z0-9]+)*)"
        }
      ]
    },
    "numbers": {
      "patterns": [
        {
          "name": "constant.numeric.integer.myscript",
          "match": "\d+"
        },
        {
          "name": "constant.numeric.decimal.myscript",
          "match": "\d+\.\d+"
        }
      ]
    },
    "punctuations": {
      "patterns": [
        {
          "name": "punctuation.separator.parameter.myscript",
          "match": ","
        },
        {
          "name": "punctuation.curly.open.myscript",
          "match": "\{"
        },
        {
          "name": "punctuation.curly.close.myscript",
          "match": "\}"
        }
      ]
    },
    "strings": {
      "name": "template.myscript",
      "begin": "\<",
      "beginCaptures": {
        "0": {
          "name": "entity.name.type.myscript"
        }
      },
      "end": "\>",
      "endCaptures": {
        "0": {
          "name": "entity.name.type.myscript"
        }
      },
      "patterns": [
        {
          "include": "#codes"
        },
        {
          "name": "punctuation.term.myscript",
          "begin": "\{",
          "beginCaptures": {
            "0": {
              "name": "entity.name.type.myscript"
            }
          },
          "end": "\}",
          "endCaptures": {
            "0": {
              "name": "entity.name.type.myscript"
            }
          },
          "patterns": [
            {
              "include": "#nestedterms"
            },
            {
              "include": "#terms"
            },
            {
              "include": "#numbers"
            },
            {
              "include": "#strings"
            },
            {
              "include": "#punctuations"
            },
            {
              "include": "#codes"
            }
          ]
        },
        {
          "name": "entity.name.type",
          "match": "[^\#\{\}\>]+"
        },
        {
          "name": "entity.name.type",
          "match": "\#"
        }
      ]
    }
  },
  "scopeName": "source.myscript"
}