This is an automated email from the ASF dual-hosted git repository.

jeremyyao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil-vscode.git


The following commit(s) were added to refs/heads/main by this push:
     new b83cb92  Document elementCompletion.ts and elementItems.ts in relation 
to documenting ElementCompletionProvider Intellisense functionaltiy
b83cb92 is described below

commit b83cb92afafe8209c4f0107b5a4c3ffe50e66969
Author: Jeremy Yao <[email protected]>
AuthorDate: Mon Jan 26 21:13:24 2026 -0500

    Document elementCompletion.ts and elementItems.ts in relation to 
documenting ElementCompletionProvider Intellisense functionaltiy
    
    Closes #1488
---
 src/language/intellisense-development.md           | 140 +++++++++++++-
 src/language/providers/elementCompletion.ts        | 208 +++++++++++++++++----
 .../providers/intellisense/elementItems.ts         | 116 +++++++-----
 3 files changed, 373 insertions(+), 91 deletions(-)

diff --git a/src/language/intellisense-development.md 
b/src/language/intellisense-development.md
index a4128c7..c148878 100644
--- a/src/language/intellisense-development.md
+++ b/src/language/intellisense-development.md
@@ -43,10 +43,12 @@ This document contains an overview of how Intellisense 
works, as well as a gener
           - [attributeValueCompletion.ts](#attributevaluecompletionts)
           - [closeElement.ts](#closeelementts)
           - [closeElementSlash.ts](#closeelementslashts)
+          - [elementCompletion.ts](#elementcompletionts)
           - [closeUtils.ts](#closeutilsts)
         - [Intellisense Data Files (intellisense 
subdirectory)](#intellisense-data-files-intellisense-subdirectory)
           - [attributeItems.ts](#attributeitemsts)
           - [attributeValueItems.ts](#attributevalueitemsts)
+          - [elementItems.ts](#elementitemsts)
         - [src/language/dfdl.ts](#srclanguagedfdlts)
     - [TDML](#tdml)
 
@@ -314,6 +316,77 @@ Hover tooltips can be found under `attributeHoverValues()` 
in `attributeHoverIte
 5. `checkItemsOnLine()` decides: self-closing tag, full closing tag, or nothing
 6. Inserts appropriate snippet at the correct position
 
+###### elementCompletion.ts
+
+**Purpose:** Element name completion provider for XML elements in DFDL schemas 
and TDML test files. Suggests valid child elements when the user presses 
newline inside an XML element.
+
+**Key Functionality:**
+
+- Provides context-aware element suggestions based on DFDL schema hierarchy 
and TDML structure
+- Respects DFDL schema relationships (e.g., inside `sequence` suggests 
`element`, `choice`, etc.)
+- Special handling for annotation/appinfo contexts to provide DFDL-specific 
elements based on parent type
+- Scans document for user-defined variables to populate `dfdl:setVariable` 
completion choices
+- Prevents suggestions when cursor is in inappropriate contexts (XPath, 
quotes, braces, after equals, inside open elements with no missing close tags)
+- Handles multi-item lines with complex cursor positioning logic
+- Dynamic namespace prefix handling (xs:, xsd:, dfdl:)
+- Separate provider implementations for DFDL (full validation) and TDML 
(simpler logic)
+
+**Key Functions:**
+
+- `getElementCompletionProvider()`: Main DFDL document provider registration
+- `getTDMLElementCompletionProvider()`: TDML document provider registration
+- `getElementCompletionItems()`: Creates completion items from elementItems.ts 
data based on context
+- `getDefinedVariables()`: Scans document for `dfdl:defineVariable` 
declarations to extract variable names
+- `nearestOpenTagChildElements()`: Core logic determining which child elements 
are valid for a given parent (main DFDL hierarchy switch statement)
+- `getAnnotationParent()`: Finds the parent element of an annotation to 
provide correct DFDL format elements in appinfo context
+- `getTagNearestTrigger()`: Complex algorithm to find the nearest tag to 
cursor position, handling single-line and multi-line scenarios
+
+**Trigger:** Newline (`\n`)
+
+**Architecture Notes:**
+
+- Uses **guard clauses** for early returns in invalid contexts
+- Implements **dual strategy**: robust DFDL provider vs. simpler TDML provider
+- **Complex multi-tag line handling**: Extensive logic for scenarios with 
multiple tags per line
+- **Appinfo context chaining**: Traverses annotation → appinfo → parent 
element to determine valid DFDL elements
+- **Dynamic completion construction**: Variable names dynamically added to 
`dfdl:setVariable` suggestions
+- **Provider pattern**: Registers as standard VS Code completion provider
+- **Progressive tab-stop navigation**: Uses `$1`, `$2`, `$0` for guided 
element construction
+
+**Dependencies:**
+
+- `closeUtils`: `checkMissingCloseTag()` for determining tag closure state
+- `utils`: Extensive use including `checkBraceOpen()`, `cursorWithinBraces()`, 
`cursorWithinQuotes()`, `cursorAfterEquals()`, `isInXPath()`, 
`isTagEndTrigger()`, `nearestOpen()`, `nearestTag()`, `getAttributeNames()`, 
`getItemsOnLineCount()`, `getNsPrefix()`, `createCompletionItem()`
+- `intellisense/elementItems`: `elementCompletion()` factory function for 
completion data
+- `XmlItem` class from utils for encapsulating parsed element data
+
+**DFDL Hierarchy Rules (from `nearestOpenTagChildElements()`):**
+
+The function implements the complete DFDL Schema hierarchy through a large 
switch statement:
+
+- `element` → `complexType`, `simpleType`, `annotation`
+- `sequence` → `element`, `sequence`, `choice`, `annotation`
+- `choice` → `element`, `sequence`, `group`, `annotation`
+- `group` → `sequence`, `annotation`
+- `complexType` → `sequence`, `group`, `choice`, `annotation`
+- `simpleType` → `annotation`, `restriction`
+- `annotation` → `appinfo`
+- `appinfo` → DFDL elements based on annotation parent (`dfdl:format`, 
`dfdl:element`, `dfdl:sequence`, etc.)
+- `assert/discriminator` → `CDATA`, `{}`
+- `schema` root → `sequence`, `element`, `choice`, `group`, `complexType`, 
`simpleType`, `annotation`, `include`, `import`, `defineVariable`
+- `emptySchema` → `xml version` declaration
+
+**Flow:**
+
+1. User presses newline inside an XML element
+2. Guard clauses validate context (not XPath, quotes, braces, after equals, 
inside properly closed element)
+3. Extract namespace prefix and scan for user-defined variables
+4. `nearestOpen()` finds the parent element at cursor position
+5. `getTagNearestTrigger()` determines which tag should trigger completion 
(handles multi-item lines)
+6. `nearestOpenTagChildElements()` uses switch statement to determine valid 
child elements for parent
+7. `getElementCompletionItems()` filters elementItems.ts data for valid 
elements only
+8. Returns completion items with proper namespace prefixes and documentation
+
 ###### closeUtils.ts
 
 **Purpose:** Core utility module providing tag state analysis functions for 
the auto-completion system. Determines whether XML/DFDL tags are properly 
closed and identifies unclosed tags that need completion.
@@ -406,8 +479,8 @@ Hover tooltips can be found under `attributeHoverValues()` 
in `attributeHoverIte
 **Attribute Categories:**
 
 - XSD Core Attributes (name, ref, type, minOccurs, maxOccurs)
-- DFDL Length Properties (dfdl: length, dfdl:lengthKind, dfdl:lengthUnits)
-- DFDL Encoding Properties (dfdl: encoding, dfdl:encodingErrorPolicy)
+- DFDL Length Properties (dfdl:length, dfdl:lengthKind, dfdl:lengthUnits)
+- DFDL Encoding Properties (dfdl:encoding, dfdl:encodingErrorPolicy)
 - DFDL Text/Binary Representation
 - DFDL Separators/Delimiters
 - DFDL Calendar/Date
@@ -449,16 +522,71 @@ Hover tooltips can be found under 
`attributeHoverValues()` in `attributeHoverIte
 - `noChoiceAttributes`: List of attributes without predefined choices
 - `attributeValues(attributeName, startPos, additionalTypes)`: Inserts 
appropriate snippet at cursor
 
+###### elementItems.ts
+
+**Purpose:** Static completion data for XML elements used in DFDL/XSD 
documents. Provides a complete catalog of XML/DFDL elements that can be 
suggested in different schema contexts, along with their snippet templates and 
documentation.
+
+**Data Structure:**
+
+- Factory function `elementCompletion(definedVariables, nsPrefix)` that 
returns an object with an `items` array
+- Each item contains:
+  - `item`: Element name (can include namespace prefix)
+  - `snippetString`: VS Code snippet with tab stops, placeholders, and default 
values
+  - `markdownString`: Documentation shown in completion tooltip
+
+**Snippet Features:**
+
+- **Tab stops**: `$1`, `$2`, `$0` for progressive navigation
+- **Choice placeholders**: `${1|option1,option2|}` for dropdown selections
+- **Dynamic variable insertion**: Uses `definedVariables` parameter to 
populate `dfdl:setVariable` ref attribute choices
+- **Namespace prefix handling**: Accepts `nsPrefix` parameter to customize 
snippets with correct namespace (xs:, xsd:, etc.)
+- **Multi-line templates**: Many elements include proper indentation and 
structure
+
+**Element Categories:**
+
+- **XML Declaration**: `xml version` - XML prolog with UTF-8 encoding
+- **XSD Core Elements**: `schema`, `element` (name/ref variants), 
`complexType`, `simpleType`, `sequence`, `choice`, `group`, `annotation`, 
`appinfo`, `restriction`, `include`, `import`
+- **DFDL Property Elements**: `dfdl:format`, `dfdl:property`, `dfdl:assert`, 
`dfdl:discriminator`, `dfdl:escapeScheme`
+- **DFDL Variable Elements**: `dfdl:defineVariable`, `dfdl:setVariable`, 
`dfdl:newVariableInstance`
+- **DFDL Format Definition Elements**: `dfdl:defineFormat`, 
`dfdl:defineEscapeScheme`
+- **DFDL Container Elements**: `dfdl:element`, `dfdl:sequence`, `dfdl:choice`, 
`dfdl:group`
+- **XSD Restriction Elements**: `minInclusive`, `minExclusive`, 
`maxInclusive`, `maxExclusive`, `pattern`, `totalDigits`, `fractionDigits`, 
`enumeration`
+- **Special Constructs**: `CDATA`, `{}` DFDL expression wrapper
+
+**Key Export:**
+
+- `elementCompletion(definedVariables, nsPrefix)`: **Factory function** that 
generates completion data dynamically based on:
+  - `definedVariables`: Comma-separated string of variable names for 
`dfdl:setVariable` dropdown
+  - `nsPrefix`: Namespace prefix to use for XSD elements (typically "xs:" or 
"xsd:")
+
+**Dynamic Behavior:**
+
+Unlike static attribute files, `elementItems.ts` is a **factory function** 
that constructs completion data at runtime. This enables:
+
+- Dynamic population of variable names from the document
+- Customizable namespace prefixes based on document context
+- Flexible snippet construction that adapts to schema conventions
+
+**Example Usage:**
+
+```typescript
+// In elementCompletion.ts
+const definedVariables = getDefinedVariables(document) // "var1,var2,var3"
+const nsPrefix = getNsPrefix(document, position) // "xs:"
+const elementData = elementCompletion(definedVariables, nsPrefix)
+// elementData.items now contains customized snippets with proper vars and 
prefixes
+```
+
 ##### src/language/dfdl.ts
 
 **Purpose:** The central registration file for all DFDL language features.
 
 **Key Functionality:**
 
-- **Starting Point:** It is executed during extension activation and registers 
the completion and hover providers with VS Code. This file is the “entry point” 
for Language features. If you want to add providers, this is the place to 
update.
-- **Central Rgistration Point:**It imports provider modules (element, 
attribute, attributeValue, closeElement, attributeHover, etc.) and registers 
them with appropriate trigger characters (e.g., `<`, `:`, `"`, `=`, `/`, 
`whitespace`).
-- **Wiring:**It does not perform completion logic itself — rather it wires VS 
Code events to the exported provider objects/functions in the provider modules.
-- **DFDL Language Provider:**When VS Code triggers a provider callback for the 
DFDL language, the registered provider function from the corresponding module 
is invoked.
+- **Starting Point:** It is executed during extension activation and registers 
the completion and hover providers with VS Code. This file is the "entry point" 
for Language features. If you want to add providers, this is the place to 
update.
+- **Central Registration Point:** It imports provider modules (element, 
attribute, attributeValue, closeElement, attributeHover, etc.) and registers 
them with appropriate trigger characters (e.g., `<`, `:`, `"`, `=`, `/`, 
`whitespace`).
+- **Wiring:** It does not perform completion logic itself — rather it wires VS 
Code events to the exported provider objects/functions in the provider modules.
+- **DFDL Language Provider:** When VS Code triggers a provider callback for 
the DFDL language, the registered provider function from the corresponding 
module is invoked.
 
 ##### src\language\providers\utils.ts
 
diff --git a/src/language/providers/elementCompletion.ts 
b/src/language/providers/elementCompletion.ts
index fea2132..f62056a 100644
--- a/src/language/providers/elementCompletion.ts
+++ b/src/language/providers/elementCompletion.ts
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 import * as vscode from 'vscode'
 import { checkMissingCloseTag, getCloseTag } from './closeUtils'
 import {
@@ -33,11 +32,41 @@ import {
   cursorAfterEquals,
 } from './utils'
 import { elementCompletion } from './intellisense/elementItems'
-
+/**
+ * Registers an element completion provider for DFDL language files.
+ * This provider suggests child elements when the user is inside an XML element
+ * and types a newline, helping to construct DFDL schema structures.
+ *
+ * **Trigger:** Newline character (`\n`)
+ *
+ * **Key Behaviors:**
+ * - Provides context-aware element suggestions based on the parent element
+ * - Respects DFDL schema hierarchy (e.g., inside `sequence` suggests 
`element`, `choice`, etc.)
+ * - Handles annotation/appinfo contexts specially for DFDL format definitions
+ * - Scans document for defined variables to include in completions
+ * - Prevents suggestions when cursor is in inappropriate contexts (XPath, 
quotes, braces, etc.)
+ */
 export function getElementCompletionProvider(dfdlFormatString: string) {
   return vscode.languages.registerCompletionItemProvider(
     'dfdl',
     {
+      /**
+       * Provides completion items when newline is pressed in a DFDL document.
+       * Determines which child elements are valid based on the current XML 
context.
+       *
+       * **Context Detection Flow:**
+       * 1. Check if cursor is in a valid context (not XPath, quotes, braces, 
etc.)
+       * 2. Find the nearest open parent element
+       * 3. Check if there are any unclosed tags that need completion
+       * 4. Determine which element is nearest to the cursor position
+       * 5. Return appropriate child elements for that parent
+       *
+       * @param document - The active text document
+       * @param position - The cursor position where newline was pressed
+       * @param token - Cancellation token for async operations
+       * @param context - Completion context including trigger character
+       * @returns Array of completion items or undefined
+       */
       provideCompletionItems(
         document: vscode.TextDocument,
         position: vscode.Position,
@@ -45,6 +74,9 @@ export function 
getElementCompletionProvider(dfdlFormatString: string) {
         context: vscode.CompletionContext
       ) {
         const triggerChar = context.triggerCharacter
+
+        // **GUARD CLAUSES**: Only provide completions in valid XML contexts
+        // Prevent completion inside XPath expressions, braces, quotes, after 
equals, or at tag ends
         if (
           !checkBraceOpen(document, position) &&
           !cursorWithinBraces(document, position) &&
@@ -58,24 +90,27 @@ export function 
getElementCompletionProvider(dfdlFormatString: string) {
           let triggerText = document.lineAt(triggerLine).text
           let itemsOnLine = getItemsOnLineCount(triggerText)
           let nearestOpenItem = nearestOpen(document, position)
+
+          // If we found an open item with a namespace, use that namespace
           if (nearestOpenItem.itemNS != 'none') {
             nsPrefix = nearestOpenItem.itemNS
           }
           let lastCloseSymbol = triggerText.lastIndexOf('>')
           let firstOpenSymbol = triggerText.indexOf('<')
-
           let missingCloseTag = checkMissingCloseTag(
             document,
             position,
             nsPrefix
           )
-
+          // **EARLY RETURN**: If inside an open element with no missing close 
tags, don't suggest
           if (
             !nearestOpenItem.itemName.includes('none') &&
             missingCloseTag == 'none'
           ) {
             return undefined
           }
+
+          // **EARLY RETURN**: For multi-item lines at specific positions, 
don't suggest
           if (
             missingCloseTag === 'none' &&
             itemsOnLine > 1 &&
@@ -84,9 +119,9 @@ export function 
getElementCompletionProvider(dfdlFormatString: string) {
           ) {
             return undefined
           }
-
+          // Scan document for user-defined variables to include in completions
           let definedVariables = getDefinedVariables(document)
-
+          // Find which tag is nearest to the cursor position
           let [tagNearestTrigger, tagPosition] = getTagNearestTrigger(
             document,
             position,
@@ -96,7 +131,7 @@ export function 
getElementCompletionProvider(dfdlFormatString: string) {
             itemsOnLine,
             nsPrefix
           )
-
+          // Return appropriate child elements for the parent context
           return nearestOpenTagChildElements(
             document,
             position,
@@ -108,10 +143,13 @@ export function 
getElementCompletionProvider(dfdlFormatString: string) {
         }
       },
     },
-    '\n'
+    '\n' // Triggered on newline
   )
 }
-
+/**
+ * Registers a simpler element completion provider for TDML files.
+ * TDML has less complex requirements than DFDL schemas.
+ */
 export function getTDMLElementCompletionProvider(tdmlFormatString: string) {
   return vscode.languages.registerCompletionItemProvider('tdml', {
     provideCompletionItems(
@@ -120,6 +158,7 @@ export function 
getTDMLElementCompletionProvider(tdmlFormatString: string) {
       token: vscode.CancellationToken,
       context: vscode.CompletionContext
     ) {
+      // **SIMPLER GUARD CLAUSES**: TDML uses less strict validation
       if (
         checkBraceOpen(document, position) ||
         cursorWithinBraces(document, position) ||
@@ -129,7 +168,6 @@ export function 
getTDMLElementCompletionProvider(tdmlFormatString: string) {
       ) {
         return undefined
       }
-
       let nsPrefix = getNsPrefix(document, position)
       let [triggerLine, triggerPos] = [position.line, position.character]
       let triggerText = document.lineAt(triggerLine).text
@@ -139,9 +177,7 @@ export function 
getTDMLElementCompletionProvider(tdmlFormatString: string) {
       let nearestOpenItem = xmlItem.itemName
       let lastCloseSymbol = triggerText.lastIndexOf('>')
       let firstOpenSymbol = triggerText.indexOf('<')
-
       let missingCloseTag = checkMissingCloseTag(document, position, nsPrefix)
-
       if (nearestOpenItem.includes('none')) {
         if (missingCloseTag !== 'none') {
           return undefined
@@ -153,9 +189,7 @@ export function 
getTDMLElementCompletionProvider(tdmlFormatString: string) {
         ) {
           return undefined
         }
-
         let definedVariables = getDefinedVariables(document)
-
         let [tagNearestTrigger, tagPosition] = getTagNearestTrigger(
           document,
           position,
@@ -165,7 +199,6 @@ export function 
getTDMLElementCompletionProvider(tdmlFormatString: string) {
           itemsOnLine,
           nsPrefix
         )
-
         return nearestOpenTagChildElements(
           document,
           position,
@@ -178,7 +211,16 @@ export function 
getTDMLElementCompletionProvider(tdmlFormatString: string) {
     },
   })
 }
-
+/**
+ * Creates completion items from the elementItems data structure.
+ * Filters items based on which elements are valid in the current context.
+ *
+ * @param itemsToUse - Array of element names that are valid in this context
+ * @param preVal - Prefix value to prepend (usually empty for elements)
+ * @param definedVariables - Comma-separated list of variable names for 
dfdl:setVariable completion
+ * @param nsPrefix - Namespace prefix to use (xs:, dfdl:, etc.)
+ * @returns Array of VS Code completion items
+ */
 function getElementCompletionItems(
   itemsToUse: string[],
   preVal: string = '',
@@ -186,10 +228,12 @@ function getElementCompletionItems(
   nsPrefix: string
 ) {
   let compItems: vscode.CompletionItem[] = []
-
+  // Iterate through all available element completions
   elementCompletion(definedVariables, nsPrefix).items.forEach((e) => {
     for (let i = 0; i < itemsToUse.length; ++i) {
+      // Check if this item matches one of the valid elements for this context
       if (e.item.includes(itemsToUse[i])) {
+        // Handle dfdl-prefixed items specially
         if (
           (e.item.includes('dfdl:') && itemsToUse[i].includes('dfdl:')) ||
           !e.item.includes('dfdl')
@@ -200,37 +244,65 @@ function getElementCompletionItems(
       }
     }
   })
-
   return compItems
 }
-
+/**
+ * Scans the document to find all dfdl:defineVariable declarations.
+ * Extracts variable names to populate the dropdown for dfdl:setVariable 
completion.
+ *
+ * @param document - The VS Code text document to scan
+ * @returns Comma-separated string of variable names, or empty string if none 
found
+ */
 function getDefinedVariables(document: vscode.TextDocument) {
   let additionalTypes = ''
   let lineNum = 0
   let itemCnt = 0
   const lineCount = document.lineCount
-
+  // Scan entire document line by line
   while (lineNum !== lineCount) {
     const triggerText = document
       .lineAt(lineNum)
       .text.substring(0, document.lineAt(lineNum).range.end.character)
-
+    // Look for variable definitions
     if (triggerText.includes('dfdl:defineVariable name=')) {
       let startPos = triggerText.indexOf('"', 0)
       let endPos = triggerText.indexOf('"', startPos + 1)
       let newType = triggerText.substring(startPos + 1, endPos)
-
+      // Build comma-separated list of variable names
       additionalTypes =
         itemCnt === 0 ? newType : String(additionalTypes + ',' + newType)
       ++itemCnt
     }
-
     ++lineNum
   }
-
   return additionalTypes
 }
-
+/**
+ * Determines which child elements are valid for a given parent element.
+ * This is the core logic for context-aware element completion in DFDL schemas.
+ *
+ * **DFDL Schema Hierarchy Rules:**
+ * - `element` can contain: `complexType`, `simpleType`, `annotation`
+ * - `sequence` can contain: `element`, `sequence`, `choice`, `annotation`
+ * - `choice` can contain: `element`, `sequence`, `group`, `annotation`
+ * - `complexType` can contain: `sequence`, `group`, `choice`, `annotation`
+ * - `simpleType` can contain: `annotation`, `restriction`
+ * - `annotation` → `appinfo` → DFDL format definitions
+ * - `schema` root can contain: `sequence`, `element`, `choice`, `group`, 
`complexType`, `simpleType`, `annotation`, `include`, `import`
+ *
+ * **Special Contexts:**
+ * - Inside `appinfo`: Provides DFDL-specific elements based on parent of 
annotation
+ * - `assert`/`discriminator`: Suggests CDATA and {} for expressions
+ * - Variable-related tags: Provide specific DFDL variable elements
+ *
+ * @param document - The VS Code text document
+ * @param position - The cursor position
+ * @param tagNearestTrigger - The parent element name
+ * @param tagPosition - Position of the parent element
+ * @param definedVariables - Comma-separated variable names for setVariable 
completion
+ * @param nsPrefix - Namespace prefix (xs:, dfdl:, etc.)
+ * @returns Array of completion items or undefined
+ */
 function nearestOpenTagChildElements(
   document: vscode.TextDocument,
   position: vscode.Position,
@@ -239,6 +311,7 @@ function nearestOpenTagChildElements(
   definedVariables: string,
   nsPrefix: string
 ) {
+  // **MAIN SWITCH**: Determine valid child elements based on parent tag
   switch (tagNearestTrigger) {
     case 'element':
       return getElementCompletionItems(
@@ -283,25 +356,35 @@ function nearestOpenTagChildElements(
         nsPrefix
       )
     case 'annotation':
+      // Annotation can only contain appinfo
       return getElementCompletionItems(['appinfo'], '', '', nsPrefix)
     case 'appinfo':
+      // Appinfo context requires special handling - need to find parent of 
annotation
       let triggerText = document.lineAt(tagPosition.line).text
       let iCount = getItemsOnLineCount(triggerText)
+
+      // Adjust position if needed for multi-line tags
       const newPosition =
         iCount < 2
           ? new vscode.Position(tagPosition.line - 1, tagPosition.character)
           : tagPosition
+
+      // Find the parent element that contains this annotation
       let [pElement, pPosition] = getAnnotationParent(
         document,
         newPosition,
         nsPrefix
       )
+
+      // Get attributes of the parent element
       let attributeNames: string[] = getAttributeNames(
         document,
         pPosition,
         nsPrefix,
         pElement
       )
+
+      // Provide DFDL-specific elements based on parent type
       switch (pElement) {
         case 'schema':
           return getElementCompletionItems(
@@ -354,6 +437,7 @@ function nearestOpenTagChildElements(
             nsPrefix
           )
         case 'group':
+          // Group behavior depends on whether it has a 'ref' attribute
           if (attributeNames.includes('ref')) {
             return getElementCompletionItems(
               [
@@ -397,8 +481,10 @@ function nearestOpenTagChildElements(
           return undefined
       }
     case 'assert':
+      // Assert can contain CDATA or expressions
       return getElementCompletionItems(['CDATA', '{}'], '', '', nsPrefix)
     case 'discriminator':
+      // Discriminator can contain CDATA or expressions
       return getElementCompletionItems(['CDATA', '{}'], '', '', nsPrefix)
     case 'defineFormat':
       return getElementCompletionItems(['dfdl:format'], '', '', nsPrefix)
@@ -411,6 +497,7 @@ function nearestOpenTagChildElements(
     case 'import':
       return getElementCompletionItems([''], '', '', nsPrefix)
     case 'schema':
+      // Root schema can contain many top-level elements
       return getElementCompletionItems(
         [
           'sequence',
@@ -429,14 +516,35 @@ function nearestOpenTagChildElements(
         nsPrefix
       )
     case 'xml version':
+      // After XML declaration, suggest schema
       return getElementCompletionItems(['schema'], '', '', '')
     case 'emptySchema':
+      // Empty document, suggest XML declaration
       return getElementCompletionItems(['xml version'], '', '', '')
     default:
       return undefined
   }
 }
-
+/**
+ * Finds the parent element of an annotation tag.
+ * In DFDL schemas, the content of `appinfo` depends on what element the 
annotation is attached to.
+ * This function traverses up to find that parent element.
+ *
+ * **Example:**
+ * ```xml
+ * <xs:element name="example">
+ *   <xs:annotation>
+ *     <xs:appinfo>|cursor here|</xs:appinfo>
+ *   </xs:annotation>
+ * </xs:element>
+ * ```
+ * Returns `['element', positionOfElement]`
+ *
+ * @param document - The VS Code text document
+ * @param tagPosition - Position within the annotation/appinfo
+ * @param nsPrefix - Namespace prefix
+ * @returns Tuple: [parentElementName, parentElementPosition]
+ */
 export function getAnnotationParent(
   document: vscode.TextDocument,
   tagPosition: vscode.Position,
@@ -456,9 +564,11 @@ export function getAnnotationParent(
     nsPrefix
   )
   pElement = nElement
-  //get parent of annotation tag
+
+  // If we found an annotation, we need to go up one more level to get the 
actual parent
   if (pElement === 'annotation') {
     if (iCount < 2) {
+      // Adjust position for multi-line cases
       newPosition = new vscode.Position(
         newPosition.line - 1,
         newPosition.character
@@ -479,7 +589,31 @@ export function getAnnotationParent(
   }
   return [pElement, pPosition]
 }
-
+/**
+ * Finds the nearest tag to the cursor position that should trigger completion.
+ * This is a complex function that handles single-line and multi-line tag 
scenarios.
+ *
+ * **Algorithm:**
+ * 1. For empty documents, returns special 'emptySchema' indicator
+ * 2. For multi-item lines: checks cursor position relative to tags
+ * 3. For single-item lines: walks up the document tree to find the 
appropriate parent
+ * 4. Uses `nearestTag()` and `getCloseTag()` to determine tag relationships
+ * 5. Handles edge cases where tags are unclosed or nested
+ *
+ * **Key Logic:**
+ * - On multi-tag lines, ensures cursor is positioned correctly between tags
+ * - Tracks tag closure state to find the nearest open tag
+ * - Adjusts search position based on nesting levels
+ *
+ * @param document - The VS Code text document
+ * @param position - The cursor position
+ * @param triggerText - Text of the current line
+ * @param triggerLine - Current line number
+ * @param triggerPos - Current character position
+ * @param itemsOnLine - Count of XML items on the line
+ * @param nsPrefix - Namespace prefix
+ * @returns Tuple: [nearestTagName, tagPosition]
+ */
 export function getTagNearestTrigger(
   document: vscode.TextDocument,
   position: vscode.Position,
@@ -491,7 +625,7 @@ export function getTagNearestTrigger(
 ): [string, vscode.Position] {
   let [startLine, startPos] = [triggerLine, triggerPos]
   let tagNearestTrigger = 'none'
-
+  // **SPECIAL CASE**: Empty document - return special indicator
   if (
     itemsOnLine === 0 &&
     document.lineCount === 1 &&
@@ -499,7 +633,7 @@ export function getTagNearestTrigger(
   ) {
     return ['emptySchema', position]
   }
-
+  // **MAIN LOOP**: Continuously search for the nearest tag
   while (true) {
     let [foundTag, foundLine, foundPos] = nearestTag(
       document,
@@ -508,7 +642,7 @@ export function getTagNearestTrigger(
       startLine,
       startPos
     )
-
+    // **MULTI-ITEM LINE HANDLING**: Complex logic for lines with multiple tags
     if (itemsOnLine > 1) {
       const afterTriggerText = triggerText.substring(triggerPos)
       const afterTriggerPos = afterTriggerText.indexOf('<') + triggerPos
@@ -518,7 +652,7 @@ export function getTagNearestTrigger(
       const beforeTriggerTag = beforeTriggerText.substring(
         lastOpenTagBeforeTriggerPos
       )
-
+      // Verify cursor is in a valid position between tags (not inside a 
closing tag)
       if (
         triggerPos === afterTriggerPos &&
         triggerPos === beforeTriggerPos + 1 &&
@@ -528,9 +662,8 @@ export function getTagNearestTrigger(
         return [tagNearestTrigger, new vscode.Position(foundLine, foundPos)]
       }
     }
-
     startLine = foundLine
-
+    // Check if the found tag is closed
     let [endTag, endTagLine, endTagPos] = getCloseTag(
       document,
       position,
@@ -539,20 +672,20 @@ export function getTagNearestTrigger(
       foundLine,
       foundPos
     )
-
+    // **MULTI-ITEM LINE LOGIC**: Ensure we're targeting the right tag
     if (itemsOnLine > 1 && foundLine === triggerLine) {
       if (foundTag === endTag && endTagPos >= triggerPos) {
         tagNearestTrigger = foundTag
         return [tagNearestTrigger, new vscode.Position(foundLine, foundPos)]
       }
-
+      // Tag is closed, adjust search position
       if (endTag === 'none') {
         startLine = foundLine - 1
       } else {
         startPos = foundPos - 1
       }
     }
-
+    // **SINGLE-ITEM LINE LOGIC**: Walk up the tree to find appropriate parent
     if (itemsOnLine < 2) {
       if (
         (foundTag === endTag && endTagLine >= triggerLine) ||
@@ -561,7 +694,6 @@ export function getTagNearestTrigger(
         tagNearestTrigger = foundTag
         return [tagNearestTrigger, new vscode.Position(foundLine, foundPos)]
       }
-
       startLine = foundLine - 1
     }
   }
diff --git a/src/language/providers/intellisense/elementItems.ts 
b/src/language/providers/intellisense/elementItems.ts
index d44732b..63d2aa5 100644
--- a/src/language/providers/intellisense/elementItems.ts
+++ b/src/language/providers/intellisense/elementItems.ts
@@ -14,7 +14,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+/**
+ * Element Completion Data and Factory Function
+ *
+ * This module exports the element completion data used by 
elementCompletion.ts.
+ * It provides a complete catalog of XML/DFDL elements that can be suggested
+ * in different schema contexts, along with their snippet templates and 
documentation.
+ *
+ * **Dynamic Behavior:**
+ * - The `elementCompletion` function generates completion items dynamically
+ * - It accepts `definedVariables` to populate the dfdl:setVariable dropdown
+ * - It accepts `nsPrefix` to customize snippets with the correct namespace
+ *
+ * **Snippet Features:**
+ * - Tab stops ($1, $2, $0) for navigation
+ * - Choice placeholders (${1|option1,option2|}) for enumerated values
+ * - Dynamic variable insertion using string concatenation
+ */
 // prettier-ignore
 export const elementCompletion = (definedVariables, nsPrefix) => {
   return {
@@ -22,234 +38,240 @@ export const elementCompletion = (definedVariables, 
nsPrefix) => {
       {
         item: 'xml version',
         snippetString: '<?xml version="1.0" encoding="UTF-8"?>\n$0',
+        markdownString: 'XML declaration with UTF-8 encoding'
       },
       {
         item: nsPrefix + 'schema',
-        snippetString: '<${1|\0,xs:,xsd:|}$2' + 'schema 
xmlns:xs="http://www.w3.org/2001/xmlSchema"\n\t\txmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"\n\t\txmlns:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"\n\t\txmlns:fn="http:/www.w3.org/2005/xpath-functions"\nelementFormDefault="unqualified"$0',
+        snippetString: '<${1|' + '\0' + ',xs:,xsd:|}$2' + 'schema 
xmlns:xs="http://www.w3.org/2001/xmlSchema"\n\t\txmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"\n\t\txmlns:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"\n\t\txmlns:fn="http:/www.w3.org/2005/xpath-functions"\nelementFormDefault="unqualified"$0',
+        markdownString: 'Root schema element with standard DFDL namespace 
declarations'
       },
       {
         item: nsPrefix + 'element',
         snippetString: '<' + nsPrefix + 'element$0',
-        markdownString: 'Defines an xs element',
+        markdownString: 'Defines an xs element'
       },
       {
         item: nsPrefix + 'element name',
         snippetString: '<' + nsPrefix + 'element name="$1"$0',
-        markdownString: 'Defines an xs element',
+        markdownString: 'Defines an xs element with name attribute'
       },
       {
         item: nsPrefix + 'element ref',
         snippetString: '<' + nsPrefix + 'element ref="$1"$0',
-        markdownString: 'Defines a reference to a declared element',
+        markdownString: 'Defines a reference to a declared element'
       },
       {
         item: nsPrefix + 'group',
         snippetString: '<' + nsPrefix + 'group "$1">\n\t$0\n</' + nsPrefix + 
'group>',
-        markdownString: 'Defines a named model group to be reused later',
+        markdownString: 'Defines a named model group to be reused later'
       },
       {
         item: nsPrefix + 'group name',
         snippetString: '<' + nsPrefix + 'group name = "$1">\n\t$0\n</' + 
nsPrefix + 'group>',
-        markdownString: 'Defines a named model group to be reused later',
+        markdownString: 'Defines a named model group'
       },
       {
         item: nsPrefix + 'group ref',
         snippetString: '<' + nsPrefix + 'group ref="$1"$0',
-        markdownString: 'Defines a reference to a group declaration',
+        markdownString: 'Defines a reference to a group declaration'
       },
       {
         item: 'dfdl:assert',
         snippetString: '<dfdl:assert $0',
-        markdownString: 'Used to assert truths about a DFDL model',
+        markdownString: 'Used to assert truths about a DFDL model'
       },
       {
         item: 'dfdl:discriminator',
         snippetString: '<dfdl:discriminator $0',
-        markdownString: 'Used during parsing to resolve points or 
uncertainity, remove ambiguity during speculative parsing, improve diagnostic 
behavior',
+        markdownString: 'Used during parsing to resolve points of uncertainty 
during speculative parsing'
       },
       {
         item: 'dfdl:format',
         snippetString: '<dfdl:format $0',
-        markdownString: 'Defines the physical data format properties for 
multiple DFDL schema constructs',
+        markdownString: 'Defines physical data format properties for DFDL 
constructs'
       },
       {
         item: nsPrefix + 'annotation',
         snippetString: '<' + nsPrefix + 'annotation>\n\t$0\n\</' + nsPrefix + 
'annotation>',
+        markdownString: 'Container for DFDL annotation information'
       },
       {
         item: nsPrefix + 'appinfo',
         snippetString: '<' + nsPrefix + 'appinfo 
source="http://www.ogf.org/dfdl/";>\n\t$0\n</' + nsPrefix + 'appinfo>',
+        markdownString: 'Contains DFDL format definitions'
       },
       {
         item: nsPrefix + 'complexType',
         snippetString: '<' + nsPrefix + 'complexType>\n\t$0\n</' + nsPrefix + 
'complexType>',
-        markdownString: 'Defines a complex type definition',
+        markdownString: 'Defines a complex type definition'
       },
       {
         item: nsPrefix + 'complexType name',
         snippetString: '<' + nsPrefix + 'complexType name="$1">\n\t$0\n</' + 
nsPrefix + 'complexType>',
-        markdownString: 'Defines a complex type definition',
+        markdownString: 'Defines a named complex type'
       },
       {
         item: nsPrefix + 'simpleType',
         snippetString: '<' + nsPrefix + 'simpleType$1>\n\t$0\n</' + nsPrefix + 
'simpleType>',
-        markdownString: 'Defines a simple type definition',
+        markdownString: 'Defines a simple type definition'
       },
       {
         item: nsPrefix + 'simpleType name',
         snippetString: '<' + nsPrefix + 'simpleType name="$1"$0',
-        markdownString: 'Defines simple type definition',
+        markdownString: 'Defines a named simple type'
       },
       {
         item: nsPrefix + 'sequence',
         snippetString: '<' + nsPrefix + 'sequence',
-        markdownString: 'Specifies that the child elements must appear in a 
sequence',
+        markdownString: 'Specifies child elements must appear in sequence'
       },
       {
         item: nsPrefix + 'choice',
         snippetString: '<' + nsPrefix + 'choice',
-        markdownString: 'Define group of mutually exclusive elements that 
resolve points of uncertainty that cannot be resolved by speculative parsing',
+        markdownString: 'Defines mutually exclusive elements'
       },
       {
         item: 'dfdl:newVariableInstance',
         snippetString: '<dfdl:newVariableInstance ref="$1"$0',
-        markdownString: 'Defines the name, type, and optional default value 
for the variable'
+        markdownString: 'Creates a new instance of a defined variable'
       },
       {
         item: 'dfdl:defineVariable',
         snippetString: '<dfdl:defineVariable "$1"$0',
-        markdownString: 'Defines the name, type, and optionally default value 
for the variable.',
+        markdownString: 'Defines a variable name, type, and optional default 
value'
       },
       {
         item: 'dfdl:defineVariable name',
         snippetString: '<dfdl:defineVariable name="$1"$0',
-        markdownString: 'Defines the name, type, and optionally default value 
for the variable.',
+        markdownString: 'Defines a named variable with type and optional 
default'
       },
       {
         item: 'dfdl:setVariable',
+        // **DYNAMIC SNIPPET**: Uses definedVariables parameter to populate 
ref attribute choices
         snippetString: '<dfdl:setVariable ref="${1|' + definedVariables + 
'"|}, value="$2"$0',
-        markdownString: 'Sets the value of a variable whose declaration is in 
scope',
+        markdownString: 'Sets the value of a variable in scope'
       },
       {
         item: 'dfdl:defineFormat',
         snippetString: '<dfdl:defineFormat 
name="$1">\n\t$2\n</dfdl:defineFormat>$0',
-        markdownString: 'Defines a named reusable format definition',
+        markdownString: 'Defines a reusable format definition'
       },
       {
         item: 'dfdl:defineEscapeScheme',
         snippetString: '<dfdl:defineEscapeScheme name=$1 
>\n\t$0</dfdl:defineEscapeScheme>',
-        markdownString: 'Defines a named, reusable escapeScheme',
+        markdownString: 'Defines a reusable escape scheme'
       },
       {
         item: 'dfdl:escapeScheme',
         snippetString: '<dfdl:escapeScheme $0',
-        markdownString: 'Allows a common set of properties to be defined that 
can be reused',
+        markdownString: 'References a common set of reusable properties'
       },
       {
         item: 'dfdl:simpleType',
         snippetString: '<dfdl:simpleType $1/>$0',
-        markdownString: 'Defines the physical data format properties of an 
xs:simpleType',
+        markdownString: 'Defines physical data format properties of 
xs:simpleType'
       },
       {
         item: 'dfdl:element',
         snippetString: '<dfdl:element $1/>$0',
-        markdownString: 'Defines the physical data format properties of an 
xs:element',
+        markdownString: 'Defines physical data format properties of xs:element'
       },
       {
         item: 'dfdl:sequence',
         snippetString: '<dfdl:sequence $1/>$0',
-        markdownString: 'Defines the physical data format properties of an 
xs:sequence group',
+        markdownString: 'Defines physical data format properties of 
xs:sequence'
       },
       {
         item: 'dfdl:group',
         snippetString: '<dfdl:group $1/>$0',
-        markdownString: 'Defines the physical data format properties of an 
xs:group reference',
+        markdownString: 'Defines physical data format properties of xs:group'
       },
       {
         item: 'dfdl:choice',
         snippetString: '<dfdl:choice $1/>$0',
-        markdownString: 'Defines the physical data format properties of an 
xs:choice group',
+        markdownString: 'Defines physical data format properties of xs:choice'
       },
       {
         item: 'dfdl:property',
         snippetString: '<dfdl:property name="$1">\n\t$2\n</dfdl:property>$0',
-        markdownString: 'Used in the syntax of format annotations',
+        markdownString: 'Used in format annotations'
       },
       {
         item: 'restriction',
-        // use the "xs:" prefix for primitive types to differentiate them from 
custom simple types
+        // **CHOICE PLACEHOLDER**: Provides dropdown of common XSD primitive 
types
         snippetString: '<' + nsPrefix + 'restriction 
base="${1|xs:string,xs:decimal,xs:float,xs:double,xs:integer,xs:nonNegativeInteger,xs:int,xs:unsignedInt,xs:short,xs:unsignedShort,xs:long,xs:unsignedLong,xs:byte,xs:unsignedByte,xs:hexBinary,xs:boolean|}"$0',
-        markdownString: 'Specify the base type the element is restricted to',
+        markdownString: 'Specifies base type for restriction'
       },
       {
         item: 'minInclusive',
         snippetString: '<' + nsPrefix + 'minInclusive value="$1"/>$0',
-        markdownString: 'Used to check the validity of an element'
+        markdownString: 'Validates element has minimum inclusive value'
       },
       {
         item: 'minExclusive',
         snippetString: '<' + nsPrefix + 'minExclusive value="$1"/>$0',
-        markdownString: 'Used to check the validity of an element'
+        markdownString: 'Validates element has minimum exclusive value'
       },
       {
         item: 'maxInclusive',
         snippetString: '<' + nsPrefix + 'maxInclusive value="$1"/>$0',
-        markdownString: 'Used to check the validity of an element'
+        markdownString: 'Validates element has maximum inclusive value'
       },
       {
         item: 'maxExclusive',
         snippetString: '<' + nsPrefix + 'maxExclusive value="$1"/>$0',
-        markdownString: 'Used to check the validity of an element'
+        markdownString: 'Validates element has maximum exclusive value'
       },
       {
         item: 'pattern',
         snippetString: '<' + nsPrefix + 'pattern value="$1"/>$0',
-        markdownString: 'Used to derive new simple types by specifying a 
regular expression against which values of the type are compared'
+        markdownString: 'Restricts type with regular expression pattern'
       },
       {
         item: 'totalDigits',
         snippetString: '<' + nsPrefix + 'totalDigits value="$1"/>$0',
-        markdownString: 'Indicates the maximum allowed value for the number of 
digits'
+        markdownString: 'Restricts maximum number of digits'
       },
       {
         item: 'fractionDigits',
         snippetString: '<' + nsPrefix + 'fractionDigits value="$1"/>$0',
-        markdownString: 'Indicates the maximum number of digits in the 
fractional part'
+        markdownString: 'Restricts maximum digits in fractional part'
       },
       {
         item: 'enumeration',
         snippetString: '<' + nsPrefix + 'enumeration value="$1"/>$0',
-        markdownString: 'Used to restrict a datatype to a finite set of values'
+        markdownString: 'Restricts type to finite set of values'
       },
       {
         item: nsPrefix + 'include',
         snippetString: '<' + nsPrefix + 'include "$1"/>$0',
-        markdownString: 'Used to add all the components of an included schema'
+        markdownString: 'Includes components from another schema'
       },
       {
         item: 'documentation',
-        snippetString: '<' + nsPrefix + 
'documentation>\n\t$1\n</documentation>$0'
+        snippetString: '<' + nsPrefix + 
'documentation>\n\t$1\n</documentation>$0',
+        markdownString: 'Contains human-readable documentation'
       },
       {
         item: nsPrefix + 'import',
         snippetString: '<' + nsPrefix + 'import "$1"/>$0',
-        markdownString: 'Used to add all the components of an included schema'
+        markdownString: 'Imports components from another namespace'
       },
       {
         item: '<[CDATA[]]>',
         snippetString: '<[CDATA[$1]]>$0',
-        markdownString: ''
+        markdownString: 'CDATA section (alternative syntax)'
       },
       {
         item: '<![CDATA[]]>',
         snippetString: '<![CDATA[$1]]>$0',
-        markdownString: ''
+        markdownString: 'CDATA section for character data'
       },
       {
         item: '{}',
         snippetString: '{$1}$0',
-        markdownString: ''
-      },
+        markdownString: 'DFDL expression wrapper'
+      }
     ],
   }
 }


Reply via email to