feat: context-sensitive completions — cursor-aware filtering & type suggestions#530
Merged
tnaum-ms merged 27 commits intofeature/shell-integrationfrom Mar 18, 2026
Merged
Conversation
Implements detectCursorContext() - a pure function that determines the semantic position of the cursor within a DocumentDB query expression. Supports: key, value, operator, array-element, and unknown positions. Uses backward character scanning (no AST parsing) for robustness with incomplete/mid-typing input. Includes 41 tests covering: - Core context detection (complete expressions) - Incomplete/broken input (Step 1.5 from plan) - Multi-line expressions - fieldLookup integration for BSON type enrichment
Wire CursorContext into createCompletionItems() to filter completions based on the semantic cursor position: - key position: field names + key-position operators (, , etc.) - value position: BSON constructors only (ObjectId, UUID, ISODate) - operator position: comparison/element/array operators with type-aware sort - array-element: same as key position - unknown/undefined: full list (backward compatible) All 48 existing tests pass unchanged. 16 new context-sensitive tests added.
Call detectCursorContext() in provideCompletionItems to detect the semantic cursor position from editor text + offset. Pass the detected CursorContext through to createCompletionItems() for context-sensitive filtering. Includes field type lookup via completionStore to enrich context with BSON types for type-aware operator sorting.
Issue A - Strip outer braces from operator snippets at operator position:
{ $gt: ${1:value} } → $gt: ${1:value} (when inside { field: { | } })
Prevents double-brace insertion bug.
Issue B - Add category labels to completion items:
Uses CompletionItemLabel.detail for operator category (comparison, logical, etc.)
Uses CompletionItemLabel.description for operator description text.
Issue C - Value position now shows operators + BSON constructors:
Operators sorted first (0_), BSON constructors second (1_).
Operators keep their full brace-wrapping snippets at value position.
Also: trace-level console.debug logging in provideCompletionItems for debugging.
178 tests pass across 6 test suites. Build + lint clean.
- Remove 'detail' field from operator completions (was noisy) - Move category label to label.description (matches field items pattern) - Move entry.description to documentation (was in both detail and desc) - Combine description text + docs link in documentation field - Add range/insertText to trace logging for snippet debugging
Root cause: Monaco snippet syntax interprets $gt as a variable
reference (variable 'gt'), which resolves to empty string for unknown
variables. Result: { $gt: ${1:value} } produces '{ : value }'.
Fix: escapeSnippetDollars() escapes $ before letters ($gt → \$gt)
while preserving tab stop syntax (${1:value} unchanged).
BSON constructors like ObjectId("${1:hex}") are unaffected.
This was the root cause of POC Observation 2 (T5 ⚠️ PARTIAL).
…estions
Refactor:
- Extract completion logic into completions/ folder:
- snippetUtils.ts: stripOuterBraces, escapeSnippetDollars
- mapCompletionItems.ts: operator/field → CompletionItem mapping
- typeSuggestions.ts: type-aware value suggestions (NEW)
- createCompletionItems.ts: main entry point with context branching
- index.ts: barrel exports
- documentdbQueryCompletionProvider.ts now re-exports from completions/
New feature — type-aware value suggestions at value position:
- bool fields → true, false (as first completions)
- int/double/long/decimal → range query { $gt: ▪, $lt: ▪ }
- string → regex snippet, empty string literal
- date → ISODate constructor, date range snippet
- objectid → ObjectId constructor
- null → null literal
- array → $elemMatch, $size snippets
Suggestions get sort prefix 00_ (before operators at 0_).
First suggestion is preselected.
197 tests pass across 6 suites. Build + lint clean.
The schema analyzer uses BSONTypes enum strings ('boolean', 'int32',
'decimal128') while the type suggestions used shortened names ('bool',
'int', 'decimal'). Fix the TYPE_SUGGESTIONS keys to match:
- bool → boolean
- int → int32
- decimal → decimal128
- Added: number (generic BSONTypes.Number)
Also noted the type-name mismatch between schema-analyzer BSONTypes
('int32') and documentdb-constants applicableBsonTypes ('int') —
tracked as a future normalization task.
Replace format pattern 'yyyy-MM-ddTHH:mm:ssZ' with a valid example '2025-01-01T00:00:00Z'. The format pattern was confusing — users typed over it with values like '2222-11-11T11:11:111' which fail ISODate validation. Also update date range snippet with realistic start/end dates.
11 tasks
… and improved sorting
… for unknown identifiers
Previously `new Daddddte()` was not flagged because the validator only handled CallExpression nodes. NewExpression has the same callee shape but was not visited. Now unknown constructors in `new Foo()` produce error diagnostics (red squiggles), and near-miss typos like `new Dae()` produce warnings.
Add Date.now(), Math.floor(), Math.ceil(), Math.round(), Math.min(), Math.max() as individual completion items alongside the class-level Date/Math entries. Removed the bare `Math` entry since the individual methods are more useful. All entries use sort prefix 4_ (after BSON constructors at 3_).
…_COMPLETION_META PROJECTION_COMPLETION_META was ['field:identifier'] which returned 0 static entries — projection operators ($slice, $elemMatch, $) and BSON constructors were never shown in project/sort editors. Added 'query:projection' and 'bson' to the meta preset.
Never use git add -f to override .gitignore. Files in docs/plan/ and docs/analysis/ are local planning documents excluded from the repo.
- Remove unnecessary escape in template literal (no-useless-escape) - Formatter-applied changes to imports and whitespace
Contributor
There was a problem hiding this comment.
Pull request overview
This PR enhances the documentdb-query Monaco language by making completions cursor-context-aware (key/value/operator/array-element) and by adding type-aware value suggestions and JS-global completions, plus associated refactoring and test coverage.
Changes:
- Add heuristic cursor context detection (
detectCursorContext) and wire it into the Monaco completion provider to filter/sort suggestions by cursor position. - Introduce type-aware value suggestions and restore JS global completions used by the
@mongodb-js/shell-bson-parsersandbox. - Fix projection/sort completion presets in
documentdb-constantsand refactor completion logic into a dedicatedcompletions/module with extensive new tests.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/webviews/documentdbQuery/registerLanguage.ts | Wires cursor context detection into Monaco completions; adds debug logging. |
| src/webviews/documentdbQuery/index.ts | Re-exports cursor context utilities. |
| src/webviews/documentdbQuery/documentdbQueryValidator.ts | Adds errors for unknown calls/constructors and supports NewExpression diagnostics. |
| src/webviews/documentdbQuery/documentdbQueryValidator.test.ts | Adds/updates tests for unknown identifiers and constructors. |
| src/webviews/documentdbQuery/documentdbQueryCompletionProvider.ts | Becomes a barrel re-export for the refactored completions module. |
| src/webviews/documentdbQuery/documentdbQueryCompletionProvider.test.ts | Expands tests for context-sensitive completions, sorting, snippet escaping, and type suggestions. |
| src/webviews/documentdbQuery/cursorContext.ts | New cursor context detector (heuristic backward scanning). |
| src/webviews/documentdbQuery/cursorContext.test.ts | New unit tests for cursor context detection across complete/incomplete inputs. |
| src/webviews/documentdbQuery/completions/createCompletionItems.ts | New context-sensitive completion routing and filtering logic. |
| src/webviews/documentdbQuery/completions/mapCompletionItems.ts | New mapping utilities for operators/fields with sorting & snippet handling. |
| src/webviews/documentdbQuery/completions/typeSuggestions.ts | New type-aware value suggestions shown at value position. |
| src/webviews/documentdbQuery/completions/jsGlobals.ts | New JS global completion items (Date/Math/RegExp/etc.). |
| src/webviews/documentdbQuery/completions/snippetUtils.ts | New utilities for brace stripping and $ escaping in Monaco snippets. |
| src/webviews/documentdbQuery/completions/completionKnowledge.ts | New centralized completion rules/constants (key-only operators, placeholders). |
| src/webviews/documentdbQuery/completions/index.ts | New module barrel exports. |
| src/webviews/documentdbQuery/completions/README.md | Documents completion architecture and sorting tiers. |
| packages/documentdb-constants/src/metaTags.ts | Fixes projection/sort preset to include projection operators and BSON constructors. |
| packages/documentdb-constants/src/getFilteredCompletions.test.ts | Updates tests to validate the new projection preset behavior. |
| packages/documentdb-constants/src/bsonConstructors.ts | Updates ISODate snippet placeholder to an example timestamp. |
| .github/copilot-instructions.md | Adds git safety guidance (avoid git add -f, don’t commit planning docs). |
src/webviews/documentdbQuery/completions/createCompletionItems.ts
Outdated
Show resolved
Hide resolved
src/webviews/documentdbQuery/completions/createCompletionItems.ts
Outdated
Show resolved
Hide resolved
Tests were using 'int' but the schema analyzer produces 'int32' (BSONTypes.Int32). Also fixed applicableBsonTypes in documentdb-constants bitwise operators to use 'int32' to match, which was a real production mismatch.
When cursorContext is undefined or 'unknown', show the full set of completions (fields, all operators, BSON constructors, JS globals) instead of only key-position items. This is a better UX fallback — when context can't be determined, the user is better served by seeing everything available.
These debug logs were used during development and logged full editor text and completion items to the webview console on every keystroke. Removed to avoid unnecessary noise and potential data exposure.
…nd include JS globals
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.
Step 4.5: Context-Sensitive Completions
Adds cursor-position-aware completion filtering to the
documentdb-querylanguage. Instead of showing all operators at every cursor position, completions are filtered based on the semantic context of where the cursor sits in the query expression.Changes
Cursor context detection (
cursorContext.ts)Context-sensitive filtering
{ | }$and,$or,$nor){ age: | }{ age: { | } }$gt,$eq,$in...) with stripped braces{ $and: [ | ] }Type-aware value suggestions (
typeSuggestions.ts)When the field BSON type is known from the schema, contextual suggestions appear first (sort prefix
00_):true,false{ $gt: …, $lt: … }range query,{ $gte: … }{ $regex: /…/ },{ $regex: /\.com$/ },""ISODate("…"), date range,{ $gt: new Date(Date.now() - …) }ObjectId("…"){ $elemMatch: { … } },{ $size: … }nullType-aware operator sorting
When the field type is known, operators are sorted by relevance:
0_— Type-relevant (operator'sapplicableBsonTypesmatches the field)1a_— Comparison operators (universal, most commonly used)1b_— Other universal operators ($exists,$type,$mod)2_— Non-matching operators (demoted, not hidden)3_— BSON constructors (ObjectId,ISODate)4_— JS globals (Date,Math,RegExp,Infinity)JavaScript global completions (
jsGlobals.ts)Restored JS globals that were lost when the custom
documentdb-querylanguage replaced the built-in Monaco JS worker:Date(→new Date($1)),RegExpDate.now(),Math.floor(),Math.ceil(),Math.round(),Math.min(),Math.max()Infinity,NaN,undefinedSource:
@mongodb-js/shell-bson-parsersandbox scope (the same runtime that executes queries).Completion knowledge configuration (
completionKnowledge.ts)Centralised domain rules for the completion provider:
KEY_POSITION_OPERATORS— operators valid only at root/key position ($and,$or,$nor, etc.)LABEL_PLACEHOLDER— the…character for completion labelsINFO_INDICATOR— theℹcharacter for descriptionsField completion improvements
fieldName: |(snippet with cursor at value position)label.descriptionValidator enhancements
Unknown function 'XyzAbc'. Expected a BSON constructor or a known global.newconstructors → red error:Unknown constructor 'Daddddte'.Did you mean 'ObjectId'?Projection/sort fix
PROJECTION_COMPLETION_METAwas['field:identifier']returning 0 static entries — projection operators ($slice,$elemMatch,$) and BSON constructors were never shown in project/sort editors. Fixed by adding'query:projection'and'bson'to the preset.Bug fixes
$gtsnippet producing{ : value }—$was interpreted as a Monaco snippet variable$and/$orat key positionRefactoring
Extracted monolithic
documentdbQueryCompletionProvider.tsintocompletions/folder:createCompletionItems.ts— main entry, context branchingmapCompletionItems.ts— operator/field → CompletionItem mappingtypeSuggestions.ts— type-aware value suggestionsjsGlobals.ts— JS globals from shell-bson-parser sandboxcompletionKnowledge.ts— curated domain rulessnippetUtils.ts— snippet text manipulationREADME.md— architecture and sorting documentationTests