Skip to content

VSCode 插件开发第二课:语法高亮与基础功能

基于第一课的项目结构,为 tdh-sql 扩展添加语法高亮、代码片段和基础语言配置。

回顾:项目骨架

第一课我们创建了插件项目骨架。现在 package.json 大致如下:

json
{
  "name": "tdh-sql",
  "displayName": "TDH SQL Support",
  "version": "0.0.1",
  "engines": { "vscode": "^1.85.0" },
  "categories": ["Programming Languages"],
  "contributes": {},
  "activationEvents": []
}

一、语法高亮 (TextMate Grammar)

VSCode 使用 TextMate 语法 来实现语法高亮。通过正则表达式定义 token 类型,编辑器会自动上色。

1.1 创建语法文件

在项目根目录创建 syntaxes/tdh-sql.tmLanguage.json

json
{
  "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
  "name": "TDH SQL",
  "scopeName": "source.tdh-sql",
  "patterns": [
    {
      "name": "comment.line.double-dash.tdh-sql",
      "match": "--.*$"
    },
    {
      "name": "keyword.control.tdh-sql",
      "match": "\\b(SELECT|FROM|WHERE|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|JOIN|ON|HAVING|GROUP|ORDER|BY|AS|INTO|SET|VALUES)\\b"
    },
    {
      "name": "constant.numeric.tdh-sql",
      "match": "\\b\\d+(\\.\\d+)?\\b"
    },
    {
      "name": "string.quoted.single.tdh-sql",
      "match": "'[^']*'"
    },
    {
      "name": "support.function.tdh-sql",
      "match": "\\b(COUNT|SUM|AVG|MAX|MIN|COALESCE|CAST|CONCAT|SUBSTR|NVL)\\b"
    },
    {
      "name": "storage.type.tdh-sql",
      "match": "\\b(INT|BIGINT|VARCHAR|STRING|DATE|TIMESTAMP|DECIMAL|BOOLEAN|DOUBLE|FLOAT)\\b"
    }
  ]
}

1.2 注册语法

package.jsoncontributes 中添加:

json
{
  "contributes": {
    "languages": [{
      "id": "tdh-sql",
      "aliases": ["TDH SQL", "tdh-sql"],
      "extensions": [".tdhsql", ".tdh"],
      "configuration": "./language-configuration.json"
    }],
    "grammars": [{
      "language": "tdh-sql",
      "scopeName": "source.tdh-sql",
      "path": "./syntaxes/tdh-sql.tmLanguage.json"
    }]
  }
}

1.3 语言配置

创建 language-configuration.json,控制括号匹配、注释快捷键等:

json
{
  "comments": {
    "lineComment": "--",
    "blockComment": ["/*", "*/"]
  },
  "brackets": [
    ["(", ")"],
    ["[", "]"]
  ],
  "autoClosingPairs": [
    { "open": "(", "close": ")" },
    { "open": "'", "close": "'" }
  ],
  "surroundingPairs": [
    ["(", ")"],
    ["'", "'"]
  ]
}

效果:用户按下 Ctrl+/ 会自动添加 -- 注释,输入 ( 会自动补全 )

二、代码片段 (Snippets)

2.1 创建代码片段文件

创建 snippets/tdh-sql.json

json
{
  "SELECT statement": {
    "prefix": "sel",
    "body": [
      "SELECT ${1:*}",
      "FROM ${2:table_name}",
      "WHERE ${3:condition};"
    ],
    "description": "插入 SELECT 查询"
  },
  "INSERT statement": {
    "prefix": "ins",
    "body": [
      "INSERT INTO ${1:table_name}",
      "  (${2:columns})",
      "VALUES",
      "  (${3:values});"
    ],
    "description": "插入 INSERT 语句"
  },
  "CREATE TABLE": {
    "prefix": "ctab",
    "body": [
      "CREATE TABLE ${1:table_name} (",
      "  ${2:column1} ${3:STRING},",
      "  ${4:column2} ${5:INT}",
      ");"
    ],
    "description": "创建表"
  }
}

2.2 注册代码片段

package.jsoncontributes 中添加:

json
{
  "contributes": {
    "snippets": [{
      "language": "tdh-sql",
      "path": "./snippets/tdh-sql.json"
    }]
  }
}

效果:用户在 .tdhsql 文件中输入 sel 再按 Tab,自动展开为完整的 SELECT 语句。

三、激活事件 (Activation Events)

3.1 基础事件

package.json 中设置激活时机:

json
{
  "activationEvents": [
    "onLanguage:tdh-sql"
  ]
}

常用激活事件:

事件触发时机
onLanguage:xxx打开指定语言的文件时
onCommand:xxx执行指定命令时
onView:xxx展开指定视图时
workspaceContains:xxx工作区包含匹配文件时
*启动时(不推荐,影响性能)

3.2 按需激活

最佳实践是尽可能精确地指定激活事件,减少启动开销:

json
{
  "activationEvents": [
    "onLanguage:tdh-sql",
    "onCommand:tdh-sql.format",
    "onCommand:tdh-sql.validate"
  ]
}

四、完整的 package.json

将以上整合后,package.json 结构如下:

json
{
  "name": "tdh-sql",
  "displayName": "TDH SQL Support",
  "description": "TDH SQL 语法高亮与代码片段支持",
  "version": "0.0.1",
  "publisher": "your-publisher-id",
  "engines": {
    "vscode": "^1.85.0"
  },
  "categories": ["Programming Languages"],
  "activationEvents": [
    "onLanguage:tdh-sql"
  ],
  "contributes": {
    "languages": [{
      "id": "tdh-sql",
      "aliases": ["TDH SQL", "tdh-sql"],
      "extensions": [".tdhsql", ".tdh"],
      "configuration": "./language-configuration.json"
    }],
    "grammars": [{
      "language": "tdh-sql",
      "scopeName": "source.tdh-sql",
      "path": "./syntaxes/tdh-sql.tmLanguage.json"
    }],
    "snippets": [{
      "language": "tdh-sql",
      "path": "./snippets/tdh-sql.json"
    }]
  }
}

五、调试与测试

F5 启动扩展开发宿主 (Extension Development Host),打开一个 .tdhsql 文件即可测试语法高亮和代码片段。

下一步

第三课将深入 LSP(Language Server Protocol),实现自动补全、错误诊断、跳转定义等高级功能。