feat: mongo shell 补全增强 — 类型感知 / REPL / 排序 / snippet#12
Merged
Conversation
- 连接后/切库时预取当前库集合名,db. 补全无需先展开目录树 - mongoCompletion 拆分纯核 computeShellCompletion + 薄封装,新增值位置下拉 (sort→1/-1、投影→1/0、布尔键→true/false),复用值槽检测助手 - 新增 inline 幽灵文本(inlineHint + ghostText):被动提示单个最可能值, 与下拉互斥,Tab 接受、接受后自动清除 - ShellEditor 接入 ghostText() 与 Tab 优先级;.cm-ghost-text 样式 - 配套 computeShellCompletion / computeInlineHint 的 unit 测试
CodeMirror 6.20.2 对纯前缀匹配统一打 -100 分(不减标签长度), 导致 `db.live` 时 `lives` 与 `liveauthorizedviewers` 同分,回退到 字母序 → 长复合名反而靠前。给集合名/字段名按 `99 - len` 设 boost (CM 将 boost 直接加到匹配分),短名得分更高、稳定排在前;boost 限 在 [-99,99] 仅在前缀同分区间内重排,不会把散列匹配顶到前缀匹配之上。
NoSQLBooster/Compass 式做法的轻量自研版:渲染层 lazy Web Worker 跑 TS 语言服务,喂入手写的 mongo 基础 d.ts(Database/Collection/Cursor, 链式方法返回自身,匹配 shellCore shim 子集)+ 运行时按集合名生成的 interface Database 增强声明,靠 TS 真类型推导链式补全 (db.coll.find().sort(). 知道仍是 cursor、getSiblingDB(x). 是 Database、 const c = db.x.find(); c. 知道 c 是 Cursor)。 - shellCompletion: 成员访问(.后)走 TS,其余($算子/值槽/字段/全局)与 worker 不可用/超时/空结果时回退到现有正则源 mongoCompletionSource - 用 noLib + 紧凑内置 globals,避免把 ~30 个 lib.es*.d.ts 打进 worker; typescript 编译器被打成独立懒加载 chunk(~1.6MB gzip,不进主包) - 客户端 id-keyed pending/超时/崩溃透明回退(仿 serializerPool); 编辑器挂载时预热 worker;条目按 kind→type 映射、复用 lengthBoost 排序 - 配 buildCollectionDecls / isMemberCompletion 单测;typecheck + build 通过
TS 把集合声明为 Collection 属性,补全条目 kind=property → CM 默认渲染 □ 图标(property),与方法的 ƒ 混在一起显得"空白"。在 db. 成员场景下把 property 条目映射为 type:'class'(○)+ detail:'collection',方法保留 ƒ 并加 'db' 标注,恢复此前正则源的集合外观。
- 抽 completionRegistry.ts 作为补全"数据模型"单一真相源:算子(按
query/update/aggregate 上下文分组)、全局构造器、JS 关键字/字面量、
值表(sort/projection/boolean)、REPL 命令表,均带 category。
mongoCompletion/stageCompletion 改为消费它,扩展=改表不改正则
- 裸词位置新增 JS 关键字补全(const/function/return/debugger…),
原 true/false/null 归为字面量
- TS 方法条目渲染为调用 snippet:limit→limit(10)、find→find({ })、
sort→sort({ field: -1 })…,常用方法配模板、零参方法 name()、其余 name()
shellCore 预处理:整段恰为单条 REPL 命令时不走 vm,翻译成 driver 调用—— show dbs/databases→listDatabases、show collections/tables→listCollections、 show users/roles→usersInfo/rolesInfo、show profile→system.profile; use x→返回 ack + useDatabase 信号,渲染层据此 setActiveDatabase(并预取集合)。 混合脚本仍按 JS 执行(报错,与 mongosh 一致)。 - ShellResult 加 useDatabase 字段;parseReplCommand 纯解析(可单测) - 行首语句位置补全 show dbs/use 等(category=command,来自注册表) - 配 parseReplCommand 单测 + runReplCommand 集成测试(5 例,真实 mongo)
- 建议词加粗(fg-0)、匹配段强调色加粗;类型 detail 改为很淡(fg-3)、更小、 斜体,明显从标签后退 - 选中行从 CodeMirror 默认刺眼蓝改为应用 accent + accent-fg,detail 半透明 - 用 .cm-tooltip.cm-tooltip-autocomplete 提高优先级压过 CM 运行时注入样式
- Enter 改为保持当前行缩进(JS 缩进器会把续行的 .sort()/.project() 链
归零,丢掉手动缩进);开括号后加一级、{|} 时把闭括号下沉到新行。
下拉打开时让位给 Enter 接受补全。
- 零参方法(admin/toArray/itcount…)改用纯 `name()` apply 而非无字段
snippet:CM 对无字段 snippet 不设光标,会落在插入起点(db.|admin()),
纯字符串 apply 则把光标放在末尾(db.admin()|)。
- Tab 链入 nextSnippetField、Shift+Tab 链入 prevSnippetField,
多字段 snippet(sort/updateOne)可在占位间跳转而非插入制表符。
类型 detail 已用文字标明类别,CodeMirror 默认那套(○ 集合、□ 算子、 🔑 关键字/全局/命令、abc 值)反而是噪音。CSS 把这些 ::after content 置空; .cm-completionIcon 列宽固定 .8em,留白后标签仍对齐。
- tsAutocompleteClient: pending 改存 {resolve, timer},新增幂等 settle()
作为唯一收口;cancel() 真正丢弃在飞请求,快速输入不再累积 pending/timer
- ShellEditor: enterKeepIndent 用 range.from/to 替代 range.head,
对空光标与选区一致;更新 plain Enter 的陈旧注释
- completionRegistry: 删除 AGG_EXPR_OPERATORS 里重复的 $mergeObjects
- mongoCompletion: 补全 inString 文档,注明不处理模板串/注释的已知限制
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
迭代 mongo shell 编辑器的代码补全,对齐 NoSQLBooster / Compass 的体验(两者均逆向调研过:NoSQLBooster 用 Ace + 内嵌 TS 语言服务,Compass 用 CodeMirror 6 +
@mongodb-js/mongodb-ts-autocomplete)。本项目沿用 CodeMirror 6,采用「TS 语言服务 worker + 正则注册表」的混合架构。主要变更
db.补全无需先展开目录树。mongo.d.ts(匹配 shellCore shim 子集)+ 运行时生成的集合接口声明,db.coll.find().sort().等链式按真类型推导。typescript打成独立懒加载 chunk,不进主包。worker 不可用时透明回退到正则源。completionRegistry.ts作为「数据模型」单一真相源(算子按 query/update/aggregate 分组、全局、JS 关键字/字面量、值表、REPL 命令),扩展=改表。sort({ _id:处下拉1/-1,并有灰色幽灵提示(Tab 接受)。limit→limit(10)、find→find({ })、sort→sort({ field: -1 })…,Tab 在占位符间跳转。show dbs/databases/collections/tables/users/roles/profile、use x(切库信号);整段恰为单条命令时翻译成 driver 调用,混合脚本仍按 JS 执行。99-len设 boost,短名/近似匹配优先。ƒ(方法) 和𝑥(字段),其余留白。()后。测试
pnpm typecheck✅pnpm test:unit✅(343)pnpm test:integration✅(116,真实 MongoDB,含 REPL 命令)pnpm build✅(worker 独立 chunk)