<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 -->
<p>Geode documentation tagged with <strong>Language Server Protocol (LSP)</strong>. LSP is a standardized protocol for language tooling that enables IDE features like auto-completion, error checking, and refactoring across editors without requiring editor-specific implementations.</p>
<h3 id="introduction-to-language-server-protocol" class="position-relative d-flex align-items-center group">
<span>Introduction to Language Server Protocol</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="introduction-to-language-server-protocol"
aria-haspopup="dialog"
aria-label="Share link: Introduction to Language Server Protocol">
<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><p>The Language Server Protocol (LSP) was created by Microsoft in 2016 to solve a long-standing problem in developer tooling: implementing sophisticated language features for every editor/language combination required M × N implementations. With LSP, a single language server can provide features to any LSP-compliant editor, reducing the implementation burden from M × N to M + N. This architectural shift has enabled rich IDE experiences across VS Code, Vim, Emacs, Sublime Text, and many other editors.</p>
<p>For query languages like GQL, LSP integration transforms the development experience. Rather than writing queries in plain text and discovering syntax errors at execution time, developers get immediate feedback as they type. Auto-completion suggests table names, column names, and functions. Hover tooltips display documentation. Go-to-definition jumps to label definitions. These features, commonplace for programming languages, dramatically improve productivity when working with database queries.</p>
<p>Geode’s LSP server provides comprehensive GQL language support to any LSP-compatible editor. The server understands GQL syntax, connects to your database to fetch schema information, and provides intelligent suggestions based on your actual graph structure. Whether you write queries in VS Code, Vim, or any other modern editor, you get the same high-quality development experience with syntax validation, smart auto-completion, and real-time error checking.</p>
<h3 id="key-concepts" class="position-relative d-flex align-items-center group">
<span>Key Concepts</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="key-concepts"
aria-haspopup="dialog"
aria-label="Share link: Key Concepts">
<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="language-server-architecture" class="position-relative d-flex align-items-center group">
<span>Language Server Architecture</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-architecture"
aria-haspopup="dialog"
aria-label="Share link: Language Server Architecture">
<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>LSP uses a client-server architecture:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">┌─────────────┐ ┌─────────────────┐
</span></span><span class="line"><span class="cl">│ Editor │ JSON-RPC/stdio │ Language │
</span></span><span class="line"><span class="cl">│ (Client) │<------------------>│ Server │
</span></span><span class="line"><span class="cl">│ │ │ (Geode LSP) │
</span></span><span class="line"><span class="cl">└─────────────┘ └─────────────────┘
</span></span><span class="line"><span class="cl"> │
</span></span><span class="line"><span class="cl"> │ QUIC
</span></span><span class="line"><span class="cl"> ▼
</span></span><span class="line"><span class="cl"> ┌─────────────────┐
</span></span><span class="line"><span class="cl"> │ Geode │
</span></span><span class="line"><span class="cl"> │ Database │
</span></span><span class="line"><span class="cl"> └─────────────────┘
</span></span></code></pre></div><ul>
<li><strong>Client</strong>: Editor plugin that implements LSP client protocol</li>
<li><strong>Server</strong>: Geode LSP server that provides language intelligence</li>
<li><strong>Communication</strong>: JSON-RPC messages over stdin/stdout</li>
<li><strong>Database Connection</strong>: LSP server connects to Geode for schema info</li>
</ul>
<h4 id="lsp-capabilities" class="position-relative d-flex align-items-center group">
<span>LSP Capabilities</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="lsp-capabilities"
aria-haspopup="dialog"
aria-label="Share link: LSP Capabilities">
<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>The protocol defines standard capabilities:</p>
<ul>
<li><strong>textDocument/completion</strong>: Auto-completion suggestions</li>
<li><strong>textDocument/hover</strong>: Hover tooltips with documentation</li>
<li><strong>textDocument/definition</strong>: Go-to-definition navigation</li>
<li><strong>textDocument/references</strong>: Find all references</li>
<li><strong>textDocument/documentSymbol</strong>: Document outline</li>
<li><strong>textDocument/formatting</strong>: Code formatting</li>
<li><strong>textDocument/diagnostics</strong>: Real-time error checking</li>
<li><strong>textDocument/codeAction</strong>: Quick fixes and refactorings</li>
</ul>
<h4 id="document-synchronization" class="position-relative d-flex align-items-center group">
<span>Document Synchronization</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="document-synchronization"
aria-haspopup="dialog"
aria-label="Share link: Document Synchronization">
<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>LSP tracks document state:</p>
<ul>
<li><strong>didOpen</strong>: Editor opens a GQL file</li>
<li><strong>didChange</strong>: User edits the document</li>
<li><strong>didSave</strong>: User saves changes</li>
<li><strong>didClose</strong>: Editor closes the document</li>
</ul>
<p>The server maintains a synchronized copy of each document to provide accurate suggestions.</p>
<h4 id="schema-aware-features" class="position-relative d-flex align-items-center group">
<span>Schema-Aware Features</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="schema-aware-features"
aria-haspopup="dialog"
aria-label="Share link: Schema-Aware Features">
<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>Geode’s LSP server uses database schema for intelligent suggestions:</p>
<ul>
<li><strong>Label Completion</strong>: Suggests available node labels</li>
<li><strong>Property Completion</strong>: Suggests properties for specific labels</li>
<li><strong>Relationship Types</strong>: Suggests valid relationship types</li>
<li><strong>Function Signatures</strong>: Shows parameter lists for functions</li>
<li><strong>Index Hints</strong>: Suggests indexes for query optimization</li>
</ul>
<h3 id="how-lsp-works-in-geode" class="position-relative d-flex align-items-center group">
<span>How LSP Works in Geode</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="how-lsp-works-in-geode"
aria-haspopup="dialog"
aria-label="Share link: How LSP Works in Geode">
<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="installation-and-setup" class="position-relative d-flex align-items-center group">
<span>Installation and Setup</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="installation-and-setup"
aria-haspopup="dialog"
aria-label="Share link: Installation and Setup">
<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>Install the Geode LSP server:</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 globally</span>
</span></span><span class="line"><span class="cl">npm install -g @geodedb/language-server
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Or use with editor plugin (VS Code example)</span>
</span></span><span class="line"><span class="cl">code --install-extension geodedb.gql-language-server
</span></span></code></pre></div><p>Configure connection to your database:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="c1">// .vscode/settings.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">"gql.server.host"</span><span class="p">:</span> <span class="s2">"localhost"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.server.port"</span><span class="p">:</span> <span class="mi">3141</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.server.database"</span><span class="p">:</span> <span class="s2">"mydb"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.server.tls"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.validation.enabled"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.completion.autoComplete"</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
<h4 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>
</h4><p>The LSP server provides context-aware suggestions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Pe</span><span class="p">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">^^</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">Person</span><span class="w"> </span><span class="p">[</span><span class="py">label</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">Product</span><span class="w"> </span><span class="p">[</span><span class="py">label</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">Pet</span><span class="w"> </span><span class="p">[</span><span class="py">label</span><span class="p">]</span><span class="w">
</span></span></span></code></pre></div><p>After selecting a label, property suggestions appear:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">na</span><span class="p">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">^^</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">name</span><span class="w"> </span><span class="p">[</span><span class="py">property</span><span class="p">:</span><span class="w"> </span><span class="nc">STRING</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">nationality</span><span class="w"> </span><span class="p">[</span><span class="py">property</span><span class="p">:</span><span class="w"> </span><span class="nc">STRING</span><span class="p">]</span><span class="w">
</span></span></span></code></pre></div><p>Relationship type completion:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">WO</span><span class="p">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">^^</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WORKS_AT</span><span class="w"> </span><span class="p">[</span><span class="py">relationship</span><span class="w"> </span><span class="kd">type</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nc">WORKED_WITH</span><span class="w"> </span><span class="p">[</span><span class="py">relationship</span><span class="w"> </span><span class="kd">type</span><span class="p">]</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="error-checking" class="position-relative d-flex align-items-center group">
<span>Error Checking</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="error-checking"
aria-haspopup="dialog"
aria-label="Share link: Error Checking">
<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>Real-time diagnostics highlight issues:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="err">'</span><span class="py">thirty</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">^^^^^^^^</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">Error</span><span class="p">:</span><span class="w"> </span><span class="nc">Type</span><span class="w"> </span><span class="py">mismatch</span><span class="p">:</span><span class="w"> </span><span class="nc">cannot</span><span class="w"> </span><span class="py">compare</span><span class="w"> </span><span class="py">INTEGER</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">STRING</span><span class="w">
</span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">UnknownLabel</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">^^^^^^^^^^^^</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">Warning</span><span class="p">:</span><span class="w"> </span><span class="nc">Label</span><span class="w"> </span><span class="err">'</span><span class="py">UnknownLabel</span><span class="err">'</span><span class="w"> </span><span class="py">does</span><span class="w"> </span><span class="py">not</span><span class="w"> </span><span class="py">exist</span><span class="w"> </span><span class="py">in</span><span class="w"> </span><span class="kd">schema</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="hover-documentation" class="position-relative d-flex align-items-center group">
<span>Hover Documentation</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="hover-documentation"
aria-haspopup="dialog"
aria-label="Share link: Hover Documentation">
<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>Hovering over keywords shows documentation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">^^^^^</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="py">clause</span><span class="p">:</span><span class="w"> </span><span class="nc">Specify</span><span class="w"> </span><span class="py">graph</span><span class="w"> </span><span class="py">patterns</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">match</span><span class="w"> </span><span class="py">against</span><span class="w"> </span><span class="py">the</span><span class="w"> </span><span class="py">database</span><span class="err">.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">Syntax</span><span class="p">:</span><span class="w"> </span><span class="nc">MATCH</span><span class="w"> </span><span class="err"><</span><span class="py">pattern</span><span class="err">></span><span class="w"> </span><span class="p">[</span><span class="py">WHERE</span><span class="w"> </span><span class="err"><</span><span class="py">condition</span><span class="err">></span><span class="p">]</span><span class="w">
</span></span></span></code></pre></div><p>Hovering over properties shows type information:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">^^^^^</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">Property</span><span class="p">:</span><span class="w"> </span><span class="nc">email</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">Type</span><span class="p">:</span><span class="w"> </span><span class="nc">STRING</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">Indexed</span><span class="p">:</span><span class="w"> </span><span class="nc">UNIQUE</span><span class="w"> </span><span class="py">BTREE</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">Description</span><span class="p">:</span><span class="w"> </span><span class="nc">User</span><span class="err">'</span><span class="py">s</span><span class="w"> </span><span class="py">email</span><span class="w"> </span><span class="py">address</span><span class="w"> </span><span class="p">(</span><span class="py">unique</span><span class="w"> </span><span class="py">identifier</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="go-to-definition" class="position-relative d-flex align-items-center group">
<span>Go-to-Definition</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="go-to-definition"
aria-haspopup="dialog"
aria-label="Share link: Go-to-Definition">
<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>Jump to label or property definitions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Ctrl</span><span class="err">+</span><span class="py">Click</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="s">"Person"</span><span class="w"> </span><span class="py">jumps</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="kd">schema</span><span class="w"> </span><span class="py">definition</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">^^^^^^</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Jump</span><span class="w"> </span><span class="py">to</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">CREATE</span><span class="w"> </span><span class="py">LABEL</span><span class="w"> </span><span class="py">Person</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="py">INTEGER</span><span class="w"> </span><span class="py">PRIMARY</span><span class="w"> </span><span class="py">KEY</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">name</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">email</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">UNIQUE</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">age</span><span class="w"> </span><span class="py">INTEGER</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="query-formatting" class="position-relative d-flex align-items-center group">
<span>Query Formatting</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-formatting"
aria-haspopup="dialog"
aria-label="Share link: Query Formatting">
<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>Auto-format GQL queries:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">//</span><span class="w"> </span><span class="py">Before</span><span class="w"> </span><span class="py">formatting</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">f</span><span class="p">)</span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="err">></span><span class="py">30RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="py">f</span><span class="err">.</span><span class="py">name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">//</span><span class="w"> </span><span class="py">After</span><span class="w"> </span><span class="py">formatting</span><span class="w"> </span><span class="p">(</span><span class="py">Shift</span><span class="err">+</span><span class="py">Alt</span><span class="err">+</span><span class="py">F</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">f</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">30</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">f</span><span class="err">.</span><span class="py">name</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="use-cases" class="position-relative d-flex align-items-center group">
<span>Use Cases</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="use-cases"
aria-haspopup="dialog"
aria-label="Share link: Use Cases">
<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-integration" class="position-relative d-flex align-items-center group">
<span>VS Code Integration</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-integration"
aria-haspopup="dialog"
aria-label="Share link: VS Code Integration">
<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">// .vscode/settings.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">"gql.server.host"</span><span class="p">:</span> <span class="s2">"localhost"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.server.port"</span><span class="p">:</span> <span class="mi">3141</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.validation.enabled"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.completion.autoComplete"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.format.enable"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.hover.documentation"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.trace.server"</span><span class="p">:</span> <span class="s2">"verbose"</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Create GQL file and get full IDE support:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">//</span><span class="w"> </span><span class="py">queries</span><span class="err">.</span><span class="py">gql</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">Full</span><span class="w"> </span><span class="py">LSP</span><span class="w"> </span><span class="py">support</span><span class="w"> </span><span class="py">enabled</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">WORKS_AT</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="nv">$minAge</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">industry</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nv">$industry</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">employee</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">name</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">company</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">salary</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">salary</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">salary</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">10</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="vimneovim-integration" class="position-relative d-flex align-items-center group">
<span>Vim/Neovim Integration</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="vimneovim-integration"
aria-haspopup="dialog"
aria-label="Share link: Vim/Neovim Integration">
<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-lua" data-lang="lua"><span class="line"><span class="cl"><span class="c1">-- init.lua</span>
</span></span><span class="line"><span class="cl"><span class="n">require</span><span class="p">(</span><span class="s1">'lspconfig'</span><span class="p">).</span><span class="n">geode_gql.setup</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="n">cmd</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">'geode-language-server'</span><span class="p">,</span> <span class="s1">'--stdio'</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="n">filetypes</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">'gql'</span><span class="p">,</span> <span class="s1">'geode'</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="n">root_dir</span> <span class="o">=</span> <span class="n">require</span><span class="p">(</span><span class="s1">'lspconfig'</span><span class="p">).</span><span class="n">util.root_pattern</span><span class="p">(</span><span class="s1">'.git'</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="n">settings</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">geode</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">server</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">host</span> <span class="o">=</span> <span class="s1">'localhost'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">port</span> <span class="o">=</span> <span class="mi">3141</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="n">validation</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">enabled</span> <span class="o">=</span> <span class="kc">true</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="emacs-integration" class="position-relative d-flex align-items-center group">
<span>Emacs Integration</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="emacs-integration"
aria-haspopup="dialog"
aria-label="Share link: Emacs Integration">
<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-elisp" data-lang="elisp"><span class="line"><span class="cl"><span class="c1">;; init.el</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">use-package</span> <span class="nv">lsp-mode</span>
</span></span><span class="line"><span class="cl"> <span class="nb">:hook</span> <span class="p">((</span><span class="nv">gql-mode</span> <span class="o">.</span> <span class="nv">lsp</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"> <span class="nb">:config</span>
</span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nv">lsp-register-client</span>
</span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nv">make-lsp-client</span>
</span></span><span class="line"><span class="cl"> <span class="nb">:new-connection</span> <span class="p">(</span><span class="nv">lsp-stdio-connection</span> <span class="s">"geode-language-server"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nb">:major-modes</span> <span class="o">'</span><span class="p">(</span><span class="nv">gql-mode</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nb">:server-id</span> <span class="ss">'geode-gql</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">setq</span> <span class="nv">lsp-geode-server-host</span> <span class="s">"localhost"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">setq</span> <span class="nv">lsp-geode-server-port</span> <span class="mi">3141</span><span class="p">)</span>
</span></span></code></pre></div>
<h4 id="jupyter-notebook-integration" class="position-relative d-flex align-items-center group">
<span>Jupyter Notebook Integration</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="jupyter-notebook-integration"
aria-haspopup="dialog"
aria-label="Share link: Jupyter Notebook Integration">
<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-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Enable LSP in Jupyter cells with %%gql magic</span>
</span></span><span class="line"><span class="cl"><span class="o">%</span><span class="n">load_ext</span> <span class="n">geode_jupyter</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">%%</span><span class="n">gql</span>
</span></span><span class="line"><span class="cl"><span class="n">MATCH</span> <span class="p">(</span><span class="n">p</span><span class="p">:</span><span class="n">Person</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">WHERE</span> <span class="n">p</span><span class="o">.</span><span class="n">age</span> <span class="o">></span> <span class="mi">30</span> <span class="c1"># Auto-completion works here!</span>
</span></span><span class="line"><span class="cl"><span class="n">RETURN</span> <span class="n">p</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">email</span>
</span></span></code></pre></div>
<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>
<h4 id="editor-configuration" class="position-relative d-flex align-items-center group">
<span>Editor Configuration</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="editor-configuration"
aria-haspopup="dialog"
aria-label="Share link: Editor Configuration">
<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><ol>
<li><strong>Enable All Features</strong>: Turn on validation, completion, and formatting</li>
<li><strong>Configure Connection</strong>: Set database connection parameters</li>
<li><strong>File Associations</strong>: Associate <code>.gql</code> files with GQL language mode</li>
<li><strong>Keybindings</strong>: Set up convenient shortcuts for common operations</li>
<li><strong>Diagnostics Level</strong>: Configure warning/error severity</li>
</ol>
<h4 id="query-development" class="position-relative d-flex align-items-center group">
<span>Query Development</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-development"
aria-haspopup="dialog"
aria-label="Share link: Query Development">
<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><ol>
<li><strong>Let LSP Guide</strong>: Follow auto-completion suggestions</li>
<li><strong>Fix Errors Early</strong>: Address red squiggles immediately</li>
<li><strong>Use Hover</strong>: Read documentation without leaving editor</li>
<li><strong>Format Frequently</strong>: Format queries for consistency</li>
<li><strong>Navigate with LSP</strong>: Use go-to-definition for exploration</li>
</ol>
<h4 id="schema-management" class="position-relative d-flex align-items-center group">
<span>Schema Management</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="schema-management"
aria-haspopup="dialog"
aria-label="Share link: Schema Management">
<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><ol>
<li><strong>Keep Schema Updated</strong>: LSP reflects current database schema</li>
<li><strong>Reload After Changes</strong>: Refresh LSP after schema modifications</li>
<li><strong>Document Schema</strong>: Add comments that appear in hover tooltips</li>
<li><strong>Use Type Hints</strong>: Leverage type information for correctness</li>
</ol>
<h4 id="performance-optimization" class="position-relative d-flex align-items-center group">
<span>Performance Optimization</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="performance-optimization"
aria-haspopup="dialog"
aria-label="Share link: Performance Optimization">
<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><ol>
<li><strong>Lazy Loading</strong>: Configure LSP to load schema on demand</li>
<li><strong>Cache Settings</strong>: Enable schema caching for large databases</li>
<li><strong>Selective Completion</strong>: Limit suggestions for very large schemas</li>
<li><strong>Debounce Validation</strong>: Adjust validation debounce time</li>
</ol>
<h3 id="performance-considerations" class="position-relative d-flex align-items-center group">
<span>Performance Considerations</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="performance-considerations"
aria-haspopup="dialog"
aria-label="Share link: Performance Considerations">
<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="startup-time" class="position-relative d-flex align-items-center group">
<span>Startup Time</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="startup-time"
aria-haspopup="dialog"
aria-label="Share link: Startup Time">
<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>LSP server initialization is fast:</p>
<ul>
<li><strong>Server Start</strong>: 100-300ms cold start</li>
<li><strong>Schema Loading</strong>: 50-200ms depending on schema size</li>
<li><strong>First Completion</strong>: <10ms after initialization</li>
<li><strong>Incremental Updates</strong>: <5ms for document changes</li>
</ul>
<h4 id="memory-usage" class="position-relative d-flex align-items-center group">
<span>Memory Usage</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="memory-usage"
aria-haspopup="dialog"
aria-label="Share link: Memory Usage">
<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>LSP server is lightweight:</p>
<ul>
<li><strong>Base Memory</strong>: ~50MB for server process</li>
<li><strong>Schema Cache</strong>: ~1-5MB for typical schemas</li>
<li><strong>Document State</strong>: ~10KB per open document</li>
<li><strong>Total</strong>: <100MB for typical usage</li>
</ul>
<h4 id="completion-performance" class="position-relative d-flex align-items-center group">
<span>Completion Performance</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-performance"
aria-haspopup="dialog"
aria-label="Share link: Completion Performance">
<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>Auto-completion is very responsive:</p>
<ul>
<li><strong>Keyword Completion</strong>: <1ms (pre-computed)</li>
<li><strong>Label Completion</strong>: 1-5ms (schema lookup)</li>
<li><strong>Property Completion</strong>: 2-10ms (filtered by label)</li>
<li><strong>Complex Queries</strong>: <20ms even with large schemas</li>
</ul>
<h3 id="troubleshooting" class="position-relative d-flex align-items-center group">
<span>Troubleshooting</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="troubleshooting"
aria-haspopup="dialog"
aria-label="Share link: Troubleshooting">
<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="lsp-server-not-starting" class="position-relative d-flex align-items-center group">
<span>LSP Server Not Starting</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="lsp-server-not-starting"
aria-haspopup="dialog"
aria-label="Share link: LSP Server Not Starting">
<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><strong>Symptom</strong>: Editor shows “Language server failed to start”</p>
<p><strong>Solutions</strong>:</p>
<ul>
<li>Verify <code>geode-language-server</code> is in PATH</li>
<li>Check server logs in editor output panel</li>
<li>Confirm Node.js version >= 16</li>
<li>Test server manually: <code>geode-language-server --stdio</code></li>
<li>Review editor’s LSP configuration</li>
</ul>
<h4 id="no-auto-completion" class="position-relative d-flex align-items-center group">
<span>No 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="no-auto-completion"
aria-haspopup="dialog"
aria-label="Share link: No 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>
</h4><p><strong>Symptom</strong>: Auto-completion not appearing</p>
<p><strong>Solutions</strong>:</p>
<ul>
<li>Verify file has <code>.gql</code> extension</li>
<li>Check LSP client is enabled for GQL files</li>
<li>Confirm database connection settings</li>
<li>Test schema loading: hover over existing label</li>
<li>Restart LSP server</li>
</ul>
<h4 id="incorrect-suggestions" class="position-relative d-flex align-items-center group">
<span>Incorrect Suggestions</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="incorrect-suggestions"
aria-haspopup="dialog"
aria-label="Share link: Incorrect Suggestions">
<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><strong>Symptom</strong>: Wrong or outdated suggestions</p>
<p><strong>Solutions</strong>:</p>
<ul>
<li>Refresh schema cache</li>
<li>Verify LSP connected to correct database</li>
<li>Check for schema changes not yet loaded</li>
<li>Clear LSP cache and restart</li>
<li>Review database connection status</li>
</ul>
<h4 id="performance-issues" class="position-relative d-flex align-items-center group">
<span>Performance Issues</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="performance-issues"
aria-haspopup="dialog"
aria-label="Share link: Performance Issues">
<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><strong>Symptom</strong>: Slow auto-completion or validation</p>
<p><strong>Solutions</strong>:</p>
<ul>
<li>Enable schema caching</li>
<li>Increase debounce time for validation</li>
<li>Limit completion result count</li>
<li>Check network latency to database</li>
<li>Review LSP trace logs for bottlenecks</li>
</ul>
<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/ide/"
>IDE Integration</a>
- Editor and IDE features</li>
<li><a
href="/tags/tools/"
>Developer Tools</a>
- Development tooling</li>
<li><a
href="/tags/gql-syntax/"
>GQL Syntax</a>
- GQL language syntax</li>
<li><a
href="/tags/development/"
>Query Development</a>
- Query development workflow</li>
<li><a
href="/tags/productivity/"
>Productivity</a>
- Developer productivity</li>
<li><a
href="/tags/tooling/"
>Tooling</a>
- Development tools ecosystem</li>
</ul>
<h3 id="implementation-details" class="position-relative d-flex align-items-center group">
<span>Implementation Details</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="implementation-details"
aria-haspopup="dialog"
aria-label="Share link: Implementation Details">
<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="language-server-architecture-1" class="position-relative d-flex align-items-center group">
<span>Language Server Architecture</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-architecture-1"
aria-haspopup="dialog"
aria-label="Share link: Language Server Architecture">
<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>Geode’s LSP server implements the full LSP specification:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">┌──────────────────────────────────────────────┐
</span></span><span class="line"><span class="cl">│ Editor (VS Code, Vim, Emacs, etc.) │
</span></span><span class="line"><span class="cl">│ - UI rendering │
</span></span><span class="line"><span class="cl">│ - User input handling │
</span></span><span class="line"><span class="cl">│ - LSP client implementation │
</span></span><span class="line"><span class="cl">└────────────────┬─────────────────────────────┘
</span></span><span class="line"><span class="cl"> │ JSON-RPC over stdio/socket
</span></span><span class="line"><span class="cl">┌────────────────▼─────────────────────────────┐
</span></span><span class="line"><span class="cl">│ Geode Language Server │
</span></span><span class="line"><span class="cl">│ ┌──────────────────────────────────────┐ │
</span></span><span class="line"><span class="cl">│ │ Protocol Handler │ │
</span></span><span class="line"><span class="cl">│ │ - Message routing │ │
</span></span><span class="line"><span class="cl">│ │ - Request/response matching │ │
</span></span><span class="line"><span class="cl">│ └────────────┬─────────────────────────┘ │
</span></span><span class="line"><span class="cl">│ │ │
</span></span><span class="line"><span class="cl">│ ┌────────────▼─────────────────────────┐ │
</span></span><span class="line"><span class="cl">│ │ Document Manager │ │
</span></span><span class="line"><span class="cl">│ │ - Tracks open documents │ │
</span></span><span class="line"><span class="cl">│ │ - Synchronizes changes │ │
</span></span><span class="line"><span class="cl">│ │ - Caches parsed ASTs │ │
</span></span><span class="line"><span class="cl">│ └────────────┬─────────────────────────┘ │
</span></span><span class="line"><span class="cl">│ │ │
</span></span><span class="line"><span class="cl">│ ┌────────────▼─────────────────────────┐ │
</span></span><span class="line"><span class="cl">│ │ GQL Parser & Analyzer │ │
</span></span><span class="line"><span class="cl">│ │ - Lexical analysis │ │
</span></span><span class="line"><span class="cl">│ │ - Syntax parsing │ │
</span></span><span class="line"><span class="cl">│ │ - Semantic analysis │ │
</span></span><span class="line"><span class="cl">│ │ - Type checking │ │
</span></span><span class="line"><span class="cl">│ └────────────┬─────────────────────────┘ │
</span></span><span class="line"><span class="cl">│ │ │
</span></span><span class="line"><span class="cl">│ ┌────────────▼─────────────────────────┐ │
</span></span><span class="line"><span class="cl">│ │ Schema Provider │ │
</span></span><span class="line"><span class="cl">│ │ - Connects to Geode database │ │
</span></span><span class="line"><span class="cl">│ │ - Caches schema information │ │
</span></span><span class="line"><span class="cl">│ │ - Provides label/property metadata │ │
</span></span><span class="line"><span class="cl">│ └────────────┬─────────────────────────┘ │
</span></span><span class="line"><span class="cl">│ │ │
</span></span><span class="line"><span class="cl">│ ┌────────────▼─────────────────────────┐ │
</span></span><span class="line"><span class="cl">│ │ Feature Providers │ │
</span></span><span class="line"><span class="cl">│ │ - Completion │ │
</span></span><span class="line"><span class="cl">│ │ - Hover │ │
</span></span><span class="line"><span class="cl">│ │ - Definition │ │
</span></span><span class="line"><span class="cl">│ │ - Diagnostics │ │
</span></span><span class="line"><span class="cl">│ │ - Formatting │ │
</span></span><span class="line"><span class="cl">│ └──────────────────────────────────────┘ │
</span></span><span class="line"><span class="cl">└──────────────┬───────────────────────────────┘
</span></span><span class="line"><span class="cl"> │ QUIC/TLS
</span></span><span class="line"><span class="cl">┌──────────────▼───────────────────────────────┐
</span></span><span class="line"><span class="cl">│ Geode Database Server │
</span></span><span class="line"><span class="cl">│ - Schema metadata │
</span></span><span class="line"><span class="cl">│ - Index information │
</span></span><span class="line"><span class="cl">│ - Query validation │
</span></span><span class="line"><span class="cl">└──────────────────────────────────────────────┘
</span></span></code></pre></div>
<h4 id="completion-provider-implementation" class="position-relative d-flex align-items-center group">
<span>Completion Provider Implementation</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-implementation"
aria-haspopup="dialog"
aria-label="Share link: Completion Provider Implementation">
<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">// Simplified TypeScript pseudocode
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">class</span> <span class="nx">CompletionProvider</span> <span class="p">{</span>
</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">TextDocument</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">position</span>: <span class="kt">Position</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">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">line</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">line</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">context</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getContext</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></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="kr">type</span> <span class="o">===</span> <span class="s1">'LABEL'</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Provide label completions
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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">schemaProvider</span><span class="p">.</span><span class="nx">getLabels</span><span class="p">();</span>
</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="nx">label</span>: <span class="kt">label.name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">kind</span>: <span class="kt">CompletionItemKind.Class</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">detail</span><span class="o">:</span> <span class="sb">`Label with </span><span class="si">${</span><span class="nx">label</span><span class="p">.</span><span class="nx">propertyCount</span><span class="si">}</span><span class="sb"> properties`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">documentation</span>: <span class="kt">label.description</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">insertText</span>: <span class="kt">label.name</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">if</span> <span class="p">(</span><span class="nx">context</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="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Provide property completions for specific label
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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">schemaProvider</span><span class="p">.</span><span class="nx">getProperties</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="nx">context</span><span class="p">.</span><span class="nx">labelName</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">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="nx">label</span>: <span class="kt">prop.name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">kind</span>: <span class="kt">CompletionItemKind.Property</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <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">nullable</span> <span class="o">?</span> <span class="s1">' | null'</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">documentation</span>: <span class="kt">prop.description</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">insertText</span>: <span class="kt">prop.name</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">if</span> <span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="kr">type</span> <span class="o">===</span> <span class="s1">'RELATIONSHIP_TYPE'</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Provide relationship type completions
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">types</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">schemaProvider</span><span class="p">.</span><span class="nx">getRelationshipTypes</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">types</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="kr">type</span> <span class="o">=></span> <span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">label</span>: <span class="kt">type.name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">kind</span>: <span class="kt">CompletionItemKind.Reference</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">detail</span><span class="o">:</span> <span class="sb">`</span><span class="si">${</span><span class="kr">type</span><span class="p">.</span><span class="nx">fromLabel</span><span class="si">}</span><span class="sb"> -> </span><span class="si">${</span><span class="kr">type</span><span class="p">.</span><span class="nx">toLabel</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">documentation</span>: <span class="kt">type.description</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">insertText</span>: <span class="kt">type.name</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">// Default: GQL keywords
</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">getKeywordCompletions</span><span class="p">(</span><span class="nx">context</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">getKeywordCompletions</span><span class="p">(</span><span class="nx">context</span>: <span class="kt">Context</span><span class="p">)</span><span class="o">:</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="p">[</span>
</span></span><span class="line"><span class="cl"> <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></span><span class="line"><span class="cl"> <span class="s1">'MERGE'</span><span class="p">,</span> <span class="s1">'WITH'</span><span class="p">,</span> <span class="s1">'ORDER BY'</span><span class="p">,</span> <span class="s1">'LIMIT'</span><span class="p">,</span> <span class="s1">'SKIP'</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="k">return</span> <span class="nx">keywords</span>
</span></span><span class="line"><span class="cl"> <span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">kw</span> <span class="o">=></span> <span class="nx">kw</span><span class="p">.</span><span class="nx">startsWith</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nx">prefix</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">()))</span>
</span></span><span class="line"><span class="cl"> <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="nx">label</span>: <span class="kt">kw</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">kind</span>: <span class="kt">CompletionItemKind.Keyword</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">insertText</span>: <span class="kt">kw</span> <span class="o">+</span> <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 class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
<h4 id="diagnostic-provider-implementation" class="position-relative d-flex align-items-center group">
<span>Diagnostic Provider Implementation</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="diagnostic-provider-implementation"
aria-haspopup="dialog"
aria-label="Share link: Diagnostic Provider Implementation">
<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="kr">class</span> <span class="nx">DiagnosticProvider</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">async</span> <span class="nx">provideDiagnostics</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">TextDocument</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">Diagnostic</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">diagnostics</span>: <span class="kt">Diagnostic</span><span class="p">[]</span> <span class="o">=</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">// Parse query
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">ast</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">parser</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</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></span><span class="line"><span class="cl"> <span class="c1">// Validate against schema
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">schemaErrors</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">validateSchema</span><span class="p">(</span><span class="nx">ast</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="nx">diagnostics</span><span class="p">.</span><span class="nx">push</span><span class="p">(...</span><span class="nx">schemaErrors</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Type checking
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">typeErrors</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">checkTypes</span><span class="p">(</span><span class="nx">ast</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="nx">diagnostics</span><span class="p">.</span><span class="nx">push</span><span class="p">(...</span><span class="nx">typeErrors</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Best practices warnings
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">warnings</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">checkBestPractices</span><span class="p">(</span><span class="nx">ast</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="nx">diagnostics</span><span class="p">.</span><span class="nx">push</span><span class="p">(...</span><span class="nx">warnings</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">syntaxError</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Syntax error from parser
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">diagnostics</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">range</span>: <span class="kt">this.getErrorRange</span><span class="p">(</span><span class="nx">syntaxError</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">message</span>: <span class="kt">syntaxError.message</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">severity</span>: <span class="kt">DiagnosticSeverity.Error</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">source</span><span class="o">:</span> <span class="s1">'gql-parser'</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">return</span> <span class="nx">diagnostics</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">validateSchema</span><span class="p">(</span><span class="nx">ast</span>: <span class="kt">ASTNode</span><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">Diagnostic</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">diagnostics</span>: <span class="kt">Diagnostic</span><span class="p">[]</span> <span class="o">=</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">node</span> <span class="k">of</span> <span class="nx">ast</span><span class="p">.</span><span class="nx">matchClauses</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">node</span><span class="p">.</span><span class="nx">label</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Check if label exists
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">labelExists</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">schemaProvider</span><span class="p">.</span><span class="nx">hasLabel</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="nx">node</span><span class="p">.</span><span class="nx">label</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="o">!</span><span class="nx">labelExists</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">diagnostics</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">range</span>: <span class="kt">node.labelRange</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="o">:</span> <span class="sb">`Label '</span><span class="si">${</span><span class="nx">node</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span><span class="sb">' does not exist in schema`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">severity</span>: <span class="kt">DiagnosticSeverity.Warning</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">source</span><span class="o">:</span> <span class="s1">'gql-schema'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">code</span><span class="o">:</span> <span class="s1">'unknown-label'</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">// Check properties
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">for</span> <span class="p">(</span><span class="kr">const</span> <span class="nx">prop</span> <span class="k">of</span> <span class="nx">node</span><span class="p">.</span><span class="nx">properties</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">propExists</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">schemaProvider</span><span class="p">.</span><span class="nx">hasProperty</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="nx">node</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">prop</span><span class="p">.</span><span class="nx">name</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="o">!</span><span class="nx">propExists</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">diagnostics</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">range</span>: <span class="kt">prop.range</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="o">:</span> <span class="sb">`Property '</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">' does not exist on label '</span><span class="si">${</span><span class="nx">node</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span><span class="sb">'`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">severity</span>: <span class="kt">DiagnosticSeverity.Error</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">source</span><span class="o">:</span> <span class="s1">'gql-schema'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">code</span><span class="o">:</span> <span class="s1">'unknown-property'</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></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">diagnostics</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">checkTypes</span><span class="p">(</span><span class="nx">ast</span>: <span class="kt">ASTNode</span><span class="p">)</span><span class="o">:</span> <span class="nx">Diagnostic</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">diagnostics</span>: <span class="kt">Diagnostic</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Type check comparisons
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">for</span> <span class="p">(</span><span class="kr">const</span> <span class="nx">comparison</span> <span class="k">of</span> <span class="nx">ast</span><span class="p">.</span><span class="nx">comparisons</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">leftType</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">inferType</span><span class="p">(</span><span class="nx">comparison</span><span class="p">.</span><span class="nx">left</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">rightType</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">inferType</span><span class="p">(</span><span class="nx">comparison</span><span class="p">.</span><span class="nx">right</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="k">this</span><span class="p">.</span><span class="nx">typesCompatible</span><span class="p">(</span><span class="nx">leftType</span><span class="p">,</span> <span class="nx">rightType</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">diagnostics</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">range</span>: <span class="kt">comparison.range</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="o">:</span> <span class="sb">`Type mismatch: cannot compare </span><span class="si">${</span><span class="nx">leftType</span><span class="si">}</span><span class="sb"> with </span><span class="si">${</span><span class="nx">rightType</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">severity</span>: <span class="kt">DiagnosticSeverity.Error</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">source</span><span class="o">:</span> <span class="s1">'gql-type-checker'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">code</span><span class="o">:</span> <span class="s1">'type-mismatch'</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="k">return</span> <span class="nx">diagnostics</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">checkBestPractices</span><span class="p">(</span><span class="nx">ast</span>: <span class="kt">ASTNode</span><span class="p">)</span><span class="o">:</span> <span class="nx">Diagnostic</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">diagnostics</span>: <span class="kt">Diagnostic</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Check for unbounded traversals
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">for</span> <span class="p">(</span><span class="kr">const</span> <span class="nx">pattern</span> <span class="k">of</span> <span class="nx">ast</span><span class="p">.</span><span class="nx">patterns</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">pattern</span><span class="p">.</span><span class="nx">isVariableLength</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">pattern</span><span class="p">.</span><span class="nx">hasMaxDepth</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">diagnostics</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">range</span>: <span class="kt">pattern.range</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="o">:</span> <span class="s1">'Unbounded variable-length pattern may cause performance issues'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">severity</span>: <span class="kt">DiagnosticSeverity.Warning</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">source</span><span class="o">:</span> <span class="s1">'gql-best-practices'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">code</span><span class="o">:</span> <span class="s1">'unbounded-traversal'</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">// Check for missing LIMIT
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ast</span><span class="p">.</span><span class="nx">hasLimit</span> <span class="o">&&</span> <span class="nx">ast</span><span class="p">.</span><span class="nx">matchClauses</span><span class="p">.</span><span class="nx">length</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">diagnostics</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">range</span>: <span class="kt">ast.range</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="o">:</span> <span class="s1">'Consider adding LIMIT clause to bound result set'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">severity</span>: <span class="kt">DiagnosticSeverity.Hint</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">source</span><span class="o">:</span> <span class="s1">'gql-best-practices'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">code</span><span class="o">:</span> <span class="s1">'missing-limit'</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">return</span> <span class="nx">diagnostics</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="schema-caching-strategy" class="position-relative d-flex align-items-center group">
<span>Schema Caching Strategy</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="schema-caching-strategy"
aria-haspopup="dialog"
aria-label="Share link: Schema Caching Strategy">
<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="kr">class</span> <span class="nx">SchemaProvider</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">cache</span>: <span class="kt">Map</span><span class="p"><</span><span class="nt">string</span><span class="err">,</span> <span class="na">CacheEntry</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 class="kr">private</span> <span class="nx">cacheTimeout</span> <span class="o">=</span> <span class="mi">300000</span><span class="p">;</span> <span class="c1">// 5 minutes
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"> <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">Label</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">cacheKey</span> <span class="o">=</span> <span class="s1">'labels'</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="k">this</span><span class="p">.</span><span class="nx">isCached</span><span class="p">(</span><span class="nx">cacheKey</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">cache</span><span class="p">.</span><span class="kr">get</span><span class="p">(</span><span class="nx">cacheKey</span><span class="p">)</span><span class="o">!</span><span class="p">.</span><span class="nx">data</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">// Fetch from database
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <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">client</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span><span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb"> SHOW LABELS
</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></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="kr">set</span><span class="p">(</span><span class="nx">cacheKey</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">data</span>: <span class="kt">labels</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">timestamp</span>: <span class="kt">Date.now</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">labels</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">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">Property</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">cacheKey</span> <span class="o">=</span> <span class="sb">`properties:</span><span class="si">${</span><span class="nx">label</span><span class="si">}</span><span class="sb">`</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="k">this</span><span class="p">.</span><span class="nx">isCached</span><span class="p">(</span><span class="nx">cacheKey</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">cache</span><span class="p">.</span><span class="kr">get</span><span class="p">(</span><span class="nx">cacheKey</span><span class="p">)</span><span class="o">!</span><span class="p">.</span><span class="nx">data</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">properties</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span><span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb"> SHOW PROPERTIES FOR (:</span><span class="si">${</span><span class="nx">label</span><span class="si">}</span><span class="sb">)
</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></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="kr">set</span><span class="p">(</span><span class="nx">cacheKey</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">data</span>: <span class="kt">properties</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">timestamp</span>: <span class="kt">Date.now</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">properties</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">invalidateCache() {</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">clear</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">isCached</span><span class="p">(</span><span class="nx">key</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="kr">boolean</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">entry</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="kr">get</span><span class="p">(</span><span class="nx">key</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">entry</span><span class="p">)</span> <span class="k">return</span> <span class="kc">false</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">age</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">entry</span><span class="p">.</span><span class="nx">timestamp</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">age</span> <span class="o">></span> <span class="k">this</span><span class="p">.</span><span class="nx">cacheTimeout</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">cache</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">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="k">return</span> <span class="kc">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></code></pre></div>
<h3 id="advanced-ide-features" class="position-relative d-flex align-items-center group">
<span>Advanced IDE Features</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="advanced-ide-features"
aria-haspopup="dialog"
aria-label="Share link: Advanced IDE Features">
<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="inlay-hints" class="position-relative d-flex align-items-center group">
<span>Inlay Hints</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="inlay-hints"
aria-haspopup="dialog"
aria-label="Share link: Inlay Hints">
<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>Display inferred types inline:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">PURCHASED</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Product</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">^^</span><span class="py">User</span><span class="w"> </span><span class="err">^^</span><span class="py">Product</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">price</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">100</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">^^</span><span class="py">number</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">u</span><span class="p">,</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">p</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">purchase_count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">^^</span><span class="py">number</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">purchase_count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">^^</span><span class="py">string</span><span class="w"> </span><span class="err">^^</span><span class="py">number</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="code-actions-quick-fixes" class="position-relative d-flex align-items-center group">
<span>Code Actions (Quick Fixes)</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="code-actions-quick-fixes"
aria-haspopup="dialog"
aria-label="Share link: Code Actions (Quick Fixes)">
<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>Provide automated fixes for common issues:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">//</span><span class="w"> </span><span class="py">Before</span><span class="p">:</span><span class="w"> </span><span class="nc">unbounded</span><span class="w"> </span><span class="py">traversal</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="err">*</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">▲</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">Quick</span><span class="w"> </span><span class="py">fix</span><span class="p">:</span><span class="w"> </span><span class="nc">Add</span><span class="w"> </span><span class="py">depth</span><span class="w"> </span><span class="py">limit</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">//</span><span class="w"> </span><span class="py">After</span><span class="p">:</span><span class="w"> </span><span class="nc">quick</span><span class="w"> </span><span class="py">fix</span><span class="w"> </span><span class="py">applied</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="err">*</span><span class="py">1</span><span class="err">.</span><span class="mf">.3</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">CodeActionProvider</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">async</span> <span class="nx">provideCodeActions</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">TextDocument</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">range</span>: <span class="kt">Range</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">context</span>: <span class="kt">CodeActionContext</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">CodeAction</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">actions</span>: <span class="kt">CodeAction</span><span class="p">[]</span> <span class="o">=</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">diagnostic</span> <span class="k">of</span> <span class="nx">context</span><span class="p">.</span><span class="nx">diagnostics</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">diagnostic</span><span class="p">.</span><span class="nx">code</span> <span class="o">===</span> <span class="s1">'unbounded-traversal'</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">actions</span><span class="p">.</span><span class="nx">push</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">'Add depth limit (1..3)'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">kind</span>: <span class="kt">CodeActionKind.QuickFix</span><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 class="nx">diagnostic</span><span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="nx">edit</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">changes</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="p">[</span><span class="nb">document</span><span class="p">.</span><span class="nx">uri</span><span class="p">]</span><span class="o">:</span> <span class="p">[{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">range</span>: <span class="kt">diagnostic.range</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">newText</span>: <span class="kt">this.addDepthLimit</span><span class="p">(</span><span class="nx">diagnostic</span><span class="p">.</span><span class="nx">range</span><span class="p">,</span> <span class="s1">'1..3'</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="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">diagnostic</span><span class="p">.</span><span class="nx">code</span> <span class="o">===</span> <span class="s1">'missing-limit'</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">actions</span><span class="p">.</span><span class="nx">push</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">'Add LIMIT clause'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">kind</span>: <span class="kt">CodeActionKind.QuickFix</span><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 class="nx">diagnostic</span><span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="nx">edit</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">changes</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="p">[</span><span class="nb">document</span><span class="p">.</span><span class="nx">uri</span><span class="p">]</span><span class="o">:</span> <span class="p">[{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">range</span>: <span class="kt">new</span> <span class="nx">Range</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">lineCount</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">document</span><span class="p">.</span><span class="nx">lineCount</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">newText</span><span class="o">:</span> <span class="s1">'\nLIMIT 100;'</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="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">actions</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="semantic-highlighting" class="position-relative d-flex align-items-center group">
<span>Semantic 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="semantic-highlighting"
aria-haspopup="dialog"
aria-label="Share link: Semantic 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>
</h4><p>Syntax highlighting based on semantic meaning:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_id</span><span class="p">})</span><span class="err">-</span><span class="p">[:</span><span class="nc">PURCHASED</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="nc">p</span><span class="p">:</span><span class="nc">Product</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">▲</span><span class="w"> </span><span class="err">▲</span><span class="w"> </span><span class="err">▲</span><span class="w"> </span><span class="err">▲</span><span class="w"> </span><span class="err">▲</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="err">│</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">variable</span><span class="w"> </span><span class="py">label</span><span class="w"> </span><span class="py">property</span><span class="w"> </span><span class="py">relationship</span><span class="w"> </span><span class="py">label</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">(</span><span class="py">blue</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="py">green</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="py">yellow</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="py">purple</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="py">green</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">price</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">100</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">▲</span><span class="w"> </span><span class="err">▲</span><span class="w"> </span><span class="err">▲</span><span class="w"> </span><span class="err">▲</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="err">│</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">variable</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="py">number</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">property</span><span class="w"> </span><span class="py">operator</span><span class="w"> </span><span class="p">(</span><span class="py">literal</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">name</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">user_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">▲</span><span class="w"> </span><span class="err">▲▲</span><span class="w"> </span><span class="err">▲</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="err">││</span><span class="w"> </span><span class="err">│</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">variable</span><span class="w"> </span><span class="err">││</span><span class="w"> </span><span class="py">alias</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">property</span><span class="w"> </span><span class="py">keyword</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="workspace-symbol-search" class="position-relative d-flex align-items-center group">
<span>Workspace Symbol Search</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="workspace-symbol-search"
aria-haspopup="dialog"
aria-label="Share link: Workspace Symbol Search">
<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>Find symbols across all GQL files:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Ctrl+T → "User"
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Results:
</span></span><span class="line"><span class="cl"> ┌────────────────────────────────────────┐
</span></span><span class="line"><span class="cl"> │ (:User) - queries/users.gql:1 │
</span></span><span class="line"><span class="cl"> │ (:User:Admin) - queries/admin.gql:15 │
</span></span><span class="line"><span class="cl"> │ user_events - streams/events.gql:42 │
</span></span><span class="line"><span class="cl"> └────────────────────────────────────────┘
</span></span></code></pre></div>
<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><a
href="https://microsoft.github.io/language-server-protocol/"
aria-label="LSP Specification – opens in new window"
target="_blank" rel="noopener noreferrer"
>LSP Specification
<span aria-hidden="true" class="external-icon">↗</span>
</a>
- Official LSP documentation</li>
<li><a
href="/docs/development/lsp-guide/"
>Geode LSP Guide</a>
- Installation and configuration</li>
<li><a
href="/docs/gql-reference/"
>GQL Language Reference</a>
- Complete GQL documentation</li>
<li><a
href="/docs/development/repl-advanced/"
>REPL Advanced Guide</a>
- Advanced REPL usage</li>
<li><a
href="https://code.visualstudio.com/api/language-extensions/language-server-extension-guide"
aria-label="Language Server Implementation Guide – opens in new window"
target="_blank" rel="noopener noreferrer"
>Language Server Implementation Guide
<span aria-hidden="true" class="external-icon">↗</span>
</a>
- VS Code LSP guide</li>
</ul>
Tag
4 articles
Tag: Language Server Protocol (LSP)
Explore Geode's LSP implementation for IDE integration providing syntax highlighting, auto-completion, error checking, and go-to-definition for GQL queries.