<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-28 --> <p>Creating plugins and extensions for Geode enables developers to enhance their editor experience with GQL-specific features like syntax highlighting, intelligent auto-completion, real-time diagnostics, and integrated query execution. Whether you are building a plugin for your team&rsquo;s custom editor, extending an existing integration, or contributing to the Geode ecosystem, this guide provides comprehensive coverage of plugin development patterns and best practices.</p> <p>Geode&rsquo;s plugin architecture leverages the Language Server Protocol (LSP) for cross-editor compatibility, allowing you to build language intelligence features once and deploy them across VS Code, Neovim, Vim, Emacs, Sublime Text, and any other LSP-compatible editor.</p> <p>This guide covers LSP client implementation, syntax highlighting packages, completion sources, query execution integration, result visualization, testing strategies, and publishing workflows for various editor ecosystems.</p> <h3 id="architecture-overview" class="position-relative d-flex align-items-center group"> <span>Architecture Overview</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="architecture-overview" aria-haspopup="dialog" aria-label="Share link: Architecture Overview"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden> <div class="hsm-dialog" role="document"> <div class="hsm-header"> <h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2> <button type="button" class="hsm-close" aria-label="Close"> <i class="fa-solid fa-xmark"></i> </button> </div> <div class="hsm-body"> <label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label> <div class="input-group mb-4 hsm-url-group"> <input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" /> <button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy"> <i class="fa-duotone fa-clipboard" aria-hidden="true"></i> </button> </div> <div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div> <div class="hsm-share-grid"> <a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-twitter me-2"></i>Twitter </a> <a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-linkedin me-2"></i>LinkedIn </a> <a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-facebook me-2"></i>Facebook </a> </div> </div> </div> </div> <style> .heading-share-modal { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); z-index: 1050; padding: 1rem; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .heading-share-modal[hidden] { display: none !important; } .hsm-dialog { max-width: 420px; width: 100%; background: var(--bs-body-bg, #fff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden; animation: hsm-fade-in 0.2s ease-out; } @keyframes hsm-fade-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } [data-bs-theme="dark"] .hsm-dialog { background: #1e293b; border-color: rgba(255,255,255,0.1); color: #f8f9fa; } .hsm-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); background: rgba(0,0,0,0.02); } [data-bs-theme="dark"] .hsm-header { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.1); } .hsm-close { background: transparent; border: none; color: inherit; opacity: 0.5; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 1.2rem; line-height: 1; transition: opacity 0.2s; } .hsm-close:hover { opacity: 1; } .hsm-body { padding: 1.5rem; } .hsm-url-group { display: flex !important; align-items: stretch; } .hsm-url-group .form-control { flex: 1; min-width: 0; margin: 0; background: var(--bs-secondary-bg, #f8f9fa); border-color: var(--bs-border-color, #dee2e6); border-top-right-radius: 0; border-bottom-right-radius: 0; height: 42px; } .hsm-url-group .btn { flex: 0 0 auto; margin: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; height: 42px; display: flex; align-items: center; justify-content: center; padding: 0 1.25rem; z-index: 2; } [data-bs-theme="dark"] .hsm-url-group .form-control { background: #0f172a; border-color: #334155; color: #e2e8f0; } .hsm-share-grid { display: flex; flex-direction: column; gap: 0.5rem; } .hsm-share-grid .btn { display: flex; align-items: center; justify-content: center; font-size: 0.9rem; padding: 0.6rem; border-color: var(--bs-border-color); width: 100%; } [data-bs-theme="dark"] .hsm-share-grid .btn { color: #e2e8f0; border-color: #475569; } [data-bs-theme="dark"] .hsm-share-grid .btn:hover { background: #334155; border-color: #cbd5e1; } </style> <script> (function(){ const modal = document.getElementById('headingShareModal'); if(!modal) return; const input = modal.querySelector('#headingShareInput'); const copyBtn = modal.querySelector('.hsm-copy'); const twitter = modal.querySelector('#share-twitter'); const linkedin = modal.querySelector('#share-linkedin'); const facebook = modal.querySelector('#share-facebook'); const closeBtn = modal.querySelector('.hsm-close'); let lastFocus=null; let trapBound=false; function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; } function isOpen(){ return !modal.hasAttribute('hidden'); } function hydrate(id){ const url=buildUrl(id); input.value=url; const enc=encodeURIComponent(url); const text=encodeURIComponent(document.title); if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`; if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`; if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`; } function openModal(id){ lastFocus=document.activeElement; hydrate(id); if(!isOpen()){ modal.removeAttribute('hidden'); } requestAnimationFrame(()=>{ input.focus(); }); trapFocus(); } function closeModal(){ if(!isOpen()) return; modal.setAttribute('hidden',''); if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus(); } function copyCurrent(){ try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); } catch(e){ fallback(); } } function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} } function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); } function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); } function bindShareButtons(){ document.querySelectorAll('.h-share').forEach(btn=>{ if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; } }); } bindShareButtons(); if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', bindShareButtons); } else { requestAnimationFrame(bindShareButtons); } document.addEventListener('click', function(e){ const shareBtn=e.target.closest && e.target.closest('.h-share'); if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); } }, true); document.addEventListener('click', e=>{ if(e.target===modal) closeModal(); if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); } if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); } }); document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); }); function trapFocus(){ if(trapBound) return; trapBound=true; modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } }); } if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); }); })(); </script> <h4 id="plugin-components" class="position-relative d-flex align-items-center group"> <span>Plugin Components</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="plugin-components" aria-haspopup="dialog" aria-label="Share link: Plugin Components"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>A complete Geode editor plugin typically includes:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">geode-editor-plugin/ </span></span><span class="line"><span class="cl">├── src/ </span></span><span class="line"><span class="cl">│ ├── extension.ts # Extension entry point </span></span><span class="line"><span class="cl">│ ├── lsp-client.ts # LSP client implementation </span></span><span class="line"><span class="cl">│ ├── completion.ts # Completion providers </span></span><span class="line"><span class="cl">│ ├── diagnostics.ts # Diagnostic handling </span></span><span class="line"><span class="cl">│ ├── execution.ts # Query execution </span></span><span class="line"><span class="cl">│ ├── results.ts # Result visualization </span></span><span class="line"><span class="cl">│ └── schema.ts # Schema explorer </span></span><span class="line"><span class="cl">├── syntaxes/ </span></span><span class="line"><span class="cl">│ └── gql.tmLanguage.json # TextMate grammar </span></span><span class="line"><span class="cl">├── snippets/ </span></span><span class="line"><span class="cl">│ └── gql.json # Code snippets </span></span><span class="line"><span class="cl">├── languages/ </span></span><span class="line"><span class="cl">│ └── gql-language-configuration.json </span></span><span class="line"><span class="cl">├── package.json # Extension manifest </span></span><span class="line"><span class="cl">└── README.md </span></span></code></pre></div> <h4 id="integration-points" class="position-relative d-flex align-items-center group"> <span>Integration Points</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="integration-points" aria-haspopup="dialog" aria-label="Share link: Integration Points"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><table> <thead> <tr> <th>Component</th> <th>Purpose</th> <th>Technology</th> </tr> </thead> <tbody> <tr> <td>Language Server</td> <td>Intelligence features</td> <td>LSP (JSON-RPC)</td> </tr> <tr> <td>Syntax Highlighting</td> <td>Tokenization</td> <td>TextMate/Tree-sitter</td> </tr> <tr> <td>Snippets</td> <td>Code templates</td> <td>Editor-specific</td> </tr> <tr> <td>Commands</td> <td>User actions</td> <td>Editor API</td> </tr> <tr> <td>UI</td> <td>Results, explorer</td> <td>Editor widgets</td> </tr> </tbody> </table> <h3 id="language-server-protocol-client" class="position-relative d-flex align-items-center group"> <span>Language Server Protocol Client</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="language-server-protocol-client" aria-haspopup="dialog" aria-label="Share link: Language Server Protocol Client"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="basic-lsp-client" class="position-relative d-flex align-items-center group"> <span>Basic LSP Client</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="basic-lsp-client" aria-haspopup="dialog" aria-label="Share link: Basic LSP Client"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Implement an LSP client to communicate with Geode&rsquo;s language server:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="c1">// src/lsp-client.ts </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">import</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">LanguageClient</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">LanguageClientOptions</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">ServerOptions</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">TransportKind</span><span class="p">,</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;vscode-languageclient/node&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kd">function</span> <span class="nx">createLanguageClient</span><span class="p">(</span><span class="nx">context</span>: <span class="kt">ExtensionContext</span><span class="p">)</span><span class="o">:</span> <span class="nx">LanguageClient</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Server options - how to start the language server </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">serverOptions</span>: <span class="kt">ServerOptions</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">command</span><span class="o">:</span> <span class="s1">&#39;geode&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">args</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;lsp&#39;</span><span class="p">,</span> <span class="s1">&#39;--stdio&#39;</span><span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="nx">transport</span>: <span class="kt">TransportKind.stdio</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Client options - document types and synchronization </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">clientOptions</span>: <span class="kt">LanguageClientOptions</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">documentSelector</span><span class="o">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">scheme</span><span class="o">:</span> <span class="s1">&#39;file&#39;</span><span class="p">,</span> <span class="nx">language</span><span class="o">:</span> <span class="s1">&#39;gql&#39;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">scheme</span><span class="o">:</span> <span class="s1">&#39;untitled&#39;</span><span class="p">,</span> <span class="nx">language</span><span class="o">:</span> <span class="s1">&#39;gql&#39;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="nx">synchronize</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">fileEvents</span>: <span class="kt">workspace.createFileSystemWatcher</span><span class="p">(</span><span class="s1">&#39;**/*.gql&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">initializationOptions</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">connection</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">host</span>: <span class="kt">workspace.getConfiguration</span><span class="p">(</span><span class="s1">&#39;geode&#39;</span><span class="p">).</span><span class="kr">get</span><span class="p">(</span><span class="s1">&#39;host&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">port</span>: <span class="kt">workspace.getConfiguration</span><span class="p">(</span><span class="s1">&#39;geode&#39;</span><span class="p">).</span><span class="kr">get</span><span class="p">(</span><span class="s1">&#39;port&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">database</span>: <span class="kt">workspace.getConfiguration</span><span class="p">(</span><span class="s1">&#39;geode&#39;</span><span class="p">).</span><span class="kr">get</span><span class="p">(</span><span class="s1">&#39;database&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">diagnostics</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">enabled</span>: <span class="kt">true</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">validateLabels</span>: <span class="kt">true</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">validateProperties</span>: <span class="kt">true</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Create and return the client </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="k">new</span> <span class="nx">LanguageClient</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;geode-gql&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;Geode GQL Language Server&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">serverOptions</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">clientOptions</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h4 id="handling-lsp-notifications" class="position-relative d-flex align-items-center group"> <span>Handling LSP Notifications</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="handling-lsp-notifications" aria-haspopup="dialog" aria-label="Share link: Handling LSP Notifications"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Handle custom notifications from the language server:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="c1">// src/notifications.ts </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">import</span> <span class="p">{</span> <span class="nx">LanguageClient</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;vscode-languageclient/node&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kd">function</span> <span class="nx">registerNotificationHandlers</span><span class="p">(</span><span class="nx">client</span>: <span class="kt">LanguageClient</span><span class="p">)</span><span class="o">:</span> <span class="k">void</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Connection status updates </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">client</span><span class="p">.</span><span class="nx">onNotification</span><span class="p">(</span><span class="s1">&#39;geode/connectionStatus&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">params</span>: <span class="kt">ConnectionStatus</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">updateStatusBar</span><span class="p">(</span><span class="nx">params</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">params</span><span class="p">.</span><span class="nx">connected</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">showConnectionError</span><span class="p">(</span><span class="nx">params</span><span class="p">.</span><span class="nx">error</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Schema changes </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">client</span><span class="p">.</span><span class="nx">onNotification</span><span class="p">(</span><span class="s1">&#39;geode/schemaChanged&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">params</span>: <span class="kt">SchemaChange</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">refreshSchemaExplorer</span><span class="p">(</span><span class="nx">params</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">showNotification</span><span class="p">(</span><span class="sb">`Schema updated: </span><span class="si">${</span><span class="nx">params</span><span class="p">.</span><span class="nx">changeType</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Query execution progress </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">client</span><span class="p">.</span><span class="nx">onNotification</span><span class="p">(</span><span class="s1">&#39;geode/queryProgress&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">params</span>: <span class="kt">QueryProgress</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">updateProgressIndicator</span><span class="p">(</span><span class="nx">params</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Diagnostic updates </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">client</span><span class="p">.</span><span class="nx">onNotification</span><span class="p">(</span><span class="s1">&#39;geode/diagnosticsUpdated&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">params</span>: <span class="kt">DiagnosticUpdate</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">handleDiagnostics</span><span class="p">(</span><span class="nx">params</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">ConnectionStatus</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">connected</span>: <span class="kt">boolean</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">host</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">port</span>: <span class="kt">number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">database</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">error?</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">SchemaChange</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">changeType</span><span class="o">:</span> <span class="s1">&#39;labels&#39;</span> <span class="o">|</span> <span class="s1">&#39;relationships&#39;</span> <span class="o">|</span> <span class="s1">&#39;indexes&#39;</span> <span class="o">|</span> <span class="s1">&#39;full&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">timestamp</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">QueryProgress</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">queryId</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">stage</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">progress</span>: <span class="kt">number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">rowsProcessed</span>: <span class="kt">number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h4 id="custom-lsp-requests" class="position-relative d-flex align-items-center group"> <span>Custom LSP Requests</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="custom-lsp-requests" aria-haspopup="dialog" aria-label="Share link: Custom LSP Requests"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Send custom requests to the language server:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="c1">// src/requests.ts </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">import</span> <span class="p">{</span> <span class="nx">LanguageClient</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;vscode-languageclient/node&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">GeodeRequests</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">constructor</span><span class="p">(</span><span class="kr">private</span> <span class="nx">client</span>: <span class="kt">LanguageClient</span><span class="p">)</span> <span class="p">{}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Execute a GQL query </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">async</span> <span class="nx">executeQuery</span><span class="p">(</span><span class="nx">query</span>: <span class="kt">string</span><span class="p">,</span> <span class="nx">params?</span>: <span class="kt">Record</span><span class="p">&lt;</span><span class="nt">string</span><span class="err">,</span> <span class="na">any</span><span class="p">&gt;)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">QueryResult</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">sendRequest</span><span class="p">(</span><span class="s1">&#39;geode/executeQuery&#39;</span><span class="p">,</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">query</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">params</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">timeout</span>: <span class="kt">30000</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Get execution plan </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">async</span> <span class="nx">explainQuery</span><span class="p">(</span><span class="nx">query</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">ExecutionPlan</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">sendRequest</span><span class="p">(</span><span class="s1">&#39;geode/explainQuery&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">query</span> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Profile query execution </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">async</span> <span class="nx">profileQuery</span><span class="p">(</span><span class="nx">query</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">ProfileResult</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">sendRequest</span><span class="p">(</span><span class="s1">&#39;geode/profileQuery&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">query</span> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Get schema information </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">async</span> <span class="nx">getSchema</span><span class="p">()</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">Schema</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">sendRequest</span><span class="p">(</span><span class="s1">&#39;geode/getSchema&#39;</span><span class="p">,</span> <span class="p">{});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Get labels with statistics </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">async</span> <span class="nx">getLabels</span><span class="p">()</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">LabelInfo</span><span class="err">[]</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">sendRequest</span><span class="p">(</span><span class="s1">&#39;geode/getLabels&#39;</span><span class="p">,</span> <span class="p">{});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Get properties for a label </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">async</span> <span class="nx">getProperties</span><span class="p">(</span><span class="nx">label</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">PropertyInfo</span><span class="err">[]</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">sendRequest</span><span class="p">(</span><span class="s1">&#39;geode/getProperties&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">label</span> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Get relationship types </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">async</span> <span class="nx">getRelationships</span><span class="p">()</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">RelationshipInfo</span><span class="err">[]</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">sendRequest</span><span class="p">(</span><span class="s1">&#39;geode/getRelationships&#39;</span><span class="p">,</span> <span class="p">{});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Cancel running query </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">async</span> <span class="nx">cancelQuery</span><span class="p">(</span><span class="nx">queryId</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">void</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">sendRequest</span><span class="p">(</span><span class="s1">&#39;geode/cancelQuery&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">queryId</span> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">QueryResult</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">columns</span>: <span class="kt">string</span><span class="p">[];</span> </span></span><span class="line"><span class="cl"> <span class="nx">rows</span>: <span class="kt">any</span><span class="p">[][];</span> </span></span><span class="line"><span class="cl"> <span class="nx">rowCount</span>: <span class="kt">number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">executionTime</span>: <span class="kt">number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">queryId</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">ExecutionPlan</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">plan</span>: <span class="kt">PlanNode</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">estimatedCost</span>: <span class="kt">number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">warnings</span>: <span class="kt">string</span><span class="p">[];</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">ProfileResult</span> <span class="kr">extends</span> <span class="nx">QueryResult</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">profile</span>: <span class="kt">ProfileNode</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">dbHits</span>: <span class="kt">number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">memoryUsage</span>: <span class="kt">number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h3 id="syntax-highlighting" class="position-relative d-flex align-items-center group"> <span>Syntax Highlighting</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="syntax-highlighting" aria-haspopup="dialog" aria-label="Share link: Syntax Highlighting"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="textmate-grammar" class="position-relative d-flex align-items-center group"> <span>TextMate Grammar</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="textmate-grammar" aria-haspopup="dialog" aria-label="Share link: TextMate Grammar"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Create a TextMate grammar for GQL syntax:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;$schema&#34;</span><span class="p">:</span> <span class="s2">&#34;https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;GQL&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;scopeName&#34;</span><span class="p">:</span> <span class="s2">&#34;source.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="s2">&#34;#comments&#34;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="s2">&#34;#strings&#34;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="s2">&#34;#numbers&#34;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="s2">&#34;#keywords&#34;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="s2">&#34;#functions&#34;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="s2">&#34;#labels&#34;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="s2">&#34;#relationships&#34;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="s2">&#34;#properties&#34;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="s2">&#34;#variables&#34;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;include&#34;</span><span class="p">:</span> <span class="s2">&#34;#operators&#34;</span> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;repository&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;comments&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;comment.line.double-dash.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;--.*$&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;comment.block.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;begin&#34;</span><span class="p">:</span> <span class="s2">&#34;/\\*&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;end&#34;</span><span class="p">:</span> <span class="s2">&#34;\\*/&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;strings&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;string.quoted.single.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;begin&#34;</span><span class="p">:</span> <span class="s2">&#34;&#39;&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;end&#34;</span><span class="p">:</span> <span class="s2">&#34;&#39;&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;constant.character.escape.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\\\.&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;string.quoted.double.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;begin&#34;</span><span class="p">:</span> <span class="s2">&#34;\&#34;&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;end&#34;</span><span class="p">:</span> <span class="s2">&#34;\&#34;&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;constant.character.escape.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\\\.&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;numbers&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;constant.numeric.float.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\b\\d+\\.\\d+([eE][+-]?\\d+)?\\b&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;constant.numeric.integer.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\b\\d+\\b&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;keywords&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;keyword.control.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\b(?i:MATCH|WHERE|RETURN|CREATE|DELETE|MERGE|SET|REMOVE|WITH|UNWIND|CALL|YIELD|ORDER|BY|SKIP|LIMIT|OPTIONAL|DISTINCT|AS|CASE|WHEN|THEN|ELSE|END)\\b&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;keyword.operator.logical.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\b(?i:AND|OR|NOT|XOR|IN|IS|NULL|TRUE|FALSE)\\b&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;keyword.control.transaction.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\b(?i:BEGIN|COMMIT|ROLLBACK|TRANSACTION)\\b&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;functions&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;support.function.aggregate.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\b(?i:COUNT|SUM|AVG|MIN|MAX|COLLECT|STDEV|PERCENTILE)\\b&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;support.function.string.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\b(?i:UPPER|LOWER|TRIM|LTRIM|RTRIM|SUBSTRING|REPLACE|SPLIT|REVERSE|SIZE|LENGTH)\\b&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;support.function.math.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\b(?i:ABS|CEIL|FLOOR|ROUND|SIGN|RAND|LOG|LOG10|EXP|SQRT|SIN|COS|TAN)\\b&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;support.function.temporal.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\b(?i:DATE|DATETIME|TIME|DURATION|LOCALDATETIME|LOCALTIME)\\b&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;support.function.misc.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\b(?i:COALESCE|NULLIF|ID|TYPE|LABELS|PROPERTIES|KEYS|NODES|RELATIONSHIPS|HEAD|TAIL|LAST)\\b&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;labels&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;entity.name.type.label.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;:\\s*([A-Za-z_][A-Za-z0-9_]*)&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;captures&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;1&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;entity.name.type.gql&#34;</span> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;relationships&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;entity.name.type.relationship.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;-\\[\\s*:?([A-Za-z_][A-Za-z0-9_]*)&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;captures&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;1&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;entity.name.type.gql&#34;</span> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;properties&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;variable.other.property.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\.([A-Za-z_][A-Za-z0-9_]*)&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;variables&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;variable.parameter.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\$([A-Za-z_][A-Za-z0-9_]*)&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;operators&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;patterns&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;keyword.operator.comparison.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;=|&lt;&gt;|!=|&lt;|&gt;|&lt;=|&gt;=|=~&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;keyword.operator.arithmetic.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\+|-|\\*|/|%|\\^&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;keyword.operator.string.gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;match&#34;</span><span class="p">:</span> <span class="s2">&#34;\\b(?i:STARTS|ENDS|CONTAINS|LIKE)\\b&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h4 id="tree-sitter-grammar" class="position-relative d-flex align-items-center group"> <span>Tree-sitter Grammar</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="tree-sitter-grammar" aria-haspopup="dialog" aria-label="Share link: Tree-sitter Grammar"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>For editors supporting Tree-sitter (Neovim, Helix):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// grammar.js </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="nx">grammar</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;gql&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">extras</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="sr">/\s/</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">comment</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">],</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">rules</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">source_file</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">repeat</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">statement</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">statement</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">choice</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">match_clause</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">create_clause</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">merge_clause</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">delete_clause</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">return_clause</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">with_clause</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">optional</span><span class="p">(</span><span class="s1">&#39;;&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">match_clause</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">caseInsensitive</span><span class="p">(</span><span class="s1">&#39;MATCH&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">pattern</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">where_clause</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">pattern</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">node_pattern</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">repeat</span><span class="p">(</span><span class="nx">seq</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">relationship_pattern</span><span class="p">,</span> <span class="nx">$</span><span class="p">.</span><span class="nx">node_pattern</span><span class="p">))</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">node_pattern</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;(&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">variable</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">label</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">properties</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;)&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">relationship_pattern</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">choice</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">seq</span><span class="p">(</span><span class="s1">&#39;-[&#39;</span><span class="p">,</span> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">variable</span><span class="p">),</span> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">rel_type</span><span class="p">),</span> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">properties</span><span class="p">),</span> <span class="s1">&#39;]-&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">seq</span><span class="p">(</span><span class="s1">&#39;-[&#39;</span><span class="p">,</span> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">variable</span><span class="p">),</span> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">rel_type</span><span class="p">),</span> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">properties</span><span class="p">),</span> <span class="s1">&#39;]-&gt;&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">seq</span><span class="p">(</span><span class="s1">&#39;&lt;-[&#39;</span><span class="p">,</span> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">variable</span><span class="p">),</span> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">rel_type</span><span class="p">),</span> <span class="nx">optional</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">properties</span><span class="p">),</span> <span class="s1">&#39;]-&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">label</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">,</span> <span class="nx">$</span><span class="p">.</span><span class="nx">identifier</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">rel_type</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">,</span> <span class="nx">$</span><span class="p">.</span><span class="nx">identifier</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">variable</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">$</span><span class="p">.</span><span class="nx">identifier</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">identifier</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="o">/</span><span class="p">[</span><span class="nx">A</span><span class="o">-</span><span class="nx">Za</span><span class="o">-</span><span class="nx">z_</span><span class="p">][</span><span class="nx">A</span><span class="o">-</span><span class="nx">Za</span><span class="o">-</span><span class="nx">z0</span><span class="o">-</span><span class="mi">9_</span><span class="p">]</span><span class="o">*</span><span class="err">/,</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">properties</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;{&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">sepBy</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">,</span> <span class="nx">$</span><span class="p">.</span><span class="nx">property_assignment</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;}&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">property_assignment</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">identifier</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;:&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">expression</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">where_clause</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">caseInsensitive</span><span class="p">(</span><span class="s1">&#39;WHERE&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">expression</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">return_clause</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">caseInsensitive</span><span class="p">(</span><span class="s1">&#39;RETURN&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">sepBy</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">,</span> <span class="nx">$</span><span class="p">.</span><span class="nx">return_item</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">return_item</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">expression</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">optional</span><span class="p">(</span><span class="nx">seq</span><span class="p">(</span><span class="nx">caseInsensitive</span><span class="p">(</span><span class="s1">&#39;AS&#39;</span><span class="p">),</span> <span class="nx">$</span><span class="p">.</span><span class="nx">identifier</span><span class="p">))</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">expression</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">choice</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">literal</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">variable</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">property_access</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">function_call</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">binary_expression</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">unary_expression</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">seq</span><span class="p">(</span><span class="s1">&#39;(&#39;</span><span class="p">,</span> <span class="nx">$</span><span class="p">.</span><span class="nx">expression</span><span class="p">,</span> <span class="s1">&#39;)&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">literal</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">choice</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">string</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">number</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="kr">boolean</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="kc">null</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">string</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">choice</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">seq</span><span class="p">(</span><span class="s2">&#34;&#39;&#34;</span><span class="p">,</span> <span class="sr">/[^&#39;]*/</span><span class="p">,</span> <span class="s2">&#34;&#39;&#34;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">seq</span><span class="p">(</span><span class="s1">&#39;&#34;&#39;</span><span class="p">,</span> <span class="sr">/[^&#34;]*/</span><span class="p">,</span> <span class="s1">&#39;&#34;&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">number</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="o">/</span><span class="err">\</span><span class="nx">d</span><span class="o">+</span><span class="p">(</span><span class="err">\</span><span class="p">.</span><span class="err">\</span><span class="nx">d</span><span class="o">+</span><span class="p">)</span><span class="o">?</span><span class="err">/,</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">boolean</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">choice</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">caseInsensitive</span><span class="p">(</span><span class="s1">&#39;TRUE&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">caseInsensitive</span><span class="p">(</span><span class="s1">&#39;FALSE&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kc">null</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">caseInsensitive</span><span class="p">(</span><span class="s1">&#39;NULL&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">property_access</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">variable</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;.&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">identifier</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">function_call</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">identifier</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;(&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">optional</span><span class="p">(</span><span class="nx">sepBy</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">,</span> <span class="nx">$</span><span class="p">.</span><span class="nx">expression</span><span class="p">)),</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;)&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">binary_expression</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">prec</span><span class="p">.</span><span class="nx">left</span><span class="p">(</span><span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">expression</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">choice</span><span class="p">(</span><span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="s1">&#39;-&#39;</span><span class="p">,</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;=&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="s1">&#39;AND&#39;</span><span class="p">,</span> <span class="s1">&#39;OR&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">expression</span> </span></span><span class="line"><span class="cl"> <span class="p">)),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">unary_expression</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">prec</span><span class="p">.</span><span class="nx">right</span><span class="p">(</span><span class="nx">seq</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">choice</span><span class="p">(</span><span class="s1">&#39;NOT&#39;</span><span class="p">,</span> <span class="s1">&#39;-&#39;</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">$</span><span class="p">.</span><span class="nx">expression</span> </span></span><span class="line"><span class="cl"> <span class="p">)),</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">comment</span><span class="o">:</span> <span class="nx">$</span> <span class="p">=&gt;</span> <span class="nx">choice</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">seq</span><span class="p">(</span><span class="s1">&#39;--&#39;</span><span class="p">,</span> <span class="sr">/.*/</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">seq</span><span class="p">(</span><span class="s1">&#39;/*&#39;</span><span class="p">,</span> <span class="sr">/[^*]*\*+([^/*][^*]*\*+)*/</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">caseInsensitive</span><span class="p">(</span><span class="nx">keyword</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="nx">keyword</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">).</span><span class="nx">map</span><span class="p">(</span><span class="nx">c</span> <span class="p">=&gt;</span> </span></span><span class="line"><span class="cl"> <span class="sb">`[</span><span class="si">${</span><span class="nx">c</span><span class="p">.</span><span class="nx">toLowerCase</span><span class="p">()</span><span class="si">}${</span><span class="nx">c</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">()</span><span class="si">}</span><span class="sb">]`</span> </span></span><span class="line"><span class="cl"> <span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">));</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">sepBy</span><span class="p">(</span><span class="nx">sep</span><span class="p">,</span> <span class="nx">rule</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">optional</span><span class="p">(</span><span class="nx">seq</span><span class="p">(</span><span class="nx">rule</span><span class="p">,</span> <span class="nx">repeat</span><span class="p">(</span><span class="nx">seq</span><span class="p">(</span><span class="nx">sep</span><span class="p">,</span> <span class="nx">rule</span><span class="p">))));</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h3 id="auto-completion" class="position-relative d-flex align-items-center group"> <span>Auto-Completion</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="auto-completion" aria-haspopup="dialog" aria-label="Share link: Auto-Completion"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="completion-provider" class="position-relative d-flex align-items-center group"> <span>Completion Provider</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="completion-provider" aria-haspopup="dialog" aria-label="Share link: Completion Provider"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Implement a completion provider for rich suggestions:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="c1">// src/completion.ts </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">vscode</span> <span class="kr">from</span> <span class="s1">&#39;vscode&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">GeodeRequests</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;./requests&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">GeodeCompletionProvider</span> <span class="kr">implements</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItemProvider</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">constructor</span><span class="p">(</span><span class="kr">private</span> <span class="nx">geode</span>: <span class="kt">GeodeRequests</span><span class="p">)</span> <span class="p">{}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">async</span> <span class="nx">provideCompletionItems</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nb">document</span><span class="o">:</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">TextDocument</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">position</span>: <span class="kt">vscode.Position</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">token</span>: <span class="kt">vscode.CancellationToken</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">vscode.CompletionItem</span><span class="err">[]</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">context</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getCompletionContext</span><span class="p">(</span><span class="nb">document</span><span class="p">,</span> <span class="nx">position</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">switch</span> <span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="kr">type</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s1">&#39;label&#39;</span><span class="o">:</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">getLabelCompletions</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s1">&#39;property&#39;</span><span class="o">:</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">getPropertyCompletions</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nx">label</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s1">&#39;relationship&#39;</span><span class="o">:</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">getRelationshipCompletions</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s1">&#39;function&#39;</span><span class="o">:</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">getFunctionCompletions</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s1">&#39;keyword&#39;</span><span class="o">:</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">getKeywordCompletions</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nx">previousKeyword</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">default</span><span class="o">:</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">[];</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">getCompletionContext</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nb">document</span><span class="o">:</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">TextDocument</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">position</span>: <span class="kt">vscode.Position</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span><span class="o">:</span> <span class="nx">CompletionContext</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">lineText</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">lineAt</span><span class="p">(</span><span class="nx">position</span><span class="p">).</span><span class="nx">text</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">textBeforeCursor</span> <span class="o">=</span> <span class="nx">lineText</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">position</span><span class="p">.</span><span class="nx">character</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// After colon - label completion </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="nx">textBeforeCursor</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/:\s*\w*$/</span><span class="p">))</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> <span class="kr">type</span><span class="o">:</span> <span class="s1">&#39;label&#39;</span> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// After dot - property completion </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">propMatch</span> <span class="o">=</span> <span class="nx">textBeforeCursor</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/(\w+)\.\w*$/</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">propMatch</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">label</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">inferLabel</span><span class="p">(</span><span class="nb">document</span><span class="p">,</span> <span class="nx">propMatch</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nx">position</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> <span class="kr">type</span><span class="o">:</span> <span class="s1">&#39;property&#39;</span><span class="p">,</span> <span class="nx">variable</span>: <span class="kt">propMatch</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nx">label</span> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// After -[ or relationship context </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="nx">textBeforeCursor</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/-\[\s*:?\w*$/</span><span class="p">))</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> <span class="kr">type</span><span class="o">:</span> <span class="s1">&#39;relationship&#39;</span> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// After function name opening paren </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="nx">textBeforeCursor</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/\w+\(\s*$/</span><span class="p">))</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> <span class="kr">type</span><span class="o">:</span> <span class="s1">&#39;function_args&#39;</span> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Default to keyword completion </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="p">{</span> <span class="kr">type</span><span class="o">:</span> <span class="s1">&#39;keyword&#39;</span><span class="p">,</span> <span class="nx">previousKeyword</span>: <span class="kt">this.getPreviousKeyword</span><span class="p">(</span><span class="nx">textBeforeCursor</span><span class="p">)</span> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="kr">async</span> <span class="nx">getLabelCompletions</span><span class="p">()</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">vscode.CompletionItem</span><span class="err">[]</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">labels</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">geode</span><span class="p">.</span><span class="nx">getLabels</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">labels</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">label</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">item</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItem</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">label</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItemKind</span><span class="p">.</span><span class="nx">Class</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">detail</span> <span class="o">=</span> <span class="sb">`Label (</span><span class="si">${</span><span class="nx">label</span><span class="p">.</span><span class="nx">nodeCount</span><span class="si">}</span><span class="sb"> nodes)`</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">documentation</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">MarkdownString</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="sb">`**</span><span class="si">${</span><span class="nx">label</span><span class="p">.</span><span class="nx">name</span><span class="si">}</span><span class="sb">**</span><span class="err">\</span><span class="sb">n</span><span class="err">\</span><span class="sb">n`</span> <span class="o">+</span> </span></span><span class="line"><span class="cl"> <span class="sb">`- Nodes: </span><span class="si">${</span><span class="nx">label</span><span class="p">.</span><span class="nx">nodeCount</span><span class="si">}</span><span class="err">\</span><span class="sb">n`</span> <span class="o">+</span> </span></span><span class="line"><span class="cl"> <span class="sb">`- Properties: </span><span class="si">${</span><span class="nx">label</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;, &#39;</span><span class="p">)</span><span class="si">}</span><span class="err">\</span><span class="sb">n`</span> <span class="o">+</span> </span></span><span class="line"><span class="cl"> <span class="sb">`- Indexes: </span><span class="si">${</span><span class="nx">label</span><span class="p">.</span><span class="nx">indexes</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;, &#39;</span><span class="p">)</span><span class="si">}</span><span class="sb">`</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">item</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="kr">async</span> <span class="nx">getPropertyCompletions</span><span class="p">(</span><span class="nx">label?</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">vscode.CompletionItem</span><span class="err">[]</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">label</span><span class="p">)</span> <span class="k">return</span> <span class="p">[];</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">properties</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">geode</span><span class="p">.</span><span class="nx">getProperties</span><span class="p">(</span><span class="nx">label</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">properties</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">prop</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">item</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItem</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">prop</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItemKind</span><span class="p">.</span><span class="nx">Property</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">detail</span> <span class="o">=</span> <span class="sb">`</span><span class="si">${</span><span class="nx">prop</span><span class="p">.</span><span class="kr">type</span><span class="si">}${</span><span class="nx">prop</span><span class="p">.</span><span class="nx">indexed</span> <span class="o">?</span> <span class="s1">&#39; (indexed)&#39;</span> <span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="si">}</span><span class="sb">`</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">documentation</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">MarkdownString</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="sb">`**</span><span class="si">${</span><span class="nx">prop</span><span class="p">.</span><span class="nx">name</span><span class="si">}</span><span class="sb">**: </span><span class="si">${</span><span class="nx">prop</span><span class="p">.</span><span class="kr">type</span><span class="si">}</span><span class="err">\</span><span class="sb">n</span><span class="err">\</span><span class="sb">n`</span> <span class="o">+</span> </span></span><span class="line"><span class="cl"> <span class="sb">`- Nullable: </span><span class="si">${</span><span class="nx">prop</span><span class="p">.</span><span class="nx">nullable</span><span class="si">}</span><span class="err">\</span><span class="sb">n`</span> <span class="o">+</span> </span></span><span class="line"><span class="cl"> <span class="sb">`- Indexed: </span><span class="si">${</span><span class="nx">prop</span><span class="p">.</span><span class="nx">indexed</span><span class="si">}</span><span class="err">\</span><span class="sb">n`</span> <span class="o">+</span> </span></span><span class="line"><span class="cl"> <span class="sb">`- Unique: </span><span class="si">${</span><span class="nx">prop</span><span class="p">.</span><span class="kt">unique</span><span class="si">}</span><span class="sb">`</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">item</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="kr">async</span> <span class="nx">getRelationshipCompletions</span><span class="p">()</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">vscode.CompletionItem</span><span class="err">[]</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">relationships</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">geode</span><span class="p">.</span><span class="nx">getRelationships</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">relationships</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">rel</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">item</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItem</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">rel</span><span class="p">.</span><span class="kr">type</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItemKind</span><span class="p">.</span><span class="nx">Reference</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">detail</span> <span class="o">=</span> <span class="sb">`Relationship (</span><span class="si">${</span><span class="nx">rel</span><span class="p">.</span><span class="nx">count</span><span class="si">}</span><span class="sb"> edges)`</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">documentation</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">MarkdownString</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="sb">`**</span><span class="si">${</span><span class="nx">rel</span><span class="p">.</span><span class="kr">type</span><span class="si">}</span><span class="sb">**</span><span class="err">\</span><span class="sb">n</span><span class="err">\</span><span class="sb">n`</span> <span class="o">+</span> </span></span><span class="line"><span class="cl"> <span class="sb">`- Count: </span><span class="si">${</span><span class="nx">rel</span><span class="p">.</span><span class="nx">count</span><span class="si">}</span><span class="err">\</span><span class="sb">n`</span> <span class="o">+</span> </span></span><span class="line"><span class="cl"> <span class="sb">`- From: </span><span class="si">${</span><span class="nx">rel</span><span class="p">.</span><span class="nx">fromLabels</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;, &#39;</span><span class="p">)</span><span class="si">}</span><span class="err">\</span><span class="sb">n`</span> <span class="o">+</span> </span></span><span class="line"><span class="cl"> <span class="sb">`- To: </span><span class="si">${</span><span class="nx">rel</span><span class="p">.</span><span class="nx">toLabels</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;, &#39;</span><span class="p">)</span><span class="si">}</span><span class="sb">`</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">item</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">getFunctionCompletions</span><span class="p">()</span><span class="o">:</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItem</span><span class="p">[]</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">GQL_FUNCTIONS</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">fn</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">item</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItem</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">fn</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItemKind</span><span class="p">.</span><span class="nb">Function</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">detail</span> <span class="o">=</span> <span class="nx">fn</span><span class="p">.</span><span class="nx">signature</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">documentation</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">MarkdownString</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="sb">`**</span><span class="si">${</span><span class="nx">fn</span><span class="p">.</span><span class="nx">signature</span><span class="si">}</span><span class="sb">**</span><span class="err">\</span><span class="sb">n</span><span class="err">\</span><span class="sb">n</span><span class="si">${</span><span class="nx">fn</span><span class="p">.</span><span class="nx">description</span><span class="si">}</span><span class="err">\</span><span class="sb">n</span><span class="err">\</span><span class="sb">n`</span> <span class="o">+</span> </span></span><span class="line"><span class="cl"> <span class="sb">`**Example:**</span><span class="err">\</span><span class="sb">n\`\`\`gql</span><span class="err">\</span><span class="sb">n</span><span class="si">${</span><span class="nx">fn</span><span class="p">.</span><span class="nx">example</span><span class="si">}</span><span class="err">\</span><span class="sb">n\`\`\``</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">insertText</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">SnippetString</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">fn</span><span class="p">.</span><span class="nx">name</span><span class="si">}</span><span class="sb">($1)`</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">item</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">getKeywordCompletions</span><span class="p">(</span><span class="nx">previousKeyword?</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItem</span><span class="p">[]</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">keywords</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getContextualKeywords</span><span class="p">(</span><span class="nx">previousKeyword</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">keywords</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">kw</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">item</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItem</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">kw</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CompletionItemKind</span><span class="p">.</span><span class="nx">Keyword</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">detail</span> <span class="o">=</span> <span class="s1">&#39;Keyword&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">documentation</span> <span class="o">=</span> <span class="nx">kw</span><span class="p">.</span><span class="nx">description</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">kw</span><span class="p">.</span><span class="nx">snippet</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">item</span><span class="p">.</span><span class="nx">insertText</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">SnippetString</span><span class="p">(</span><span class="nx">kw</span><span class="p">.</span><span class="nx">snippet</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">item</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">inferLabel</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nb">document</span><span class="o">:</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">TextDocument</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">variable</span>: <span class="kt">string</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">position</span>: <span class="kt">vscode.Position</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span><span class="o">:</span> <span class="kt">string</span> <span class="o">|</span> <span class="kc">undefined</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Search backwards for variable binding with label </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">text</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getText</span><span class="p">(</span><span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">Range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">position</span><span class="p">.</span><span class="nx">line</span><span class="p">,</span> <span class="nx">position</span><span class="p">.</span><span class="nx">character</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">match</span> <span class="o">=</span> <span class="nx">text</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="sb">`\\(</span><span class="si">${</span><span class="nx">variable</span><span class="si">}</span><span class="sb">:(\\w+)\\)`</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">match</span> <span class="o">?</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">:</span> <span class="kc">undefined</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">getPreviousKeyword</span><span class="p">(</span><span class="nx">text</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="kt">string</span> <span class="o">|</span> <span class="kc">undefined</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">keywords</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;MATCH&#39;</span><span class="p">,</span> <span class="s1">&#39;WHERE&#39;</span><span class="p">,</span> <span class="s1">&#39;RETURN&#39;</span><span class="p">,</span> <span class="s1">&#39;CREATE&#39;</span><span class="p">,</span> <span class="s1">&#39;DELETE&#39;</span><span class="p">,</span> <span class="s1">&#39;SET&#39;</span><span class="p">,</span> <span class="s1">&#39;WITH&#39;</span><span class="p">];</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">(</span><span class="kr">const</span> <span class="nx">kw</span> <span class="k">of</span> <span class="nx">keywords</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">text</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">().</span><span class="nx">includes</span><span class="p">(</span><span class="nx">kw</span><span class="p">))</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">kw</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">undefined</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">getContextualKeywords</span><span class="p">(</span><span class="nx">previous?</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="nx">KeywordInfo</span><span class="p">[]</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Return keywords valid in current context </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">all</span> <span class="o">=</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;MATCH&#39;</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">&#39;Match patterns in the graph&#39;</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">&#39;MATCH ($1)&#39;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;WHERE&#39;</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">&#39;Filter results&#39;</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">&#39;WHERE $1&#39;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;RETURN&#39;</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">&#39;Return results&#39;</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">&#39;RETURN $1;&#39;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;CREATE&#39;</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">&#39;Create nodes/relationships&#39;</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">&#39;CREATE ($1)&#39;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;DELETE&#39;</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">&#39;Delete nodes/relationships&#39;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;SET&#39;</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">&#39;Set properties&#39;</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">&#39;SET $1 = $2&#39;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;ORDER BY&#39;</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">&#39;Order results&#39;</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">&#39;ORDER BY $1&#39;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;LIMIT&#39;</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">&#39;Limit results&#39;</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">&#39;LIMIT $1&#39;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;SKIP&#39;</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">&#39;Skip results&#39;</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">&#39;SKIP $1&#39;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">];</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Filter based on context </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="nx">previous</span> <span class="o">===</span> <span class="s1">&#39;MATCH&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">all</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">k</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="s1">&#39;WHERE&#39;</span><span class="p">,</span> <span class="s1">&#39;RETURN&#39;</span><span class="p">,</span> <span class="s1">&#39;WITH&#39;</span><span class="p">,</span> <span class="s1">&#39;CREATE&#39;</span><span class="p">,</span> <span class="s1">&#39;DELETE&#39;</span><span class="p">].</span><span class="nx">includes</span><span class="p">(</span><span class="nx">k</span><span class="p">.</span><span class="nx">name</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">previous</span> <span class="o">===</span> <span class="s1">&#39;WHERE&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">all</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">k</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="s1">&#39;AND&#39;</span><span class="p">,</span> <span class="s1">&#39;OR&#39;</span><span class="p">,</span> <span class="s1">&#39;RETURN&#39;</span><span class="p">,</span> <span class="s1">&#39;WITH&#39;</span><span class="p">].</span><span class="nx">includes</span><span class="p">(</span><span class="nx">k</span><span class="p">.</span><span class="nx">name</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">all</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">CompletionContext</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">type</span><span class="o">:</span> <span class="s1">&#39;label&#39;</span> <span class="o">|</span> <span class="s1">&#39;property&#39;</span> <span class="o">|</span> <span class="s1">&#39;relationship&#39;</span> <span class="o">|</span> <span class="s1">&#39;function&#39;</span> <span class="o">|</span> <span class="s1">&#39;function_args&#39;</span> <span class="o">|</span> <span class="s1">&#39;keyword&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">variable?</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">label?</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">previousKeyword?</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">KeywordInfo</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">name</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">description</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">snippet?</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h3 id="query-execution" class="position-relative d-flex align-items-center group"> <span>Query Execution</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="query-execution" aria-haspopup="dialog" aria-label="Share link: Query Execution"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="execution-provider" class="position-relative d-flex align-items-center group"> <span>Execution Provider</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="execution-provider" aria-haspopup="dialog" aria-label="Share link: Execution Provider"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Implement query execution with result handling:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="c1">// src/execution.ts </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">vscode</span> <span class="kr">from</span> <span class="s1">&#39;vscode&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">GeodeRequests</span><span class="p">,</span> <span class="nx">QueryResult</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;./requests&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">ResultsPanel</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;./results-panel&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">QueryExecutor</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">resultsPanel</span>: <span class="kt">ResultsPanel</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">runningQueries</span>: <span class="kt">Map</span><span class="p">&lt;</span><span class="nt">string</span><span class="err">,</span> <span class="na">vscode.CancellationTokenSource</span><span class="p">&gt;</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Map</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">constructor</span><span class="p">(</span><span class="kr">private</span> <span class="nx">geode</span>: <span class="kt">GeodeRequests</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">resultsPanel</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ResultsPanel</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">async</span> <span class="nx">executeQuery</span><span class="p">(</span><span class="nb">document</span><span class="o">:</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">TextDocument</span><span class="p">,</span> <span class="nx">selection?</span>: <span class="kt">vscode.Selection</span><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">void</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">query</span> <span class="o">=</span> <span class="nx">selection</span> </span></span><span class="line"><span class="cl"> <span class="o">?</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getText</span><span class="p">(</span><span class="nx">selection</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">getCurrentQuery</span><span class="p">(</span><span class="nb">document</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">query</span><span class="p">.</span><span class="nx">trim</span><span class="p">())</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">vscode</span><span class="p">.</span><span class="nb">window</span><span class="p">.</span><span class="nx">showWarningMessage</span><span class="p">(</span><span class="s1">&#39;No query to execute&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">queryId</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">generateQueryId</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">cancellation</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">CancellationTokenSource</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">runningQueries</span><span class="p">.</span><span class="kr">set</span><span class="p">(</span><span class="nx">queryId</span><span class="p">,</span> <span class="nx">cancellation</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Show progress </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">await</span> <span class="nx">vscode</span><span class="p">.</span><span class="nb">window</span><span class="p">.</span><span class="nx">withProgress</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">location</span>: <span class="kt">vscode.ProgressLocation.Notification</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">title</span><span class="o">:</span> <span class="s1">&#39;Executing query...&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">cancellable</span>: <span class="kt">true</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="kr">async</span> <span class="p">(</span><span class="nx">progress</span><span class="p">,</span> <span class="nx">token</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">token</span><span class="p">.</span><span class="nx">onCancellationRequested</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">cancelQuery</span><span class="p">(</span><span class="nx">queryId</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">startTime</span> <span class="o">=</span> <span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">geode</span><span class="p">.</span><span class="nx">executeQuery</span><span class="p">(</span><span class="nx">query</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">executionTime</span> <span class="o">=</span> <span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">()</span> <span class="o">-</span> <span class="nx">startTime</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">resultsPanel</span><span class="p">.</span><span class="nx">showResults</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="p">...</span><span class="nx">result</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">executionTime</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">query</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">handleError</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">finally</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">runningQueries</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">queryId</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">async</span> <span class="nx">explainQuery</span><span class="p">(</span><span class="nb">document</span><span class="o">:</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">TextDocument</span><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">void</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">query</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getCurrentQuery</span><span class="p">(</span><span class="nb">document</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">plan</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">geode</span><span class="p">.</span><span class="nx">explainQuery</span><span class="p">(</span><span class="nx">query</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">resultsPanel</span><span class="p">.</span><span class="nx">showPlan</span><span class="p">(</span><span class="nx">plan</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">handleError</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">async</span> <span class="nx">profileQuery</span><span class="p">(</span><span class="nb">document</span><span class="o">:</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">TextDocument</span><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">void</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">query</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getCurrentQuery</span><span class="p">(</span><span class="nb">document</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">profile</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">geode</span><span class="p">.</span><span class="nx">profileQuery</span><span class="p">(</span><span class="nx">query</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">resultsPanel</span><span class="p">.</span><span class="nx">showProfile</span><span class="p">(</span><span class="nx">profile</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">handleError</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">getCurrentQuery</span><span class="p">(</span><span class="nb">document</span><span class="o">:</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">TextDocument</span><span class="p">)</span><span class="o">:</span> <span class="kt">string</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">text</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getText</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">editor</span> <span class="o">=</span> <span class="nx">vscode</span><span class="p">.</span><span class="nb">window</span><span class="p">.</span><span class="nx">activeTextEditor</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">editor</span><span class="p">)</span> <span class="k">return</span> <span class="nx">text</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">position</span> <span class="o">=</span> <span class="nx">editor</span><span class="p">.</span><span class="nx">selection</span><span class="p">.</span><span class="nx">active</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">queries</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">splitQueries</span><span class="p">(</span><span class="nx">text</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Find query containing cursor </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kd">let</span> <span class="nx">currentOffset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">cursorOffset</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">offsetAt</span><span class="p">(</span><span class="nx">position</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">(</span><span class="kr">const</span> <span class="nx">query</span> <span class="k">of</span> <span class="nx">queries</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">queryEnd</span> <span class="o">=</span> <span class="nx">currentOffset</span> <span class="o">+</span> <span class="nx">query</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">cursorOffset</span> <span class="o">&gt;=</span> <span class="nx">currentOffset</span> <span class="o">&amp;&amp;</span> <span class="nx">cursorOffset</span> <span class="o">&lt;=</span> <span class="nx">queryEnd</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">query</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">currentOffset</span> <span class="o">=</span> <span class="nx">queryEnd</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// +1 for semicolon </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">text</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">splitQueries</span><span class="p">(</span><span class="nx">text</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="kt">string</span><span class="p">[]</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Split on semicolons, but respect strings </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">queries</span>: <span class="kt">string</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span> </span></span><span class="line"><span class="cl"> <span class="kd">let</span> <span class="nx">current</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kd">let</span> <span class="nx">inString</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kd">let</span> <span class="nx">stringChar</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">(</span><span class="kr">const</span> <span class="nx">char</span> <span class="k">of</span> <span class="nx">text</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">((</span><span class="nx">char</span> <span class="o">===</span> <span class="s2">&#34;&#39;&#34;</span> <span class="o">||</span> <span class="nx">char</span> <span class="o">===</span> <span class="s1">&#39;&#34;&#39;</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">inString</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">inString</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">stringChar</span> <span class="o">=</span> <span class="nx">char</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">char</span> <span class="o">===</span> <span class="nx">stringChar</span> <span class="o">&amp;&amp;</span> <span class="nx">inString</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">inString</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">char</span> <span class="o">===</span> <span class="s1">&#39;;&#39;</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">inString</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">current</span><span class="p">.</span><span class="nx">trim</span><span class="p">())</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">queries</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">current</span><span class="p">.</span><span class="nx">trim</span><span class="p">());</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">current</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">continue</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">current</span> <span class="o">+=</span> <span class="nx">char</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">current</span><span class="p">.</span><span class="nx">trim</span><span class="p">())</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">queries</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">current</span><span class="p">.</span><span class="nx">trim</span><span class="p">());</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">queries</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="kr">async</span> <span class="nx">cancelQuery</span><span class="p">(</span><span class="nx">queryId</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p">&lt;</span><span class="nt">void</span><span class="p">&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">cancellation</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">runningQueries</span><span class="p">.</span><span class="kr">get</span><span class="p">(</span><span class="nx">queryId</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">cancellation</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">cancellation</span><span class="p">.</span><span class="nx">cancel</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">geode</span><span class="p">.</span><span class="nx">cancelQuery</span><span class="p">(</span><span class="nx">queryId</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">runningQueries</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">queryId</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">handleError</span><span class="p">(</span><span class="nx">error</span>: <span class="kt">any</span><span class="p">)</span><span class="o">:</span> <span class="k">void</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="nx">error</span><span class="p">.</span><span class="nx">message</span> <span class="o">||</span> <span class="s1">&#39;Query execution failed&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">vscode</span><span class="p">.</span><span class="nb">window</span><span class="p">.</span><span class="nx">showErrorMessage</span><span class="p">(</span><span class="sb">`Geode Error: </span><span class="si">${</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">resultsPanel</span><span class="p">.</span><span class="nx">showError</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">generateQueryId</span><span class="p">()</span><span class="o">:</span> <span class="kt">string</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="sb">`query-</span><span class="si">${</span><span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">()</span><span class="si">}</span><span class="sb">-</span><span class="si">${</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">().</span><span class="nx">toString</span><span class="p">(</span><span class="mi">36</span><span class="p">).</span><span class="nx">substr</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">9</span><span class="p">)</span><span class="si">}</span><span class="sb">`</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h4 id="results-panel" class="position-relative d-flex align-items-center group"> <span>Results Panel</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="results-panel" aria-haspopup="dialog" aria-label="Share link: Results Panel"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Create a webview panel for displaying results:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="c1">// src/results-panel.ts </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">vscode</span> <span class="kr">from</span> <span class="s1">&#39;vscode&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">ResultsPanel</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">panel</span>: <span class="kt">vscode.WebviewPanel</span> <span class="o">|</span> <span class="kc">undefined</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">showResults</span><span class="p">(</span><span class="nx">result</span>: <span class="kt">QueryResultWithMeta</span><span class="p">)</span><span class="o">:</span> <span class="k">void</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ensurePanel</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">panel</span><span class="o">!</span><span class="p">.</span><span class="nx">webview</span><span class="p">.</span><span class="nx">html</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getResultsHtml</span><span class="p">(</span><span class="nx">result</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">panel</span><span class="o">!</span><span class="p">.</span><span class="nx">reveal</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">showPlan</span><span class="p">(</span><span class="nx">plan</span>: <span class="kt">ExecutionPlan</span><span class="p">)</span><span class="o">:</span> <span class="k">void</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ensurePanel</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">panel</span><span class="o">!</span><span class="p">.</span><span class="nx">webview</span><span class="p">.</span><span class="nx">html</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getPlanHtml</span><span class="p">(</span><span class="nx">plan</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">panel</span><span class="o">!</span><span class="p">.</span><span class="nx">reveal</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">showProfile</span><span class="p">(</span><span class="nx">profile</span>: <span class="kt">ProfileResult</span><span class="p">)</span><span class="o">:</span> <span class="k">void</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ensurePanel</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">panel</span><span class="o">!</span><span class="p">.</span><span class="nx">webview</span><span class="p">.</span><span class="nx">html</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getProfileHtml</span><span class="p">(</span><span class="nx">profile</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">panel</span><span class="o">!</span><span class="p">.</span><span class="nx">reveal</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">showError</span><span class="p">(</span><span class="nx">error</span>: <span class="kt">any</span><span class="p">)</span><span class="o">:</span> <span class="k">void</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ensurePanel</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">panel</span><span class="o">!</span><span class="p">.</span><span class="nx">webview</span><span class="p">.</span><span class="nx">html</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getErrorHtml</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">panel</span><span class="o">!</span><span class="p">.</span><span class="nx">reveal</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">ensurePanel</span><span class="p">()</span><span class="o">:</span> <span class="k">void</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">panel</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">panel</span> <span class="o">=</span> <span class="nx">vscode</span><span class="p">.</span><span class="nb">window</span><span class="p">.</span><span class="nx">createWebviewPanel</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;geodeResults&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;Geode Results&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">vscode</span><span class="p">.</span><span class="nx">ViewColumn</span><span class="p">.</span><span class="nx">Two</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">enableScripts</span>: <span class="kt">true</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">retainContextWhenHidden</span>: <span class="kt">true</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">panel</span><span class="p">.</span><span class="nx">onDidDispose</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">panel</span> <span class="o">=</span> <span class="kc">undefined</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">getResultsHtml</span><span class="p">(</span><span class="nx">result</span>: <span class="kt">QueryResultWithMeta</span><span class="p">)</span><span class="o">:</span> <span class="kt">string</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">tableRows</span> <span class="o">=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">rows</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">row</span> <span class="o">=&gt;</span> </span></span><span class="line"><span class="cl"> <span class="sb">`&lt;tr&gt;</span><span class="si">${</span><span class="nx">result</span><span class="p">.</span><span class="nx">columns</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">col</span> <span class="o">=&gt;</span> </span></span><span class="line"><span class="cl"> <span class="sb">`&lt;td&gt;</span><span class="si">${</span><span class="k">this</span><span class="p">.</span><span class="nx">formatValue</span><span class="p">(</span><span class="nx">row</span><span class="p">[</span><span class="nx">col</span><span class="p">])</span><span class="si">}</span><span class="sb">&lt;/td&gt;`</span> </span></span><span class="line"><span class="cl"> <span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="si">}</span><span class="sb">&lt;/tr&gt;`</span> </span></span><span class="line"><span class="cl"> <span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="sb">`&lt;!DOCTYPE html&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;html&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;head&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;style&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> body { font-family: var(--vscode-font-family); padding: 10px; } </span></span></span><span class="line"><span class="cl"><span class="sb"> .stats { color: var(--vscode-descriptionForeground); margin-bottom: 10px; } </span></span></span><span class="line"><span class="cl"><span class="sb"> table { border-collapse: collapse; width: 100%; } </span></span></span><span class="line"><span class="cl"><span class="sb"> th, td { border: 1px solid var(--vscode-panel-border); padding: 8px; text-align: left; } </span></span></span><span class="line"><span class="cl"><span class="sb"> th { background: var(--vscode-editor-lineHighlightBackground); } </span></span></span><span class="line"><span class="cl"><span class="sb"> tr:hover { background: var(--vscode-list-hoverBackground); } </span></span></span><span class="line"><span class="cl"><span class="sb"> .toolbar { margin-bottom: 10px; } </span></span></span><span class="line"><span class="cl"><span class="sb"> button { background: var(--vscode-button-background); color: var(--vscode-button-foreground); border: none; padding: 5px 10px; cursor: pointer; } </span></span></span><span class="line"><span class="cl"><span class="sb"> button:hover { background: var(--vscode-button-hoverBackground); } </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;/style&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;/head&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;body&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;div class=&#34;toolbar&#34;&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;button onclick=&#34;copyResults()&#34;&gt;Copy&lt;/button&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;button onclick=&#34;exportCsv()&#34;&gt;Export CSV&lt;/button&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;button onclick=&#34;exportJson()&#34;&gt;Export JSON&lt;/button&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;/div&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;div class=&#34;stats&#34;&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> </span><span class="si">${</span><span class="nx">result</span><span class="p">.</span><span class="nx">rowCount</span><span class="si">}</span><span class="sb"> rows in </span><span class="si">${</span><span class="nx">result</span><span class="p">.</span><span class="nx">executionTime</span><span class="si">}</span><span class="sb">ms </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;/div&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;table&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;thead&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;tr&gt;</span><span class="si">${</span><span class="nx">result</span><span class="p">.</span><span class="nx">columns</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">c</span> <span class="o">=&gt;</span> <span class="sb">`&lt;th&gt;</span><span class="si">${</span><span class="nx">c</span><span class="si">}</span><span class="sb">&lt;/th&gt;`</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="si">}</span><span class="sb">&lt;/tr&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;/thead&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;tbody&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> </span><span class="si">${</span><span class="nx">tableRows</span><span class="si">}</span><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;/tbody&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;/table&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;script&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> const vscode = acquireVsCodeApi(); </span></span></span><span class="line"><span class="cl"><span class="sb"> const results = </span><span class="si">${</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">result</span><span class="p">)</span><span class="si">}</span><span class="sb">; </span></span></span><span class="line"><span class="cl"><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"> function copyResults() { </span></span></span><span class="line"><span class="cl"><span class="sb"> vscode.postMessage({ command: &#39;copy&#39;, data: results }); </span></span></span><span class="line"><span class="cl"><span class="sb"> } </span></span></span><span class="line"><span class="cl"><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"> function exportCsv() { </span></span></span><span class="line"><span class="cl"><span class="sb"> vscode.postMessage({ command: &#39;exportCsv&#39;, data: results }); </span></span></span><span class="line"><span class="cl"><span class="sb"> } </span></span></span><span class="line"><span class="cl"><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"> function exportJson() { </span></span></span><span class="line"><span class="cl"><span class="sb"> vscode.postMessage({ command: &#39;exportJson&#39;, data: results }); </span></span></span><span class="line"><span class="cl"><span class="sb"> } </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;/script&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;/body&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;/html&gt;`</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">formatValue</span><span class="p">(</span><span class="nx">value</span>: <span class="kt">any</span><span class="p">)</span><span class="o">:</span> <span class="kt">string</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">value</span> <span class="o">===</span> <span class="kc">null</span> <span class="o">||</span> <span class="nx">value</span> <span class="o">===</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="s1">&#39;&lt;span class=&#34;null&#34;&gt;null&lt;/span&gt;&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">value</span> <span class="o">===</span> <span class="s1">&#39;object&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="sb">`&lt;pre&gt;</span><span class="si">${</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span><span class="si">}</span><span class="sb">&lt;/pre&gt;`</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">String</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">getPlanHtml</span><span class="p">(</span><span class="nx">plan</span>: <span class="kt">ExecutionPlan</span><span class="p">)</span><span class="o">:</span> <span class="kt">string</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Render execution plan as tree </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="sb">`&lt;!DOCTYPE html&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;html&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;head&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;style&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> body { font-family: var(--vscode-font-family); padding: 10px; } </span></span></span><span class="line"><span class="cl"><span class="sb"> .plan-node { margin-left: 20px; border-left: 2px solid var(--vscode-panel-border); padding-left: 10px; } </span></span></span><span class="line"><span class="cl"><span class="sb"> .node-type { font-weight: bold; color: var(--vscode-symbolIcon-functionForeground); } </span></span></span><span class="line"><span class="cl"><span class="sb"> .node-cost { color: var(--vscode-descriptionForeground); } </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;/style&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;/head&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;body&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;h2&gt;Execution Plan&lt;/h2&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;div class=&#34;plan-tree&#34;&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> </span><span class="si">${</span><span class="k">this</span><span class="p">.</span><span class="nx">renderPlanNode</span><span class="p">(</span><span class="nx">plan</span><span class="p">.</span><span class="nx">plan</span><span class="p">)</span><span class="si">}</span><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;/div&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;p&gt;Estimated cost: </span><span class="si">${</span><span class="nx">plan</span><span class="p">.</span><span class="nx">estimatedCost</span><span class="si">}</span><span class="sb">&lt;/p&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;/body&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;/html&gt;`</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">renderPlanNode</span><span class="p">(</span><span class="nx">node</span>: <span class="kt">PlanNode</span><span class="p">)</span><span class="o">:</span> <span class="kt">string</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">children</span> <span class="o">=</span> <span class="nx">node</span><span class="p">.</span><span class="nx">children</span><span class="o">?</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">c</span> <span class="o">=&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">renderPlanNode</span><span class="p">(</span><span class="nx">c</span><span class="p">)).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="o">||</span> <span class="s1">&#39;&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="sb">` </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;div class=&#34;plan-node&#34;&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;span class=&#34;node-type&#34;&gt;</span><span class="si">${</span><span class="nx">node</span><span class="p">.</span><span class="kr">type</span><span class="si">}</span><span class="sb">&lt;/span&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;span class=&#34;node-cost&#34;&gt;(cost: </span><span class="si">${</span><span class="nx">node</span><span class="p">.</span><span class="nx">cost</span><span class="si">}</span><span class="sb">, rows: </span><span class="si">${</span><span class="nx">node</span><span class="p">.</span><span class="nx">estimatedRows</span><span class="si">}</span><span class="sb">)&lt;/span&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> </span><span class="si">${</span><span class="nx">children</span><span class="si">}</span><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;/div&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> `</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">getProfileHtml</span><span class="p">(</span><span class="nx">profile</span>: <span class="kt">ProfileResult</span><span class="p">)</span><span class="o">:</span> <span class="kt">string</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Similar to results but with profiling data </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">getResultsHtml</span><span class="p">(</span><span class="nx">profile</span><span class="p">)</span> <span class="o">+</span> <span class="sb">` </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;h3&gt;Profile&lt;/h3&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;p&gt;DB Hits: </span><span class="si">${</span><span class="nx">profile</span><span class="p">.</span><span class="nx">dbHits</span><span class="si">}</span><span class="sb">&lt;/p&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;p&gt;Memory: </span><span class="si">${</span><span class="p">(</span><span class="nx">profile</span><span class="p">.</span><span class="nx">memoryUsage</span> <span class="o">/</span> <span class="mi">1024</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">).</span><span class="nx">toFixed</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="si">}</span><span class="sb"> MB&lt;/p&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> `</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">getErrorHtml</span><span class="p">(</span><span class="nx">error</span>: <span class="kt">any</span><span class="p">)</span><span class="o">:</span> <span class="kt">string</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="sb">`&lt;!DOCTYPE html&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;html&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;head&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;style&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> body { font-family: var(--vscode-font-family); padding: 10px; } </span></span></span><span class="line"><span class="cl"><span class="sb"> .error { color: var(--vscode-errorForeground); } </span></span></span><span class="line"><span class="cl"><span class="sb"> .details { background: var(--vscode-editor-background); padding: 10px; margin-top: 10px; } </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;/style&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;/head&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;body&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;h2 class=&#34;error&#34;&gt;Error&lt;/h2&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> &lt;p&gt;</span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span> <span class="o">||</span> <span class="s1">&#39;Unknown error&#39;</span><span class="si">}</span><span class="sb">&lt;/p&gt; </span></span></span><span class="line"><span class="cl"><span class="sb"> </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">code</span> <span class="o">?</span> <span class="sb">`&lt;p&gt;Code: </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">code</span><span class="si">}</span><span class="sb">&lt;/p&gt;`</span> <span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="si">}</span><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"> </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">details</span> <span class="o">?</span> <span class="sb">`&lt;div class=&#34;details&#34;&gt;&lt;pre&gt;</span><span class="si">${</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">details</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span><span class="si">}</span><span class="sb">&lt;/pre&gt;&lt;/div&gt;`</span> <span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="si">}</span><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;/body&gt; </span></span></span><span class="line"><span class="cl"><span class="sb">&lt;/html&gt;`</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h3 id="testing" class="position-relative d-flex align-items-center group"> <span>Testing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="testing" aria-haspopup="dialog" aria-label="Share link: Testing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="unit-tests" class="position-relative d-flex align-items-center group"> <span>Unit Tests</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="unit-tests" aria-haspopup="dialog" aria-label="Share link: Unit Tests"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="c1">// test/completion.test.ts </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">assert</span> <span class="kr">from</span> <span class="s1">&#39;assert&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">GeodeCompletionProvider</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;../src/completion&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nx">suite</span><span class="p">(</span><span class="s1">&#39;Completion Provider&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">test</span><span class="p">(</span><span class="s1">&#39;should complete labels after colon&#39;</span><span class="p">,</span> <span class="kr">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">provider</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GeodeCompletionProvider</span><span class="p">(</span><span class="nx">mockGeode</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nb">document</span> <span class="o">=</span> <span class="nx">createMockDocument</span><span class="p">(</span><span class="s1">&#39;MATCH (u:&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">position</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Position</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">completions</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">provider</span><span class="p">.</span><span class="nx">provideCompletionItems</span><span class="p">(</span><span class="nb">document</span><span class="p">,</span> <span class="nx">position</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">assert</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="nx">completions</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">assert</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="nx">completions</span><span class="p">.</span><span class="nx">some</span><span class="p">(</span><span class="nx">c</span> <span class="o">=&gt;</span> <span class="nx">c</span><span class="p">.</span><span class="nx">label</span> <span class="o">===</span> <span class="s1">&#39;User&#39;</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">test</span><span class="p">(</span><span class="s1">&#39;should complete properties after dot&#39;</span><span class="p">,</span> <span class="kr">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">provider</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GeodeCompletionProvider</span><span class="p">(</span><span class="nx">mockGeode</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nb">document</span> <span class="o">=</span> <span class="nx">createMockDocument</span><span class="p">(</span><span class="s1">&#39;MATCH (u:User) WHERE u.&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">position</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Position</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">23</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">completions</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">provider</span><span class="p">.</span><span class="nx">provideCompletionItems</span><span class="p">(</span><span class="nb">document</span><span class="p">,</span> <span class="nx">position</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">assert</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="nx">completions</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">assert</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="nx">completions</span><span class="p">.</span><span class="nx">some</span><span class="p">(</span><span class="nx">c</span> <span class="o">=&gt;</span> <span class="nx">c</span><span class="p">.</span><span class="nx">label</span> <span class="o">===</span> <span class="s1">&#39;email&#39;</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"><span class="p">});</span> </span></span></code></pre></div> <h4 id="integration-tests" class="position-relative d-flex align-items-center group"> <span>Integration Tests</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="integration-tests" aria-haspopup="dialog" aria-label="Share link: Integration Tests"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="c1">// test/integration/execution.test.ts </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">vscode</span> <span class="kr">from</span> <span class="s1">&#39;vscode&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">assert</span> <span class="kr">from</span> <span class="s1">&#39;assert&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nx">suite</span><span class="p">(</span><span class="s1">&#39;Query Execution Integration&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">suiteSetup</span><span class="p">(</span><span class="kr">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Activate extension </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">ext</span> <span class="o">=</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">extensions</span><span class="p">.</span><span class="nx">getExtension</span><span class="p">(</span><span class="s1">&#39;geodedb.geode-gql&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="nx">ext</span><span class="o">?</span><span class="p">.</span><span class="nx">activate</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">test</span><span class="p">(</span><span class="s1">&#39;should execute simple query&#39;</span><span class="p">,</span> <span class="kr">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">doc</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">workspace</span><span class="p">.</span><span class="nx">openTextDocument</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">language</span><span class="o">:</span> <span class="s1">&#39;gql&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">content</span><span class="o">:</span> <span class="s1">&#39;RETURN 1 + 1 AS result;&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="nx">vscode</span><span class="p">.</span><span class="nb">window</span><span class="p">.</span><span class="nx">showTextDocument</span><span class="p">(</span><span class="nx">doc</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="nx">vscode</span><span class="p">.</span><span class="nx">commands</span><span class="p">.</span><span class="nx">executeCommand</span><span class="p">(</span><span class="s1">&#39;geode.executeQuery&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Verify results panel appeared </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// Check result value </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">});</span> </span></span><span class="line"><span class="cl"><span class="p">});</span> </span></span></code></pre></div> <h3 id="publishing" class="position-relative d-flex align-items-center group"> <span>Publishing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="publishing" aria-haspopup="dialog" aria-label="Share link: Publishing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="vs-code-marketplace" class="position-relative d-flex align-items-center group"> <span>VS Code Marketplace</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="vs-code-marketplace" aria-haspopup="dialog" aria-label="Share link: VS Code Marketplace"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="c1">// package.json </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;geode-gql&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;displayName&#34;</span><span class="p">:</span> <span class="s2">&#34;Geode GQL&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;description&#34;</span><span class="p">:</span> <span class="s2">&#34;GQL language support for Geode graph database&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;1.0.0&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;publisher&#34;</span><span class="p">:</span> <span class="s2">&#34;geodedb&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;engines&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;vscode&#34;</span><span class="p">:</span> <span class="s2">&#34;^1.85.0&#34;</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;categories&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;Programming Languages&#34;</span><span class="p">,</span> <span class="s2">&#34;Linters&#34;</span><span class="p">,</span> <span class="s2">&#34;Formatters&#34;</span><span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;activationEvents&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;onLanguage:gql&#34;</span><span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;main&#34;</span><span class="p">:</span> <span class="s2">&#34;./out/extension.js&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;contributes&#34;</span><span class="p">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;languages&#34;</span><span class="p">:</span> <span class="p">[{</span> <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;gql&#34;</span><span class="p">,</span> <span class="nt">&#34;extensions&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;.gql&#34;</span><span class="p">],</span> <span class="nt">&#34;aliases&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;GQL&#34;</span><span class="p">]</span> <span class="p">}],</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;grammars&#34;</span><span class="p">:</span> <span class="p">[{</span> <span class="nt">&#34;language&#34;</span><span class="p">:</span> <span class="s2">&#34;gql&#34;</span><span class="p">,</span> <span class="nt">&#34;scopeName&#34;</span><span class="p">:</span> <span class="s2">&#34;source.gql&#34;</span><span class="p">,</span> <span class="nt">&#34;path&#34;</span><span class="p">:</span> <span class="s2">&#34;./syntaxes/gql.tmLanguage.json&#34;</span> <span class="p">}],</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;commands&#34;</span><span class="p">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">&#34;command&#34;</span><span class="p">:</span> <span class="s2">&#34;geode.executeQuery&#34;</span><span class="p">,</span> <span class="nt">&#34;title&#34;</span><span class="p">:</span> <span class="s2">&#34;Execute Query&#34;</span> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p><strong>Publishing</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Install vsce</span> </span></span><span class="line"><span class="cl">npm install -g @vscode/vsce </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Package extension</span> </span></span><span class="line"><span class="cl">vsce package </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Publish</span> </span></span><span class="line"><span class="cl">vsce publish </span></span></code></pre></div> <h4 id="neovim-plugin-registry" class="position-relative d-flex align-items-center group"> <span>Neovim Plugin Registry</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="neovim-plugin-registry" aria-haspopup="dialog" aria-label="Share link: Neovim Plugin Registry"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Submit to awesome-neovim and nvim-lspconfig.</p> <h4 id="vimorg" class="position-relative d-flex align-items-center group"> <span>Vim.org</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="vimorg" aria-haspopup="dialog" aria-label="Share link: Vim.org"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Submit to vim.org scripts or use vim-plug registry.</p> <h3 id="best-practices" class="position-relative d-flex align-items-center group"> <span>Best Practices</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="best-practices" aria-haspopup="dialog" aria-label="Share link: Best Practices"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p><strong>Use LSP for Cross-Editor Features</strong>: Implement features in the language server to share across editors.</p> <p><strong>Follow Editor Conventions</strong>: Match UI patterns and keybindings of the target editor.</p> <p><strong>Handle Errors Gracefully</strong>: Provide clear error messages and recovery options.</p> <p><strong>Support Offline Mode</strong>: Cache schema for basic completion when disconnected.</p> <p><strong>Document Configuration</strong>: Provide clear documentation for all settings.</p> <p><strong>Test Thoroughly</strong>: Cover unit, integration, and end-to-end scenarios.</p> <p><strong>Version Compatibility</strong>: Support multiple editor versions where possible.</p> <p><strong>Performance</strong>: Keep completion and diagnostics fast (&lt; 100ms).</p> <h3 id="related-topics" class="position-relative d-flex align-items-center group"> <span>Related Topics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="related-topics" aria-haspopup="dialog" aria-label="Share link: Related Topics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><a href="/tags/vscode/" >VS Code Extension</a> - VS Code integration details</li> <li><a href="/tags/neovim/" >Neovim Plugin</a> - Neovim configuration</li> <li><a href="/tags/vim/" >Vim Plugin</a> - Vim setup guide</li> <li><a href="/tags/editor/" >Editor Integrations</a> - Overview of all integrations</li> <li><a href="/tags/ide/" >IDE Integration</a> - IDE-specific features</li> <li><a href="/docs/development/lsp-guide/" >LSP Guide</a> - LSP implementation</li> </ul> <h3 id="further-reading" class="position-relative d-flex align-items-center group"> <span>Further Reading</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="further-reading" aria-haspopup="dialog" aria-label="Share link: Further Reading"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li>Language Server Protocol Specification</li> <li>VS Code Extension API</li> <li>Neovim Plugin Development</li> <li>Tree-sitter Grammar Development</li> <li>TextMate Grammar Reference</li> <li>Editor Plugin Best Practices</li> </ul>

Related Articles