<!-- 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’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’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’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">'vscode-languageclient/node'</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">'geode'</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">'lsp'</span><span class="p">,</span> <span class="s1">'--stdio'</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">'file'</span><span class="p">,</span> <span class="nx">language</span><span class="o">:</span> <span class="s1">'gql'</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">'untitled'</span><span class="p">,</span> <span class="nx">language</span><span class="o">:</span> <span class="s1">'gql'</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">'**/*.gql'</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">'geode'</span><span class="p">).</span><span class="kr">get</span><span class="p">(</span><span class="s1">'host'</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">'geode'</span><span class="p">).</span><span class="kr">get</span><span class="p">(</span><span class="s1">'port'</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">'geode'</span><span class="p">).</span><span class="kr">get</span><span class="p">(</span><span class="s1">'database'</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">'geode-gql'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Geode GQL Language Server'</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">'vscode-languageclient/node'</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">'geode/connectionStatus'</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">=></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">'geode/schemaChanged'</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">=></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">'geode/queryProgress'</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">=></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">'geode/diagnosticsUpdated'</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">=></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">'labels'</span> <span class="o">|</span> <span class="s1">'relationships'</span> <span class="o">|</span> <span class="s1">'indexes'</span> <span class="o">|</span> <span class="s1">'full'</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">'vscode-languageclient/node'</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"><</span><span class="nt">string</span><span class="err">,</span> <span class="na">any</span><span class="p">>)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">QueryResult</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">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">'geode/executeQuery'</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"><</span><span class="nt">ExecutionPlan</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">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">'geode/explainQuery'</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"><</span><span class="nt">ProfileResult</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">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">'geode/profileQuery'</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"><</span><span class="nt">Schema</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">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">'geode/getSchema'</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"><</span><span class="nt">LabelInfo</span><span class="err">[]</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">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">'geode/getLabels'</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"><</span><span class="nt">PropertyInfo</span><span class="err">[]</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">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">'geode/getProperties'</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"><</span><span class="nt">RelationshipInfo</span><span class="err">[]</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">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">'geode/getRelationships'</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"><</span><span class="nt">void</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">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">'geode/cancelQuery'</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">"$schema"</span><span class="p">:</span> <span class="s2">"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"name"</span><span class="p">:</span> <span class="s2">"GQL"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"scopeName"</span><span class="p">:</span> <span class="s2">"source.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">"include"</span><span class="p">:</span> <span class="s2">"#comments"</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">"include"</span><span class="p">:</span> <span class="s2">"#strings"</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">"include"</span><span class="p">:</span> <span class="s2">"#numbers"</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">"include"</span><span class="p">:</span> <span class="s2">"#keywords"</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">"include"</span><span class="p">:</span> <span class="s2">"#functions"</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">"include"</span><span class="p">:</span> <span class="s2">"#labels"</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">"include"</span><span class="p">:</span> <span class="s2">"#relationships"</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">"include"</span><span class="p">:</span> <span class="s2">"#properties"</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">"include"</span><span class="p">:</span> <span class="s2">"#variables"</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">"include"</span><span class="p">:</span> <span class="s2">"#operators"</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">"repository"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"comments"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"comment.line.double-dash.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"--.*$"</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">"name"</span><span class="p">:</span> <span class="s2">"comment.block.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"begin"</span><span class="p">:</span> <span class="s2">"/\\*"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"end"</span><span class="p">:</span> <span class="s2">"\\*/"</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">"strings"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"string.quoted.single.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"begin"</span><span class="p">:</span> <span class="s2">"'"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"end"</span><span class="p">:</span> <span class="s2">"'"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"constant.character.escape.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\\\."</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">"name"</span><span class="p">:</span> <span class="s2">"string.quoted.double.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"begin"</span><span class="p">:</span> <span class="s2">"\""</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"end"</span><span class="p">:</span> <span class="s2">"\""</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"constant.character.escape.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\\\."</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">"numbers"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"constant.numeric.float.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\b\\d+\\.\\d+([eE][+-]?\\d+)?\\b"</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">"name"</span><span class="p">:</span> <span class="s2">"constant.numeric.integer.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\b\\d+\\b"</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">"keywords"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"keyword.control.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\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"</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">"name"</span><span class="p">:</span> <span class="s2">"keyword.operator.logical.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\b(?i:AND|OR|NOT|XOR|IN|IS|NULL|TRUE|FALSE)\\b"</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">"name"</span><span class="p">:</span> <span class="s2">"keyword.control.transaction.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\b(?i:BEGIN|COMMIT|ROLLBACK|TRANSACTION)\\b"</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">"functions"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"support.function.aggregate.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\b(?i:COUNT|SUM|AVG|MIN|MAX|COLLECT|STDEV|PERCENTILE)\\b"</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">"name"</span><span class="p">:</span> <span class="s2">"support.function.string.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\b(?i:UPPER|LOWER|TRIM|LTRIM|RTRIM|SUBSTRING|REPLACE|SPLIT|REVERSE|SIZE|LENGTH)\\b"</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">"name"</span><span class="p">:</span> <span class="s2">"support.function.math.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\b(?i:ABS|CEIL|FLOOR|ROUND|SIGN|RAND|LOG|LOG10|EXP|SQRT|SIN|COS|TAN)\\b"</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">"name"</span><span class="p">:</span> <span class="s2">"support.function.temporal.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\b(?i:DATE|DATETIME|TIME|DURATION|LOCALDATETIME|LOCALTIME)\\b"</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">"name"</span><span class="p">:</span> <span class="s2">"support.function.misc.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\b(?i:COALESCE|NULLIF|ID|TYPE|LABELS|PROPERTIES|KEYS|NODES|RELATIONSHIPS|HEAD|TAIL|LAST)\\b"</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">"labels"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"entity.name.type.label.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">":\\s*([A-Za-z_][A-Za-z0-9_]*)"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"captures"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"1"</span><span class="p">:</span> <span class="p">{</span> <span class="nt">"name"</span><span class="p">:</span> <span class="s2">"entity.name.type.gql"</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">"relationships"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"entity.name.type.relationship.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"-\\[\\s*:?([A-Za-z_][A-Za-z0-9_]*)"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"captures"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"1"</span><span class="p">:</span> <span class="p">{</span> <span class="nt">"name"</span><span class="p">:</span> <span class="s2">"entity.name.type.gql"</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">"properties"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"variable.other.property.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\.([A-Za-z_][A-Za-z0-9_]*)"</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">"variables"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"variable.parameter.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\$([A-Za-z_][A-Za-z0-9_]*)"</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">"operators"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"patterns"</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">"name"</span><span class="p">:</span> <span class="s2">"keyword.operator.comparison.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"=|<>|!=|<|>|<=|>=|=~"</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">"name"</span><span class="p">:</span> <span class="s2">"keyword.operator.arithmetic.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\+|-|\\*|/|%|\\^"</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">"name"</span><span class="p">:</span> <span class="s2">"keyword.operator.string.gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"match"</span><span class="p">:</span> <span class="s2">"\\b(?i:STARTS|ENDS|CONTAINS|LIKE)\\b"</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">'gql'</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">=></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">=></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">=></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">';'</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">=></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">'MATCH'</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">=></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">=></span> <span class="nx">seq</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'('</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">')'</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">=></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">'-['</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">']-'</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">'-['</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">']->'</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">'<-['</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">']-'</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">=></span> <span class="nx">seq</span><span class="p">(</span><span class="s1">':'</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">=></span> <span class="nx">seq</span><span class="p">(</span><span class="s1">':'</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">=></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">=></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">=></span> <span class="nx">seq</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'{'</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">','</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">'}'</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">=></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">':'</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">=></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">'WHERE'</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">=></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">'RETURN'</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">','</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">=></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">'AS'</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">=></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">'('</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">')'</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">=></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">=></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">"'"</span><span class="p">,</span> <span class="sr">/[^']*/</span><span class="p">,</span> <span class="s2">"'"</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">'"'</span><span class="p">,</span> <span class="sr">/[^"]*/</span><span class="p">,</span> <span class="s1">'"'</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">=></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">=></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">'TRUE'</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">'FALSE'</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">=></span> <span class="nx">caseInsensitive</span><span class="p">(</span><span class="s1">'NULL'</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">=></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">'.'</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">=></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">'('</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">','</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">')'</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">=></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">'+'</span><span class="p">,</span> <span class="s1">'-'</span><span class="p">,</span> <span class="s1">'*'</span><span class="p">,</span> <span class="s1">'/'</span><span class="p">,</span> <span class="s1">'='</span><span class="p">,</span> <span class="s1">'<>'</span><span class="p">,</span> <span class="s1">'<'</span><span class="p">,</span> <span class="s1">'>'</span><span class="p">,</span> <span class="s1">'<='</span><span class="p">,</span> <span class="s1">'>='</span><span class="p">,</span> <span class="s1">'AND'</span><span class="p">,</span> <span class="s1">'OR'</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">=></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">'NOT'</span><span class="p">,</span> <span class="s1">'-'</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">=></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">'--'</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">'/*'</span><span class="p">,</span> <span class="sr">/[^*]*\*+([^/*][^*]*\*+)*/</span><span class="p">,</span> <span class="s1">'/'</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">''</span><span class="p">).</span><span class="nx">map</span><span class="p">(</span><span class="nx">c</span> <span class="p">=></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">''</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">'vscode'</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">'./requests'</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"><</span><span class="nt">vscode.CompletionItem</span><span class="err">[]</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">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">'label'</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">'property'</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">'relationship'</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">'function'</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">'keyword'</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">'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 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">'property'</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">'relationship'</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">'function_args'</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">'keyword'</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"><</span><span class="nt">vscode.CompletionItem</span><span class="err">[]</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">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">=></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">', '</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">', '</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"><</span><span class="nt">vscode.CompletionItem</span><span class="err">[]</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="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">=></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">' (indexed)'</span> <span class="o">:</span> <span class="s1">''</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"><</span><span class="nt">vscode.CompletionItem</span><span class="err">[]</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">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">=></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">', '</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">', '</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">=></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">=></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">'Keyword'</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">'MATCH'</span><span class="p">,</span> <span class="s1">'WHERE'</span><span class="p">,</span> <span class="s1">'RETURN'</span><span class="p">,</span> <span class="s1">'CREATE'</span><span class="p">,</span> <span class="s1">'DELETE'</span><span class="p">,</span> <span class="s1">'SET'</span><span class="p">,</span> <span class="s1">'WITH'</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">'MATCH'</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">'Match patterns in the graph'</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">'MATCH ($1)'</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">'WHERE'</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">'Filter results'</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">'WHERE $1'</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">'RETURN'</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">'Return results'</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">'RETURN $1;'</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">'CREATE'</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">'Create nodes/relationships'</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">'CREATE ($1)'</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">'DELETE'</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">'Delete nodes/relationships'</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">'SET'</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">'Set properties'</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">'SET $1 = $2'</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">'ORDER BY'</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">'Order results'</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">'ORDER BY $1'</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">'LIMIT'</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">'Limit results'</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">'LIMIT $1'</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">'SKIP'</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s1">'Skip results'</span><span class="p">,</span> <span class="nx">snippet</span><span class="o">:</span> <span class="s1">'SKIP $1'</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">'MATCH'</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">=></span> <span class="p">[</span><span class="s1">'WHERE'</span><span class="p">,</span> <span class="s1">'RETURN'</span><span class="p">,</span> <span class="s1">'WITH'</span><span class="p">,</span> <span class="s1">'CREATE'</span><span class="p">,</span> <span class="s1">'DELETE'</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">'WHERE'</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">=></span> <span class="p">[</span><span class="s1">'AND'</span><span class="p">,</span> <span class="s1">'OR'</span><span class="p">,</span> <span class="s1">'RETURN'</span><span class="p">,</span> <span class="s1">'WITH'</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">'label'</span> <span class="o">|</span> <span class="s1">'property'</span> <span class="o">|</span> <span class="s1">'relationship'</span> <span class="o">|</span> <span class="s1">'function'</span> <span class="o">|</span> <span class="s1">'function_args'</span> <span class="o">|</span> <span class="s1">'keyword'</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">'vscode'</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">'./requests'</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">'./results-panel'</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"><</span><span class="nt">string</span><span class="err">,</span> <span class="na">vscode.CancellationTokenSource</span><span class="p">></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"><</span><span class="nt">void</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">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">'No query to execute'</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">'Executing query...'</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">=></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">=></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"><</span><span class="nt">void</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">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"><</span><span class="nt">void</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">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">>=</span> <span class="nx">currentOffset</span> <span class="o">&&</span> <span class="nx">cursorOffset</span> <span class="o"><=</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">''</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">''</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">"'"</span> <span class="o">||</span> <span class="nx">char</span> <span class="o">===</span> <span class="s1">'"'</span><span class="p">)</span> <span class="o">&&</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">&&</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">';'</span> <span class="o">&&</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">''</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"><</span><span class="nt">void</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">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">'Query execution failed'</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">'vscode'</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">'geodeResults'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Geode Results'</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">=></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">=></span>
</span></span><span class="line"><span class="cl"> <span class="sb">`<tr></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">=></span>
</span></span><span class="line"><span class="cl"> <span class="sb">`<td></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"></td>`</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">''</span><span class="p">)</span><span class="si">}</span><span class="sb"></tr>`</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">''</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">`<!DOCTYPE html>
</span></span></span><span class="line"><span class="cl"><span class="sb"><html>
</span></span></span><span class="line"><span class="cl"><span class="sb"><head>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <style>
</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"> </style>
</span></span></span><span class="line"><span class="cl"><span class="sb"></head>
</span></span></span><span class="line"><span class="cl"><span class="sb"><body>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <div class="toolbar">
</span></span></span><span class="line"><span class="cl"><span class="sb"> <button onclick="copyResults()">Copy</button>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <button onclick="exportCsv()">Export CSV</button>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <button onclick="exportJson()">Export JSON</button>
</span></span></span><span class="line"><span class="cl"><span class="sb"> </div>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <div class="stats">
</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"> </div>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <table>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <thead>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <tr></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">=></span> <span class="sb">`<th></span><span class="si">${</span><span class="nx">c</span><span class="si">}</span><span class="sb"></th>`</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">''</span><span class="p">)</span><span class="si">}</span><span class="sb"></tr>
</span></span></span><span class="line"><span class="cl"><span class="sb"> </thead>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <tbody>
</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"> </tbody>
</span></span></span><span class="line"><span class="cl"><span class="sb"> </table>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <script>
</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: 'copy', 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: 'exportCsv', 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: 'exportJson', 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"> </script>
</span></span></span><span class="line"><span class="cl"><span class="sb"></body>
</span></span></span><span class="line"><span class="cl"><span class="sb"></html>`</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">'<span class="null">null</span>'</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">'object'</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">`<pre></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"></pre>`</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">`<!DOCTYPE html>
</span></span></span><span class="line"><span class="cl"><span class="sb"><html>
</span></span></span><span class="line"><span class="cl"><span class="sb"><head>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <style>
</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"> </style>
</span></span></span><span class="line"><span class="cl"><span class="sb"></head>
</span></span></span><span class="line"><span class="cl"><span class="sb"><body>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <h2>Execution Plan</h2>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <div class="plan-tree">
</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"> </div>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <p>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"></p>
</span></span></span><span class="line"><span class="cl"><span class="sb"></body>
</span></span></span><span class="line"><span class="cl"><span class="sb"></html>`</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">=></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">''</span><span class="p">)</span> <span class="o">||</span> <span class="s1">''</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"> <div class="plan-node">
</span></span></span><span class="line"><span class="cl"><span class="sb"> <span class="node-type"></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"></span>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <span class="node-cost">(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">)</span>
</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"> </div>
</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"> <h3>Profile</h3>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <p>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"></p>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <p>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</p>
</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">`<!DOCTYPE html>
</span></span></span><span class="line"><span class="cl"><span class="sb"><html>
</span></span></span><span class="line"><span class="cl"><span class="sb"><head>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <style>
</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"> </style>
</span></span></span><span class="line"><span class="cl"><span class="sb"></head>
</span></span></span><span class="line"><span class="cl"><span class="sb"><body>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <h2 class="error">Error</h2>
</span></span></span><span class="line"><span class="cl"><span class="sb"> <p></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">'Unknown error'</span><span class="si">}</span><span class="sb"></p>
</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">`<p>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"></p>`</span> <span class="o">:</span> <span class="s1">''</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">`<div class="details"><pre></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"></pre></div>`</span> <span class="o">:</span> <span class="s1">''</span><span class="si">}</span><span class="sb">
</span></span></span><span class="line"><span class="cl"><span class="sb"></body>
</span></span></span><span class="line"><span class="cl"><span class="sb"></html>`</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">'assert'</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">'../src/completion'</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">'Completion Provider'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></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">'should complete labels after colon'</span><span class="p">,</span> <span class="kr">async</span> <span class="p">()</span> <span class="o">=></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">'MATCH (u:'</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">></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">=></span> <span class="nx">c</span><span class="p">.</span><span class="nx">label</span> <span class="o">===</span> <span class="s1">'User'</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">'should complete properties after dot'</span><span class="p">,</span> <span class="kr">async</span> <span class="p">()</span> <span class="o">=></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">'MATCH (u:User) WHERE u.'</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">></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">=></span> <span class="nx">c</span><span class="p">.</span><span class="nx">label</span> <span class="o">===</span> <span class="s1">'email'</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">'vscode'</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">'assert'</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">'Query Execution Integration'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></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">=></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">'geodedb.geode-gql'</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">'should execute simple query'</span><span class="p">,</span> <span class="kr">async</span> <span class="p">()</span> <span class="o">=></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">'gql'</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">'RETURN 1 + 1 AS result;'</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">'geode.executeQuery'</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">"name"</span><span class="p">:</span> <span class="s2">"geode-gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"displayName"</span><span class="p">:</span> <span class="s2">"Geode GQL"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"description"</span><span class="p">:</span> <span class="s2">"GQL language support for Geode graph database"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"version"</span><span class="p">:</span> <span class="s2">"1.0.0"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"publisher"</span><span class="p">:</span> <span class="s2">"geodedb"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"engines"</span><span class="p">:</span> <span class="p">{</span> <span class="nt">"vscode"</span><span class="p">:</span> <span class="s2">"^1.85.0"</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"categories"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"Programming Languages"</span><span class="p">,</span> <span class="s2">"Linters"</span><span class="p">,</span> <span class="s2">"Formatters"</span><span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"activationEvents"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"onLanguage:gql"</span><span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"main"</span><span class="p">:</span> <span class="s2">"./out/extension.js"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"contributes"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"languages"</span><span class="p">:</span> <span class="p">[{</span> <span class="nt">"id"</span><span class="p">:</span> <span class="s2">"gql"</span><span class="p">,</span> <span class="nt">"extensions"</span><span class="p">:</span> <span class="p">[</span><span class="s2">".gql"</span><span class="p">],</span> <span class="nt">"aliases"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"GQL"</span><span class="p">]</span> <span class="p">}],</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"grammars"</span><span class="p">:</span> <span class="p">[{</span> <span class="nt">"language"</span><span class="p">:</span> <span class="s2">"gql"</span><span class="p">,</span> <span class="nt">"scopeName"</span><span class="p">:</span> <span class="s2">"source.gql"</span><span class="p">,</span> <span class="nt">"path"</span><span class="p">:</span> <span class="s2">"./syntaxes/gql.tmLanguage.json"</span> <span class="p">}],</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"commands"</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nt">"command"</span><span class="p">:</span> <span class="s2">"geode.executeQuery"</span><span class="p">,</span> <span class="nt">"title"</span><span class="p">:</span> <span class="s2">"Execute 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></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 (< 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>
Tag
4 articles
Plugin Development for Geode
Comprehensive guide to developing editor plugins and extensions for Geode GQL including Language Server Protocol implementation, syntax highlighting, auto-completion sources, query execution integration, and publishing to editor marketplaces.