
Beekeeper Studio UI Kit 的 bks-sql-text-editor 组件SQL 智能补全、格式化与 LSP 集成实战指南【免费下载链接】beekeeper-studioModern and easy to use SQL client for MySQL, Postgres, SQLite, SQL Server, and more. Linux, MacOS, and Windows.项目地址: https://gitcode.com/GitHub_Trending/be/beekeeper-studiobks-sql-text-editor是 Beekeeper Studio UI Kitbeekeeperstudio/ui-kit中专门面向 SQL 查询场景的文本编辑器 Web Component。它完整继承通用bks-text-editor的全部能力含 Language Server Protocol 支持并叠加了 SQL 专用的自动补全、SQL 格式化、查询选择query selection识别等特性。本文以 SQL Text Editor 官方文档 为骨架结合仓库中组件的真实源码讲解如何在自己的应用中集成 SQL 编辑器、配置表结构自动补全、接入格式化预设以及通过 LSP 获得诊断、悬停提示等能力读完即可上手构建一个具备桌面级体验的 SQL 编辑界面。组件定位SQL 专属的文本编辑器bks-sql-text-editor不是从零实现的另一个编辑器而是对 Text Editor 组件 的 SQL 化扩展它继承通用文本编辑器的全部功能包括语言服务器协议LSP支持、自定义快捷键、CodeMirror 扩展替换、上下文菜单定制等在此之上增加 SQL 领域能力基于实体表/视图元数据的自动补全、基于 sql-formatter 的SQL 格式化、基于 sql-query-identifier 的查询选择识别底层由 CodeMirror 6 驱动语法高亮、行号、代码折叠等编辑器基础设施天然具备。从源码结构看组件目录 apps/ui-kit/lib/components/sql-text-editor/ 下既有 Vue 实现SqlTextEditor.vue、SqlTextEditor.ts也有一组独立的 CodeMirror 扩展extensions/目录说明 SQL 能力是通过扩展管线注入编辑器的具体见文末“源码级解读”一节。快速上手最小可用的 SQL 编辑器在页面中引入自定义元素bks-sql-text-editor通过 DOM 属性即可设置内容与补全数据bks-sql-text-editor/bks-sql-text-editor script const sqlTextEditor document.querySelector(bks-sql-text-editor); sqlTextEditor.entities [ { name: users, schema: public, columns: [ { field: id, dataType: integer }, { field: name, dataType: string }, ], }, ]; sqlTextEditor.value SELECT * FROM users; /scriptvalue编辑器当前文本继承自 Text Editor默认entities用于自动补全的实体表元数据列表格式与bks-entity-list组件的entities属性一致详见 Entity API。安装依赖npm install beekeeperstudio/ui-kitSQL 自动补全实体与列名智能提示自动补全是 SQL 编辑器最核心的体验。组件提供两种数据来源按需选择方式一静态entities列表直接将表与列结构赋值给entities属性编辑器会在输入表名、列名时给出补全建议sqlTextEditor.entities [ { name: users, schema: public, columns: [ { field: id, dataType: integer }, { field: name, dataType: string }, ], }, ];方式二动态columnsGetter回调当表数量庞大、列信息需要按需从后端加载时可用columnsGetter代替entities.columns输入表名后组件会以“schema 名如有 实体名”的组合作为参数调用该函数返回该表的列列表支持同步或异步函数sqlTextEditor.columnsGetter async (entityName) { const columns await fetchColumns(entityName); return [ { field: id, dataType: integer }, { field: name, dataType: string }, ]; };默认 Schema 与优先级defaultSchema用于指定自动补全时的默认 schema匹配该 schema 的实体会在补全列表中优先展示默认值为public。多 schema 场景下这一属性让“当前所在 schema 的表”始终排在前面。补全关键字与标识符引用策略从 props.ts 源码 可以看到组件还提供了三个与补全细节相关的属性属性类型默认值说明keywordCasingstringpreserve补全关键字/内置函数的大小写策略preserve跟随已输入前缀SEL→SELECTsel→select无前缀时大写upper/lower强制统一大小写quoteIdentifiersstringauto补全标识符的引号策略auto仅对方言无法裸引用的名字加引号always对一切非全小写的名字都加引号quoteCharacterstringundefined加引号时使用的引号字符例如 SQL Server 用[而非仅当方言认可该字符为标识符引用符时生效否则回退到方言默认SQL 格式化方言、配置与格式化预设组件内置 SQL 格式化能力底层基于 sql-formatter并可通过属性精确控制输出。选择方言与标识符引用方言属性类型默认值说明formatterDialectstringsql格式化使用的 SQL 方言取值见 sql-formatter 的 language 列表如mysql、postgresql、sqlite等identifierDialectstringgeneric标识符引用identifier quoting使用的方言取值见 sql-query-identifier 的 dialect 选项如mysql、sqlserver注意formatterDialect影响的是格式化后的缩进、关键字换行等排版规则identifierDialect影响的是对查询中标识符的引用方式判定用于查询选择识别与引号处理两者语义不同。formatterConfig格式化选项formatterConfig是传给 SQL 格式化器的配置对象。根据 props.ts 中定义的默认值核心字段如下sqlTextEditor.formatterConfig { id: null, // 用于追踪当前选中的格式化预设 tabWidth: 2, // 缩进宽度 useTabs: false, // 是否用 Tab 缩进 keywordCase: preserve, // 关键字大小写preserve/upper/lower dataTypeCase: preserve, // 数据类型大小写 functionCase: preserve, // 函数名大小写 logicalOperatorNewline: before, // 逻辑运算符换行位置 expressionWidth: 50, // 表达式换行宽度 linesBetweenQueries: 1, // 查询之间空行数 denseOperators: false, // 运算符是否紧凑 newlineBeforeSemicolon: false, // 分号前是否换行 };该对象要求包含id属性用于关联选中的格式化预设。格式化预设菜单allowPresets 与 presets属性类型默认值说明allowPresetsbooleanfalse启用后在右键菜单“Format Query”项下增加子菜单展示可用的格式化预设presetsobject[][]格式化预设数组每个预设需包含id、name、config三个字段仅在allowPresets为true时用于填充子菜单sqlTextEditor.allowPresets true; sqlTextEditor.presets [ { id: 1, name: My Style, config: { tabWidth: 4, keywordCase: upper, linesBetweenQueries: 2 }, }, ];当用户在上下文菜单中选择某个预设时组件抛出bks-apply-preset事件事件详情为{ id: number, ...config }由宿主应用接收并应用该预设例如持久化到用户设置。仓库中 Beekeeper Studio 主应用即借助这一机制实现可配置的 SQL 格式化预设相关迁移见 20250831_create_formatter_presets.js。提示组件的格式化能力还支持自定义 sql-formatter 方言对象formatterDialectOptions如 PartiQL 等内置语言之外的自定义方言优先级高于formatterDialect适合有特殊方言需求的应用。查询选择识别bks-query-selection-change 事件组件基于 sql-query-identifier 将编辑器内容切分为独立的查询并在选区变化时发出事件事件说明事件详情bks-query-selection-change查询选择发生变化时触发{ selectedQuery: IdentifyResult, queries: IdentifyResult[] }该事件常用于实现“运行当前选中查询”类功能监听事件拿到selectedQuery即可只执行光标所在的 SQL 语句而不必发送整个编辑器内容。identifierDialect与paramTypes属性会影响查询识别结果sqlTextEditor.paramTypes { // sql-query-identifier 支持的参数类型配置例如 :name 形式的命名参数 };继承自 Text Editor 的通用能力由于 SQL 编辑器继承通用文本编辑器以下能力开箱即用完整 API 见 Text Editor API。编辑器基础属性属性类型默认值说明valuestring编辑器文本内容readOnlyboolean|stringfalse禁用编辑传nocursor时同时禁用聚焦keybindingsobjectundefined自定义快捷键键为组合名、值为函数如{ Ctrl-Enter: submit, Cmd-Enter: submit }keymapstringdefault键位方案default/vim/emacs/sublimelineWrappingbooleanfalse是否自动换行focusbooleanfalse控制或观察编辑器聚焦状态contextMenuItemsarray|functionundefined向上下文菜单追加自定义项lineNumbersbooleantrue是否显示行号lsConfigLanguageServerConfigurationundefinedLSP 集成配置见下文replaceExtensionsExtension[]|(extensions) Extension[]undefined替换或修改默认 CodeMirror 扩展SQL 编辑器默认以sql作为 LSP 的languageId这一点与通用编辑器不同。自定义快捷键示例sqlTextEditor.keybindings { Ctrl-Enter: () runCurrentQuery(), Cmd-Enter: () runCurrentQuery(), };替换 CodeMirror 扩展replaceExtensions可以接收一个“返回新列表”的函数在默认扩展基础上追加或直接传入一个扩展数组整体替换默认扩展import { monokaiInit } from uiw/codemirror-theme-monokai; // 在默认扩展基础上追加主题 sqlTextEditor.replaceExtensions (defaultExtensions) { return [...defaultExtensions, monokaiInit({ settings: { selection: , selectionMatch: } })]; }; // 完全替换默认扩展 sqlTextEditor.replaceExtensions [myCustomExtension, keymap.of([...customKeymap])];主题定制CSS 变量SQL 编辑器继承的通用编辑器支持通过 CSS 变量定制语法高亮、背景、行号等视觉元素例如.BksTextEditor { --bks-text-editor-bg-color: white; --bks-text-editor-fg-color: rgba(0, 0, 0, 0.87); --bks-text-editor-keyword-fg-color: #ff00f0; --bks-text-editor-string-fg-color: rgb(12.075, 125.925, 85.675); --bks-text-editor-gutter-bg-color: white; --bks-text-editor-linenumber-fg-color: rgba(0, 0, 0, 0.25); }完整变量清单active line、bracket、comment、number、variable、function、type 等数十个配色变量见 text-editor.md 的 Customization 章节。与上下文菜单定制相关的说明见 Context Menu 文档。接入 LSP补全、诊断、悬停与格式化SQL 编辑器继承了 Text Editor 的完整 LSP 能力可连接任意实现了 Language Server Protocol 的语言服务器如 SQL 语言服务器获得智能补全、实时诊断、悬停信息、签名帮助、语义化高亮、跳转定义、重命名与代码操作等特性。完整指南见 Language Server Protocol 文档。配置 lsConfigsqlTextEditor.lsConfig { languageId: sql, // 必填语言标识 rootUri: /path/to/project, // 必填工作区根 URI documentUri: /path/to/project/query.sql, // 必填当前文档 URI transport: { wsUri: ws://localhost:3000/lsp }, // 必填WebSocket 传输 timeout: 10000, // 可选请求超时毫秒默认 10000 };transport也可以传open-rpc/client-js的WebSocketTransport实例以获得更细粒度的连接控制import { WebSocketTransport } from open-rpc/client-js; const transport new WebSocketTransport(ws://localhost:3000/server); sqlTextEditor.lsConfig { languageId: sql, rootUri: /path, documentUri: /path/query.sql, transport };LSP 功能开关lsConfig.features可逐项启用/禁用 LSP 能力默认全部开启配置项说明默认值hoverEnabled悬停信息truecompletionEnabled代码补全truediagnosticsEnabled错误/警告诊断truesignatureHelpEnabled函数签名帮助truesemanticTokensEnabled语义化高亮truedefinitionEnabled跳转定义truerenameEnabled重命名truecodeActionsEnabled代码操作truesignatureActivateOnTyping输入时实时显示签名帮助false通过 LSP Helpers 主动请求组件在 LSP 客户端就绪后触发bks-lsp-ready事件事件详情含服务端capabilities。务必在该事件之后再通过ls()方法获取 LSP Helpers 发起主动请求sqlTextEditor.addEventListener(bks-lsp-ready, async () { const helpers sqlTextEditor.ls(); // 格式化整个文档 await helpers.formatDocument({ tabSize: 2, insertSpaces: true }); // 请求语义化 token 并应用到文档返回结果 ID可用于增量请求 const resultId await helpers.requestSemanticTokens(); // 获取底层 client 后发送自定义 LSP 请求 const client helpers.getClient(); await client.request({ method: workspace/executeCommand, params: { command: fixAllFixableProblems }, }); });Helpers 的完整 APIgetClient、formatDocument、formatDocumentRange、requestSemanticTokens以及LSP.FormattingOptions、LSP.Range、LSP.Position的数据结构见 Language Server Helpers API。使用 LSP 需要自行运行一个可通过 WebSocket 访问的语言服务器。例如 JavaScript/TypeScript 场景npm install -g typescript-language-server typescript再通过额外工具将语言服务器暴露为 WebSocket 端点。Entity 数据模型补全的数据契约entities中每个实体的结构Entity API决定了自动补全能提示到什么粒度。表 / 视图 / 物化视图属性类型必填说明idstring否唯一标识默认由entityTypeschemaname组合生成namestring是实体名entityTypetable|view|materialized-view|否实体类型schemastring否Schema 名columnsTableColumn[]否列列表TableColumn接口属性类型必填说明fieldstring是列名dataTypestring否列数据类型存储过程 / 函数Routine属性类型必填说明idstring否唯一标识默认组合生成namestring是例程名entityTyperoutine是必须为routineschemastring否Schema 名returnTypestring是返回类型returnTypeLengthnumber否返回类型长度如适用routineParamsRoutineParam[]否参数列表RoutineParam接口name必填参数名、type必填参数数据类型、length可选参数长度。Schema属性类型必填说明idstring否唯一标识默认由entityTypename组合namestring是Schema 名entityTypeschema是必须为schema事件一览除 LSP 相关事件外SQL 编辑器还暴露如下事件其中前两个为 SQL 专属其余继承自 Text Editor事件说明事件详情bks-query-selection-change查询选择变化SQL 专属{ selectedQuery, queries }bks-apply-preset从上下文菜单选择格式化预设SQL 专属{ id: number, ...config }bks-value-change文本内容变化{ value: string }bks-initialized编辑器初始化完成{ editor: TextEditor }bks-focus/bks-blur聚焦 / 失焦{ event: FocusEvent }bks-lsp-readyLSP 客户端就绪{ capabilities: object }源码级解读SQL 能力是如何注入的从源码看SQL 编辑器的能力由一组 CodeMirror 扩展构成见 extensions/index.tsexport function extensions(config: SQLExtensionsConfig) { return [ sql(config), // SQL 语法支持与语言配置 sqlHighlighter, // SQL 语法高亮 removeQueryQuotesExtension(), // 查询选中时的引号处理 sqlContextComplete(), // 上下文感知补全 config.columnsGetter ? sqlCompletionSource(config.columnsGetter) : [], // 列名动态补全 querySelection(config.identiferDialect, config.paramTypes, config.onQuerySelectionChange), // 查询切分与选择识别 ]; }这段代码印证了前文内容sqlContextComplete与sqlCompletionSource分别对应entities静态补全与columnsGetter动态补全两条路径querySelection直接消费identifierDialect与paramTypes产出bks-query-selection-change事件扩展目录还包含 customSql.ts自定义 SQL 方言/关键字配置与 removeQueryQuotes.ts选中查询引号剥离用于执行片段时去掉多余引号。属性侧的完整定义位于 props.ts它直接继承通用编辑器的 props并叠加本文所述的 SQL 专属属性——这正是“继承 扩展”架构的落地体现。完整示例一个带补全与格式化的 SQL 查询面板综合以上内容组装一个具备补全、查询选择监听与预设格式化的完整用法bks-sql-text-editor idsql-editor/bks-sql-text-editor script const editor document.getElementById(sql-editor); // 1. 静态实体补全也可改用 columnsGetter 按需加载列 editor.entities [ { name: users, schema: public, columns: [{ field: id, dataType: integer }, { field: name, dataType: string }] }, { name: orders, schema: public, columns: [{ field: id, dataType: integer }, { field: user_id, dataType: integer }] }, ]; editor.defaultSchema public; // 2. 格式化配置MySQL 方言 统一大写关键字 editor.formatterDialect mysql; editor.formatterConfig { id: my-style, tabWidth: 4, keywordCase: upper, linesBetweenQueries: 2 }; // 3. 格式化预设子菜单 editor.allowPresets true; editor.presets [ { id: 1, name: Compact, config: { tabWidth: 2, linesBetweenQueries: 1 } }, { id: 2, name: Expanded, config: { tabWidth: 4, linesBetweenQueries: 2 } }, ]; editor.addEventListener(bks-apply-preset, (e) { // 应用选中预设可持久化到用户设置 console.log(preset applied:, e.detail); }); // 4. 监听查询选择变化实现“运行当前查询” editor.addEventListener(bks-query-selection-change, (e) { const { selectedQuery } e.detail; if (selectedQuery) runQuery(selectedQuery.text); }); // 5. 初始内容 editor.value SELECT * FROM users;; /script小结bks-sql-text-editor是一个“开箱即用”的 SQL 编辑组件以通用文本编辑器为基础用 CodeMirror 扩展注入 SQL 语法高亮、实体自动补全、格式化与查询识别并通过 LSP 对接语言服务器获得智能诊断与补全。实际接入时只需关注三个层面补全准备entities元数据或提供columnsGetter按需加载列格式化设置formatterDialect/formatterConfig如需预设菜单则开启allowPresets并监听bks-apply-preset查询执行监听bks-query-selection-change拿到当前查询片段配合 LSPlsConfigbks-lsp-ready即可构建完整的 SQL 工作台。可继续阅读 SQL Text Editor API、Text Editor API 与 Language Server Protocol 文档 获取全部属性与事件定义或在 Beekeeper Studio 主应用TabQueryEditor.vue中观察该组件在生产环境中的真实用法。【免费下载链接】beekeeper-studioModern and easy to use SQL client for MySQL, Postgres, SQLite, SQL Server, and more. Linux, MacOS, and Windows.项目地址: https://gitcode.com/GitHub_Trending/be/beekeeper-studio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考