<!-- CANARY: REQ=REQ-DOCUMENTATION-STRUCTURE-001; FEATURE="DocStructure"; ASPECT=StructureTests; STATUS=TESTED; OWNER=claude; UPDATED=2026-01-16 -->
<h3 id="overview" class="position-relative d-flex align-items-center group">
<span>Overview</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="overview"
aria-haspopup="dialog"
aria-label="Share link: Overview">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden>
<div class="hsm-dialog" role="document">
<div class="hsm-header">
<h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2>
<button type="button" class="hsm-close" aria-label="Close">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<div class="hsm-body">
<label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label>
<div class="input-group mb-4 hsm-url-group">
<input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" />
<button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy">
<i class="fa-duotone fa-clipboard" aria-hidden="true"></i>
</button>
</div>
<div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div>
<div class="hsm-share-grid">
<a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-twitter me-2"></i>Twitter
</a>
<a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-linkedin me-2"></i>LinkedIn
</a>
<a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-facebook me-2"></i>Facebook
</a>
</div>
</div>
</div>
</div>
<style>
.heading-share-modal {
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.6);
z-index: 1050;
padding: 1rem;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
.heading-share-modal[hidden] { display: none !important; }
.hsm-dialog {
max-width: 420px;
width: 100%;
background: var(--bs-body-bg, #fff);
color: var(--bs-body-color, #212529);
border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
border-radius: 1rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
overflow: hidden;
animation: hsm-fade-in 0.2s ease-out;
}
@keyframes hsm-fade-in {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
[data-bs-theme="dark"] .hsm-dialog {
background: #1e293b;
border-color: rgba(255,255,255,0.1);
color: #f8f9fa;
}
.hsm-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
background: rgba(0,0,0,0.02);
}
[data-bs-theme="dark"] .hsm-header {
background: rgba(255,255,255,0.02);
border-color: rgba(255,255,255,0.1);
}
.hsm-close {
background: transparent;
border: none;
color: inherit;
opacity: 0.5;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
font-size: 1.2rem;
line-height: 1;
transition: opacity 0.2s;
}
.hsm-close:hover {
opacity: 1;
}
.hsm-body {
padding: 1.5rem;
}
.hsm-url-group {
display: flex !important;
align-items: stretch;
}
.hsm-url-group .form-control {
flex: 1;
min-width: 0;
margin: 0;
background: var(--bs-secondary-bg, #f8f9fa);
border-color: var(--bs-border-color, #dee2e6);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
height: 42px;
}
.hsm-url-group .btn {
flex: 0 0 auto;
margin: 0;
margin-left: -1px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 1.25rem;
z-index: 2;
}
[data-bs-theme="dark"] .hsm-url-group .form-control {
background: #0f172a;
border-color: #334155;
color: #e2e8f0;
}
.hsm-share-grid {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.hsm-share-grid .btn {
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
padding: 0.6rem;
border-color: var(--bs-border-color);
width: 100%;
}
[data-bs-theme="dark"] .hsm-share-grid .btn {
color: #e2e8f0;
border-color: #475569;
}
[data-bs-theme="dark"] .hsm-share-grid .btn:hover {
background: #334155;
border-color: #cbd5e1;
}
</style>
<script>
(function(){
const modal = document.getElementById('headingShareModal');
if(!modal) return;
const input = modal.querySelector('#headingShareInput');
const copyBtn = modal.querySelector('.hsm-copy');
const twitter = modal.querySelector('#share-twitter');
const linkedin = modal.querySelector('#share-linkedin');
const facebook = modal.querySelector('#share-facebook');
const closeBtn = modal.querySelector('.hsm-close');
let lastFocus=null;
let trapBound=false;
function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; }
function isOpen(){ return !modal.hasAttribute('hidden'); }
function hydrate(id){
const url=buildUrl(id);
input.value=url;
const enc=encodeURIComponent(url);
const text=encodeURIComponent(document.title);
if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`;
if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`;
if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`;
}
function openModal(id){
lastFocus=document.activeElement;
hydrate(id);
if(!isOpen()){
modal.removeAttribute('hidden');
}
requestAnimationFrame(()=>{ input.focus(); });
trapFocus();
}
function closeModal(){
if(!isOpen()) return;
modal.setAttribute('hidden','');
if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus();
}
function copyCurrent(){
try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); }
catch(e){ fallback(); }
}
function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} }
function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); }
function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); }
function bindShareButtons(){
document.querySelectorAll('.h-share').forEach(btn=>{
if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; }
});
}
bindShareButtons();
if(document.readyState==='loading'){
document.addEventListener('DOMContentLoaded', bindShareButtons);
} else {
requestAnimationFrame(bindShareButtons);
}
document.addEventListener('click', function(e){
const shareBtn=e.target.closest && e.target.closest('.h-share');
if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); }
}, true);
document.addEventListener('click', e=>{
if(e.target===modal) closeModal();
if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); }
if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); }
});
document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); });
function trapFocus(){
if(trapBound) return;
trapBound=true;
modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } });
}
if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); });
})();
</script><p>Geode provides a complete Language Server Protocol (LSP) implementation for GQL files, bringing professional IDE features to graph query development. The LSP server delivers real-time syntax checking, intelligent code completion, hover documentation, and more.</p>
<p><strong>Status</strong>: Production-ready (100% implemented and tested)</p>
<h4 id="what-youll-learn" class="position-relative d-flex align-items-center group">
<span>What You&rsquo;ll Learn</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="what-youll-learn"
aria-haspopup="dialog"
aria-label="Share link: What Youll Learn">
<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><ul>
<li>How to set up Geode LSP with your IDE</li>
<li>Available language features and capabilities</li>
<li>Integration guides for VS Code, Neovim, Vim, and Emacs</li>
<li>Troubleshooting common LSP issues</li>
<li>Advanced configuration options</li>
</ul>
<h4 id="prerequisites" class="position-relative d-flex align-items-center group">
<span>Prerequisites</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="prerequisites"
aria-haspopup="dialog"
aria-label="Share link: Prerequisites">
<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><ul>
<li>Geode installed (see <a
href="/guides/installation/"
>Installation Guide</a>
)</li>
<li>Basic familiarity with your IDE’s plugin/extension system</li>
<li>For VS Code: Node.js and npm</li>
<li>For Neovim: nvim-lspconfig plugin</li>
</ul>
<h3 id="starting-language-servers" class="position-relative d-flex align-items-center group">
<span>Starting Language Servers</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="starting-language-servers"
aria-haspopup="dialog"
aria-label="Share link: Starting Language Servers">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p>Geode provides two language server modes: LSP for IDE integration and MCP for AI assistant integration.</p>
<h4 id="lsp-server-language-server-protocol" class="position-relative d-flex align-items-center group">
<span>LSP Server (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="lsp-server-language-server-protocol"
aria-haspopup="dialog"
aria-label="Share link: LSP Server (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>
</h4><p>The LSP server provides IDE features like autocomplete, hover documentation, and diagnostics.</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"># Start the LSP server (communicates via stdin/stdout)</span>
</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 class="c1"># With verbose logging</span>
</span></span><span class="line"><span class="cl">geode lsp --verbose
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Specify log file for debugging</span>
</span></span><span class="line"><span class="cl">geode lsp --log-file<span class="o">=</span>/tmp/geode-lsp.log
</span></span></code></pre></div><p>The LSP server is typically launched automatically by your IDE, but you can test it manually:</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"># Test LSP initialization</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s1">'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"capabilities":{}}}'</span> <span class="p">|</span> geode lsp
</span></span></code></pre></div>
<h4 id="mcp-server-model-context-protocol" class="position-relative d-flex align-items-center group">
<span>MCP Server (Model Context 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="mcp-server-model-context-protocol"
aria-haspopup="dialog"
aria-label="Share link: MCP Server (Model Context 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>
</h4><p>The MCP server provides AI assistants (like Claude) with direct access to Geode.</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"># Start the MCP server</span>
</span></span><span class="line"><span class="cl">geode mcp serve
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Connect to a specific Geode instance</span>
</span></span><span class="line"><span class="cl">geode mcp serve --host localhost --port <span class="m">3141</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># With authentication</span>
</span></span><span class="line"><span class="cl">geode mcp serve --host localhost --port <span class="m">3141</span> --user admin --password secret
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># With verbose output</span>
</span></span><span class="line"><span class="cl">geode mcp serve --verbose
</span></span></code></pre></div><p><strong>MCP Server Configuration via environment variables:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Set connection details via environment</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_HOST</span><span class="o">=</span>localhost
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_PORT</span><span class="o">=</span><span class="m">3141</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_USER</span><span class="o">=</span>admin
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_PASSWORD</span><span class="o">=</span>secret
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">geode mcp serve
</span></span></code></pre></div>
<h4 id="running-both-servers" class="position-relative d-flex align-items-center group">
<span>Running Both Servers</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="running-both-servers"
aria-haspopup="dialog"
aria-label="Share link: Running Both Servers">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>For full development experience with both IDE support and AI assistance:</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"># Terminal 1: Start Geode database server</span>
</span></span><span class="line"><span class="cl">geode serve --listen 0.0.0.0:3141
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Terminal 2: Your IDE uses LSP (automatically started)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Configure your IDE to run: geode lsp</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Terminal 3: AI assistant uses MCP</span>
</span></span><span class="line"><span class="cl">geode mcp serve --host localhost --port <span class="m">3141</span>
</span></span></code></pre></div>
<h4 id="claude-code-integration" class="position-relative d-flex align-items-center group">
<span>Claude 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="claude-code-integration"
aria-haspopup="dialog"
aria-label="Share link: Claude 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><p>To use Geode with Claude Code:</p>
<ol>
<li><strong>Configure MCP in Claude settings:</strong></li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"mcpServers"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"geode"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"command"</span><span class="p">:</span> <span class="s2">"geode"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"args"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"mcp"</span><span class="p">,</span> <span class="s2">"serve"</span><span class="p">,</span> <span class="s2">"--host"</span><span class="p">,</span> <span class="s2">"localhost"</span><span class="p">,</span> <span class="s2">"--port"</span><span class="p">,</span> <span class="s2">"3141"</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><ol start="2">
<li><strong>Or use the Geode Claude plugin:</strong></li>
</ol>
<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 the plugin</span>
</span></span><span class="line"><span class="cl">claude plugins install geode-claude-plugin
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Or run with local plugin directory</span>
</span></span><span class="line"><span class="cl">claude --plugin-dir ./geode-claude-plugin
</span></span></code></pre></div><p>See the <a
href="/plugins/claude/"
>Claude Code Plugin</a>
documentation for more details.</p>
<h3 id="architecture" class="position-relative d-flex align-items-center group">
<span>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="architecture"
aria-haspopup="dialog"
aria-label="Share link: 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>
</h3>
<h4 id="components" class="position-relative d-flex align-items-center group">
<span>Components</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="components"
aria-haspopup="dialog"
aria-label="Share link: Components">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>The Geode LSP implementation consists of five main components:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">src/cli/lsp/
</span></span><span class="line"><span class="cl">├── protocol.zig # LSP protocol types and JSON-RPC structures
</span></span><span class="line"><span class="cl">├── transport.zig # stdio transport with Content-Length headers
</span></span><span class="line"><span class="cl">├── document.zig # Document state management
</span></span><span class="line"><span class="cl">├── features.zig # Language features (hover, completion, diagnostics)
</span></span><span class="line"><span class="cl">└── server.zig # Main LSP server implementation
</span></span></code></pre></div>
<h4 id="protocol-compliance" class="position-relative d-flex align-items-center group">
<span>Protocol Compliance</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="protocol-compliance"
aria-haspopup="dialog"
aria-label="Share link: Protocol Compliance">
<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><ul>
<li><strong>LSP Specification</strong>: 3.17</li>
<li><strong>Transport</strong>: JSON-RPC 2.0 over stdin/stdout</li>
<li><strong>Text Synchronization</strong>: Full and Incremental modes</li>
<li><strong>Parser Integration</strong>: Uses Geode’s ISO/IEC 39075:2024 compliance parser</li>
</ul>
<h4 id="server-capabilities" class="position-relative d-flex align-items-center group">
<span>Server 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="server-capabilities"
aria-haspopup="dialog"
aria-label="Share link: Server 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 LSP server advertises the following capabilities during initialization:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"capabilities"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"textDocumentSync"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"hoverProvider"</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">"completionProvider"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"triggerCharacters"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"."</span><span class="p">,</span> <span class="s2">":"</span><span class="p">,</span> <span class="s2">"$"</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"diagnosticProvider"</span><span class="p">:</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></code></pre></div>
<h3 id="language-features" class="position-relative d-flex align-items-center group">
<span>Language 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="language-features"
aria-haspopup="dialog"
aria-label="Share link: Language 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="1-diagnostics-syntax-errors" class="position-relative d-flex align-items-center group">
<span>1. Diagnostics (Syntax Errors)</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="1-diagnostics-syntax-errors"
aria-haspopup="dialog"
aria-label="Share link: 1. Diagnostics (Syntax Errors)">
<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 syntax error detection using Geode’s GQL parser:</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">Invalid</span><span class="w"> </span><span class="py">syntax</span><span class="w"> </span><span class="p">(</span><span class="py">missing</span><span class="w"> </span><span class="py">closing</span><span class="w"> </span><span class="py">parenthesis</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">n</span><span class="p">:</span><span class="nc">Person</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">n</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">Error</span><span class="p">:</span><span class="w"> </span><span class="nc">Expected</span><span class="w"> </span><span class="err">'</span><span class="p">)</span><span class="err">'</span><span class="w"> </span><span class="py">at</span><span class="w"> </span><span class="py">line</span><span class="w"> </span><span class="py">1</span><span class="p">,</span><span class="w"> </span><span class="py">column</span><span class="w"> </span><span class="py">16</span><span class="w">
</span></span></span></code></pre></div><p><strong>Features</strong>:</p>
<ul>
<li>Instant feedback as you type</li>
<li>Line and column precision</li>
<li>Clear error messages from the parser</li>
<li>Multiple error reporting</li>
</ul>
<h4 id="2-hover-documentation" class="position-relative d-flex align-items-center group">
<span>2. 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="2-hover-documentation"
aria-haspopup="dialog"
aria-label="Share link: 2. 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>Context-aware documentation for GQL keywords, functions, and types:</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="py">WHERE</span><span class="w"> </span><span class="py">n</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">25</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">distance</span><span class="p">(</span><span class="py">n</span><span class="err">.</span><span class="py">embedding</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">L2</span><span class="err">'</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="py">Hover</span><span class="w"> </span><span class="py">shows</span><span class="p">:</span><span class="w"> </span><span class="s">"distance(v1: VECTOR, v2: VECTOR) -> FLOAT"</span><span class="w">
</span></span></span></code></pre></div><p><strong>Supported Items</strong> (100+ documented):</p>
<ul>
<li><strong>Keywords</strong> (40+): MATCH, RETURN, WHERE, CREATE, DELETE, MERGE, etc.</li>
<li><strong>Functions</strong> (50+): count, sum, distance, similarity, timestamp, etc.</li>
<li><strong>Types</strong> (15+): INTEGER, FLOAT, VECTOR, UUID, DATETIME, etc.</li>
</ul>
<p><strong>Example Documentation</strong>:</p>
<p>Hovering over <code>distance</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">distance(v1: VECTOR, v2: VECTOR, metric: STRING) -> FLOAT
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Calculate distance between two vectors using the specified metric.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Supported metrics:
</span></span><span class="line"><span class="cl">- 'L2' or 'euclidean': Euclidean distance
</span></span><span class="line"><span class="cl">- 'cosine': Cosine distance
</span></span><span class="line"><span class="cl">- 'manhattan': Manhattan (L1) distance
</span></span><span class="line"><span class="cl">- 'dot': Dot product
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Example:
</span></span><span class="line"><span class="cl"> RETURN distance(n.embedding, $query, 'L2')
</span></span></code></pre></div>
<h4 id="3-code-completion" class="position-relative d-flex align-items-center group">
<span>3. Code 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="3-code-completion"
aria-haspopup="dialog"
aria-label="Share link: 3. Code 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>Intelligent auto-complete for GQL syntax:</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">MA</span><span class="err"><</span><span class="py">cursor</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="py">Suggests</span><span class="p">:</span><span class="w"> </span><span class="nc">MATCH</span><span class="p">,</span><span class="w"> </span><span class="py">MAX</span><span class="p">,</span><span class="w"> </span><span class="py">MANHATTAN</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">co</span><span class="err"><</span><span class="py">cursor</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="py">Suggests</span><span class="p">:</span><span class="w"> </span><span class="nc">count</span><span class="p">(),</span><span class="w"> </span><span class="py">coalesce</span><span class="p">(),</span><span class="w"> </span><span class="py">collect</span><span class="p">(),</span><span class="w"> </span><span class="py">cos</span><span class="p">(),</span><span class="w"> </span><span class="py">cosine</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">n</span><span class="err">.<</span><span class="py">cursor</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="py">Triggers</span><span class="w"> </span><span class="py">property</span><span class="w"> </span><span class="py">completion</span><span class="w"> </span><span class="p">(</span><span class="py">when</span><span class="w"> </span><span class="py">connected</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">server</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p><strong>Completion Types</strong>:</p>
<ul>
<li><strong>Keywords</strong>: All GQL keywords with proper context</li>
<li><strong>Functions</strong>: Function names with <code>()</code> insertion</li>
<li><strong>Types</strong>: Data type names</li>
<li><strong>Parameters</strong>: Variable names starting with <code>$</code></li>
</ul>
<p><strong>Trigger Characters</strong>:</p>
<ul>
<li><code>.</code> - Property access</li>
<li><code>:</code> - Label specification</li>
<li><code>$</code> - Parameter names</li>
</ul>
<h4 id="4-document-synchronization" class="position-relative d-flex align-items-center group">
<span>4. 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="4-document-synchronization"
aria-haspopup="dialog"
aria-label="Share link: 4. 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>The LSP server maintains document state using two synchronization modes:</p>
<p><strong>Full Synchronization</strong>:</p>
<ul>
<li>Server receives complete document text on every change</li>
<li>Simpler implementation, suitable for smaller files</li>
<li>Default mode</li>
</ul>
<p><strong>Incremental Synchronization</strong>:</p>
<ul>
<li>Server receives only changed text ranges</li>
<li>More efficient for large files</li>
<li>Supported but Full mode is default</li>
</ul>
<h3 id="ide-integration" class="position-relative d-flex align-items-center group">
<span>IDE 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="ide-integration"
aria-haspopup="dialog"
aria-label="Share link: IDE 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>
</h3>
<h4 id="visual-studio-code" class="position-relative d-flex align-items-center group">
<span>Visual Studio Code</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="visual-studio-code"
aria-haspopup="dialog"
aria-label="Share link: Visual Studio Code">
<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>
<h5 id="option-1-manual-configuration" class="position-relative d-flex align-items-center group">
<span>Option 1: Manual 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="option-1-manual-configuration"
aria-haspopup="dialog"
aria-label="Share link: Option 1: Manual 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>
</h5><p>Add to your <code>settings.json</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.server.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.server.path"</span><span class="p">:</span> <span class="s2">"/path/to/geode"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.server.args"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"lsp"</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 a file type association for <code>.gql</code> files:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"files.associations"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"*.gql"</span><span class="p">:</span> <span class="s2">"gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"*.gcypher"</span><span class="p">:</span> <span class="s2">"gql"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"*.cypher"</span><span class="p">:</span> <span class="s2">"gql"</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>
<h5 id="option-2-vs-code-extension" class="position-relative d-flex align-items-center group">
<span>Option 2: VS Code Extension</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="option-2-vs-code-extension"
aria-haspopup="dialog"
aria-label="Share link: Option 2: VS Code Extension">
<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>
</h5><p>A complete VS Code extension is available in the repository:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> editors/vscode
</span></span><span class="line"><span class="cl">npm install
</span></span><span class="line"><span class="cl">npm run compile
</span></span><span class="line"><span class="cl">npx vsce package
</span></span><span class="line"><span class="cl"><span class="c1"># Install the .vsix file in VS Code</span>
</span></span></code></pre></div><p><strong>Extension Features</strong>:</p>
<ul>
<li>TextMate grammar for syntax highlighting</li>
<li>Automatic LSP client configuration</li>
<li>Configurable server path and arguments</li>
<li>GQL language snippets</li>
<li>File icon themes</li>
</ul>
<p><strong>Extension Settings</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"geode.lspPath"</span><span class="p">:</span> <span class="s2">"/usr/local/bin/geode"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"geode.lspArgs"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"lsp"</span><span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"geode.trace.server"</span><span class="p">:</span> <span class="s2">"off"</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
<h4 id="neovim" class="position-relative d-flex align-items-center group">
<span>Neovim</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="neovim"
aria-haspopup="dialog"
aria-label="Share link: Neovim">
<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>
<h5 id="using-nvim-lspconfig" class="position-relative d-flex align-items-center group">
<span>Using nvim-lspconfig</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="using-nvim-lspconfig"
aria-haspopup="dialog"
aria-label="Share link: Using nvim-lspconfig">
<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>
</h5><p>Create <code>~/.config/nvim/lua/lsp/geode.lua</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="kd">local</span> <span class="n">lspconfig</span> <span class="o">=</span> <span class="n">require</span><span class="p">(</span><span class="s1">'lspconfig'</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="kd">local</span> <span class="n">configs</span> <span class="o">=</span> <span class="n">require</span><span class="p">(</span><span class="s1">'lspconfig.configs'</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">-- Define Geode LSP server</span>
</span></span><span class="line"><span class="cl"><span class="kr">if</span> <span class="ow">not</span> <span class="n">configs.geode</span> <span class="kr">then</span>
</span></span><span class="line"><span class="cl"> <span class="n">configs.geode</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">default_config</span> <span class="o">=</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">'/usr/local/bin/geode'</span><span class="p">,</span> <span class="s1">'lsp'</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">'gcypher'</span><span class="p">,</span> <span class="s1">'cypher'</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="kr">function</span><span class="p">(</span><span class="n">fname</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="kr">return</span> <span class="n">lspconfig.util</span><span class="p">.</span><span class="n">find_git_ancestor</span><span class="p">(</span><span class="n">fname</span><span class="p">)</span> <span class="ow">or</span> <span class="n">vim.fn</span><span class="p">.</span><span class="n">getcwd</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="kr">end</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="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="kr">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">-- Set up Geode LSP</span>
</span></span><span class="line"><span class="cl"><span class="n">lspconfig.geode</span><span class="p">.</span><span class="n">setup</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">on_attach</span> <span class="o">=</span> <span class="kr">function</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">bufnr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="c1">-- Key mappings</span>
</span></span><span class="line"><span class="cl"> <span class="kd">local</span> <span class="n">opts</span> <span class="o">=</span> <span class="p">{</span> <span class="n">noremap</span><span class="o">=</span><span class="kc">true</span><span class="p">,</span> <span class="n">silent</span><span class="o">=</span><span class="kc">true</span><span class="p">,</span> <span class="n">buffer</span><span class="o">=</span><span class="n">bufnr</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="n">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s1">'n'</span><span class="p">,</span> <span class="s1">'gd'</span><span class="p">,</span> <span class="n">vim.lsp</span><span class="p">.</span><span class="n">buf.definition</span><span class="p">,</span> <span class="n">opts</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s1">'n'</span><span class="p">,</span> <span class="s1">'K'</span><span class="p">,</span> <span class="n">vim.lsp</span><span class="p">.</span><span class="n">buf.hover</span><span class="p">,</span> <span class="n">opts</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s1">'n'</span><span class="p">,</span> <span class="s1">'gi'</span><span class="p">,</span> <span class="n">vim.lsp</span><span class="p">.</span><span class="n">buf.implementation</span><span class="p">,</span> <span class="n">opts</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s1">'n'</span><span class="p">,</span> <span class="s1">'<leader>rn'</span><span class="p">,</span> <span class="n">vim.lsp</span><span class="p">.</span><span class="n">buf.rename</span><span class="p">,</span> <span class="n">opts</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s1">'n'</span><span class="p">,</span> <span class="s1">'<leader>ca'</span><span class="p">,</span> <span class="n">vim.lsp</span><span class="p">.</span><span class="n">buf.code_action</span><span class="p">,</span> <span class="n">opts</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s1">'n'</span><span class="p">,</span> <span class="s1">'gr'</span><span class="p">,</span> <span class="n">vim.lsp</span><span class="p">.</span><span class="n">buf.references</span><span class="p">,</span> <span class="n">opts</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s1">'n'</span><span class="p">,</span> <span class="s1">'<leader>f'</span><span class="p">,</span> <span class="kr">function</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="n">vim.lsp</span><span class="p">.</span><span class="n">buf.format</span> <span class="p">{</span> <span class="n">async</span> <span class="o">=</span> <span class="kc">true</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="kr">end</span><span class="p">,</span> <span class="n">opts</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">-- Enable completion</span>
</span></span><span class="line"><span class="cl"> <span class="n">vim.api</span><span class="p">.</span><span class="n">nvim_buf_set_option</span><span class="p">(</span><span class="n">bufnr</span><span class="p">,</span> <span class="s1">'omnifunc'</span><span class="p">,</span> <span class="s1">'v:lua.vim.lsp.omnifunc'</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="kr">end</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">capabilities</span> <span class="o">=</span> <span class="n">require</span><span class="p">(</span><span class="s1">'cmp_nvim_lsp'</span><span class="p">).</span><span class="n">default_capabilities</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Add to <code>init.lua</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="n">require</span><span class="p">(</span><span class="s1">'lsp.geode'</span><span class="p">)</span>
</span></span></code></pre></div>
<h5 id="file-type-detection" class="position-relative d-flex align-items-center group">
<span>File Type Detection</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="file-type-detection"
aria-haspopup="dialog"
aria-label="Share link: File Type Detection">
<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>
</h5><p>Add to <code>~/.config/nvim/ftdetect/gql.vim</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-vim" data-lang="vim"><span class="line"><span class="cl"><span class="nx">au</span> <span class="nx">BufRead</span><span class="p">,</span><span class="nx">BufNewFile</span> *.<span class="nx">gql</span> <span class="nx">setfiletype</span> <span class="nx">gql</span>
</span></span><span class="line"><span class="cl"><span class="nx">au</span> <span class="nx">BufRead</span><span class="p">,</span><span class="nx">BufNewFile</span> *.<span class="nx">gcypher</span> <span class="nx">setfiletype</span> <span class="nx">gql</span>
</span></span><span class="line"><span class="cl"><span class="nx">au</span> <span class="nx">BufRead</span><span class="p">,</span><span class="nx">BufNewFile</span> *.<span class="nx">cypher</span> <span class="nx">setfiletype</span> <span class="nx">gql</span>
</span></span></code></pre></div>
<h4 id="vim" class="position-relative d-flex align-items-center group">
<span>Vim</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="vim"
aria-haspopup="dialog"
aria-label="Share link: Vim">
<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>Using vim-lsp plugin:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-vim" data-lang="vim"><span class="line"><span class="cl"><span class="k">if</span> <span class="nx">executable</span><span class="p">(</span><span class="s1">'geode'</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">au</span> <span class="nx">User</span> <span class="nx">lsp_setup</span> <span class="nx">call</span> <span class="nx">lsp</span>#<span class="nx">register_server</span><span class="p">(</span>{
</span></span><span class="line"><span class="cl"> \ <span class="s1">'name'</span>: <span class="s1">'geode-lsp'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> \ <span class="s1">'cmd'</span>: {<span class="nx">server_info</span><span class="p">-></span>[<span class="s1">'geode'</span><span class="p">,</span> <span class="s1">'lsp'</span>]}<span class="p">,</span>
</span></span><span class="line"><span class="cl"> \ <span class="s1">'allowlist'</span>: [<span class="s1">'gql'</span>]<span class="p">,</span>
</span></span><span class="line"><span class="cl"> \ }<span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">endif</span>
</span></span><span class="line"><span class="cl"><span class="c">
</span></span></span><span class="line"><span class="cl"><span class="c">" Key mappings</span>
</span></span><span class="line"><span class="cl"><span class="k">function</span><span class="p">!</span> <span class="nx">s</span>:<span class="nx">on_lsp_buffer_enabled</span><span class="p">()</span> <span class="nx">abort</span>
</span></span><span class="line"><span class="cl"> <span class="nx">setlocal</span> <span class="nx">omnifunc</span><span class="p">=</span><span class="nx">lsp</span>#<span class="nx">complete</span>
</span></span><span class="line"><span class="cl"> <span class="nx">setlocal</span> <span class="nx">signcolumn</span><span class="p">=</span><span class="nx">yes</span>
</span></span><span class="line"><span class="cl"> <span class="nx">nmap</span> <span class="p"><</span><span class="nx">buffer</span><span class="p">></span> <span class="nx">gd</span> <span class="p"><</span><span class="nx">plug</span><span class="p">>(</span><span class="nx">lsp</span><span class="p">-</span><span class="nx">definition</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">nmap</span> <span class="p"><</span><span class="nx">buffer</span><span class="p">></span> <span class="nx">K</span> <span class="p"><</span><span class="nx">plug</span><span class="p">>(</span><span class="nx">lsp</span><span class="p">-</span><span class="nx">hover</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">nmap</span> <span class="p"><</span><span class="nx">buffer</span><span class="p">></span> <span class="p"><</span><span class="nx">leader</span><span class="p">></span><span class="nx">rn</span> <span class="p"><</span><span class="nx">plug</span><span class="p">>(</span><span class="nx">lsp</span><span class="p">-</span><span class="nx">rename</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">nmap</span> <span class="p"><</span><span class="nx">buffer</span><span class="p">></span> [<span class="nx">g</span> <span class="p"><</span><span class="nx">plug</span><span class="p">>(</span><span class="nx">lsp</span><span class="p">-</span><span class="nx">previous</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">nmap</span> <span class="p"><</span><span class="nx">buffer</span><span class="p">></span> ]<span class="nx">g</span> <span class="p"><</span><span class="nx">plug</span><span class="p">>(</span><span class="nx">lsp</span><span class="p">-</span><span class="nx">next</span><span class="p">-</span><span class="nx">diagnostic</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">endfunction</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">augroup</span> <span class="nx">lsp_install</span>
</span></span><span class="line"><span class="cl"> <span class="nx">au</span><span class="p">!</span>
</span></span><span class="line"><span class="cl"> <span class="k">autocmd</span> <span class="nx">User</span> <span class="nx">lsp_buffer_enabled</span> <span class="nx">call</span> <span class="nx">s</span>:<span class="nx">on_lsp_buffer_enabled</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="nx">augroup</span> <span class="nx">END</span>
</span></span></code></pre></div>
<h4 id="emacs" class="position-relative d-flex align-items-center group">
<span>Emacs</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"
aria-haspopup="dialog"
aria-label="Share link: Emacs">
<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>Using lsp-mode:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-elisp" data-lang="elisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nv">add-to-list</span> <span class="ss">'lsp-language-id-configuration</span> <span class="o">'</span><span class="p">(</span><span class="nv">gql-mode</span> <span class="o">.</span> <span class="s">"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="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="o">'</span><span class="p">(</span><span class="s">"geode"</span> <span class="s">"lsp"</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-lsp</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">;; Define gql-mode (simple)</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">define-derived-mode</span> <span class="nv">gql-mode</span> <span class="nv">fundamental-mode</span> <span class="s">"GQL"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"Major mode for GQL graph query language."</span>
</span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nb">setq-local</span> <span class="nv">comment-start</span> <span class="s">"//"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nb">setq-local</span> <span class="nv">comment-end</span> <span class="s">""</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">;; Associate file extensions</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">add-to-list</span> <span class="ss">'auto-mode-alist</span> <span class="o">'</span><span class="p">(</span><span class="s">"\\.gql\\'"</span> <span class="o">.</span> <span class="nv">gql-mode</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">add-to-list</span> <span class="ss">'auto-mode-alist</span> <span class="o">'</span><span class="p">(</span><span class="s">"\\.gcypher\\'"</span> <span class="o">.</span> <span class="nv">gql-mode</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">add-to-list</span> <span class="ss">'auto-mode-alist</span> <span class="o">'</span><span class="p">(</span><span class="s">"\\.cypher\\'"</span> <span class="o">.</span> <span class="nv">gql-mode</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">;; Start LSP in gql-mode</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">add-hook</span> <span class="ss">'gql-mode-hook</span> <span class="nf">#'</span><span class="nv">lsp</span><span class="p">)</span>
</span></span></code></pre></div>
<h3 id="starting-the-lsp-server" class="position-relative d-flex align-items-center group">
<span>Starting the LSP Server</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="starting-the-lsp-server"
aria-haspopup="dialog"
aria-label="Share link: Starting the LSP Server">
<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="command-line-usage" class="position-relative d-flex align-items-center group">
<span>Command-Line 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="command-line-usage"
aria-haspopup="dialog"
aria-label="Share link: Command-Line 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><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Start the LSP server (communicates via stdin/stdout)</span>
</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 class="c1"># With verbose logging (to stderr)</span>
</span></span><span class="line"><span class="cl"><span class="nv">GEODE_LSP_DEBUG</span><span class="o">=</span><span class="m">1</span> geode lsp 2> /tmp/geode-lsp.log
</span></span></code></pre></div>
<h4 id="help-information" class="position-relative d-flex align-items-center group">
<span>Help Information</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="help-information"
aria-haspopup="dialog"
aria-label="Share link: Help Information">
<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-bash" data-lang="bash"><span class="line"><span class="cl">geode lsp --help
</span></span></code></pre></div><p>Output:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">geode lsp - Language Server Protocol server for GQL/Geode
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Usage: geode lsp [options]
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Description:
</span></span><span class="line"><span class="cl"> Starts a Language Server Protocol (LSP) server for GQL files.
</span></span><span class="line"><span class="cl"> The server communicates via JSON-RPC over stdin/stdout and provides:
</span></span><span class="line"><span class="cl"> - Syntax error diagnostics
</span></span><span class="line"><span class="cl"> - Hover documentation for GQL keywords, functions, and types
</span></span><span class="line"><span class="cl"> - Code completion for GQL syntax
</span></span><span class="line"><span class="cl"> - Document formatting
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Options:
</span></span><span class="line"><span class="cl"> -h, --help Show this help message
</span></span></code></pre></div>
<h4 id="environment-variables" class="position-relative d-flex align-items-center group">
<span>Environment Variables</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="environment-variables"
aria-haspopup="dialog"
aria-label="Share link: Environment Variables">
<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-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Enable debug logging</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_LSP_DEBUG</span><span class="o">=</span><span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Set log file</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_LSP_LOG</span><span class="o">=</span>/tmp/geode-lsp.log
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Set log level (debug, info, warn, error)</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_LSP_LOG_LEVEL</span><span class="o">=</span>debug
</span></span></code></pre></div>
<h3 id="testing-the-lsp-server" class="position-relative d-flex align-items-center group">
<span>Testing the LSP Server</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="testing-the-lsp-server"
aria-haspopup="dialog"
aria-label="Share link: Testing the LSP Server">
<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="manual-testing" class="position-relative d-flex align-items-center group">
<span>Manual Testing</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="manual-testing"
aria-haspopup="dialog"
aria-label="Share link: Manual Testing">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Create a test file <code>test.gql</code>:</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">Sample</span><span class="w"> </span><span class="py">GQL</span><span class="w"> </span><span class="kd">query</span><span class="w"> </span><span class="nc">for</span><span class="w"> </span><span class="py">testing</span><span class="w"> </span><span class="py">LSP</span><span class="w"> </span><span class="py">features</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="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="py">25</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="p">,</span><span class="w"> </span><span class="py">distance</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">embedding</span><span class="p">,</span><span class="w"> </span><span class="py">f</span><span class="err">.</span><span class="py">embedding</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">L2</span><span class="err">'</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">similarity</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">similarity</span><span class="w"> </span><span class="py">ASC</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><p>Start the server manually:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">geode lsp
</span></span></code></pre></div><p>Send an initialize request (JSON-RPC):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="err">Content-Length:</span> <span class="mi">250</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"jsonrpc"</span><span class="p">:</span> <span class="s2">"2.0"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"id"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"method"</span><span class="p">:</span> <span class="s2">"initialize"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"params"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"processId"</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"rootUri"</span><span class="p">:</span> <span class="s2">"file:///path/to/workspace"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"capabilities"</span><span class="p">:</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The server responds with its capabilities:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"jsonrpc"</span><span class="p">:</span> <span class="s2">"2.0"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"id"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"result"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"capabilities"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"textDocumentSync"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"hoverProvider"</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">"completionProvider"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"triggerCharacters"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"."</span><span class="p">,</span> <span class="s2">":"</span><span class="p">,</span> <span class="s2">"$"</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></code></pre></div>
<h4 id="automated-testing" class="position-relative d-flex align-items-center group">
<span>Automated Testing</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="automated-testing"
aria-haspopup="dialog"
aria-label="Share link: Automated Testing">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>The LSP implementation includes 79 comprehensive tests:</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"># Run all LSP tests</span>
</span></span><span class="line"><span class="cl">zig <span class="nb">test</span> src/cli/lsp/test_runner.zig
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Run specific test files</span>
</span></span><span class="line"><span class="cl">zig <span class="nb">test</span> src/cli/lsp/protocol_test.zig <span class="c1"># 23 tests</span>
</span></span><span class="line"><span class="cl">zig <span class="nb">test</span> src/cli/lsp/document_test.zig <span class="c1"># 28 tests</span>
</span></span><span class="line"><span class="cl">zig <span class="nb">test</span> src/cli/lsp/features_test.zig <span class="c1"># 24 tests</span>
</span></span><span class="line"><span class="cl">zig <span class="nb">test</span> src/cli/lsp/server_test.zig <span class="c1"># 4 tests</span>
</span></span><span class="line"><span class="cl">zig <span class="nb">test</span> src/cli/lsp/e2e_test.zig <span class="c1"># 13 tests</span>
</span></span></code></pre></div><p><strong>Test Coverage</strong>:</p>
<ul>
<li>Protocol structures and JSON-RPC (100%)</li>
<li>Document management and navigation (100%)</li>
<li>Language features (diagnostics, hover, completion) (100%)</li>
<li>Server lifecycle and state management (100%)</li>
<li>End-to-end workflows (100%)</li>
</ul>
<h3 id="performance" class="position-relative d-flex align-items-center group">
<span>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="performance"
aria-haspopup="dialog"
aria-label="Share link: 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>
</h3>
<h4 id="benchmarks" class="position-relative d-flex align-items-center group">
<span>Benchmarks</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="benchmarks"
aria-haspopup="dialog"
aria-label="Share link: Benchmarks">
<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>Syntax Highlighting</strong>:</p>
<ul>
<li>Small query (< 100 chars): < 1µs</li>
<li>Medium query (< 1000 chars): < 10µs</li>
<li>Large query (< 10000 chars): < 100µs</li>
</ul>
<p><strong>Diagnostics (Parser)</strong>:</p>
<ul>
<li>Small file (< 100 lines): < 5ms</li>
<li>Medium file (< 1000 lines): < 50ms</li>
<li>Large file (< 10000 lines): < 500ms</li>
</ul>
<p><strong>Hover and Completion</strong>:</p>
<ul>
<li>Response time: < 1ms (cached documentation)</li>
<li>First request: < 10ms (documentation loading)</li>
</ul>
<p><strong>Memory Usage</strong>:</p>
<ul>
<li>Base server: ~12MB</li>
<li>Per document: ~1KB + document size</li>
<li>Efficient document storage with hash map lookups</li>
</ul>
<h3 id="advanced-configuration" class="position-relative d-flex align-items-center group">
<span>Advanced 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="advanced-configuration"
aria-haspopup="dialog"
aria-label="Share link: Advanced 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>
</h3>
<h4 id="custom-trigger-characters" class="position-relative d-flex align-items-center group">
<span>Custom Trigger Characters</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="custom-trigger-characters"
aria-haspopup="dialog"
aria-label="Share link: Custom Trigger Characters">
<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>Configure additional completion triggers in your IDE:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"completionProvider"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"triggerCharacters"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"."</span><span class="p">,</span> <span class="s2">":"</span><span class="p">,</span> <span class="s2">"$"</span><span class="p">,</span> <span class="s2">"("</span><span class="p">,</span> <span class="s2">"["</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="document-formatting" class="position-relative d-flex align-items-center group">
<span>Document 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="document-formatting"
aria-haspopup="dialog"
aria-label="Share link: Document 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>The LSP server supports basic document formatting:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"method"</span><span class="p">:</span> <span class="s2">"textDocument/formatting"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"params"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"textDocument"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"uri"</span><span class="p">:</span> <span class="s2">"file:///path/to/file.gql"</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"options"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"tabSize"</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"insertSpaces"</span><span class="p">:</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></code></pre></div>
<h4 id="workspace-configuration" class="position-relative d-flex align-items-center group">
<span>Workspace 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="workspace-configuration"
aria-haspopup="dialog"
aria-label="Share link: Workspace 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><p>For multi-file projects, configure the workspace root:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="c1">-- Neovim: Custom root directory detection</span>
</span></span><span class="line"><span class="cl"><span class="n">root_dir</span> <span class="o">=</span> <span class="kr">function</span><span class="p">(</span><span class="n">fname</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="kr">return</span> <span class="n">lspconfig.util</span><span class="p">.</span><span class="n">root_pattern</span><span class="p">(</span><span class="s1">'.git'</span><span class="p">,</span> <span class="s1">'geode.yaml'</span><span class="p">)(</span><span class="n">fname</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="ow">or</span> <span class="n">lspconfig.util</span><span class="p">.</span><span class="n">find_git_ancestor</span><span class="p">(</span><span class="n">fname</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="ow">or</span> <span class="n">vim.fn</span><span class="p">.</span><span class="n">getcwd</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="kr">end</span>
</span></span></code></pre></div>
<h4 id="server-logging" class="position-relative d-flex align-items-center group">
<span>Server Logging</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="server-logging"
aria-haspopup="dialog"
aria-label="Share link: Server Logging">
<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>Enable detailed logging for debugging:</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"># Redirect stderr to log file</span>
</span></span><span class="line"><span class="cl">geode lsp 2> /tmp/geode-lsp.log
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Or in IDE configuration</span>
</span></span><span class="line"><span class="cl"><span class="o">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"gql.trace.server"</span>: <span class="s2">"verbose"</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div>
<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="server-not-starting" class="position-relative d-flex align-items-center group">
<span>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="server-not-starting"
aria-haspopup="dialog"
aria-label="Share link: 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>: IDE shows “LSP server failed to start”</p>
<p><strong>Solutions</strong>:</p>
<ol>
<li>
<p>Verify Geode is installed:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">which geode
</span></span><span class="line"><span class="cl">geode --version
</span></span></code></pre></div></li>
<li>
<p>Test server manually:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">geode lsp --help
</span></span></code></pre></div></li>
<li>
<p>Check permissions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ls -la <span class="k">$(</span>which geode<span class="k">)</span>
</span></span></code></pre></div></li>
<li>
<p>Review IDE logs for error messages</p>
</li>
</ol>
<h4 id="no-completions-or-hover" class="position-relative d-flex align-items-center group">
<span>No Completions or Hover</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-completions-or-hover"
aria-haspopup="dialog"
aria-label="Share link: No Completions or Hover">
<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>: Code completion or hover not working</p>
<p><strong>Solutions</strong>:</p>
<ol>
<li>
<p>Verify file extension is recognized:</p>
<ul>
<li>Use <code>.gql</code>, <code>.gcypher</code>, or <code>.cypher</code></li>
</ul>
</li>
<li>
<p>Check LSP client is attached:</p>
<ul>
<li>Neovim: <code>:LspInfo</code></li>
<li>VS Code: Check LSP output panel</li>
</ul>
</li>
<li>
<p>Verify server capabilities:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="c1">-- Neovim: Print capabilities</span>
</span></span><span class="line"><span class="cl"><span class="p">:</span><span class="n">lua</span> <span class="n">print</span><span class="p">(</span><span class="n">vim.inspect</span><span class="p">(</span><span class="n">vim.lsp</span><span class="p">.</span><span class="n">get_active_clients</span><span class="p">()[</span><span class="mi">1</span><span class="p">].</span><span class="n">server_capabilities</span><span class="p">))</span>
</span></span></code></pre></div></li>
<li>
<p>Restart LSP client:</p>
<ul>
<li>Neovim: <code>:LspRestart</code></li>
<li>VS Code: Reload window</li>
</ul>
</li>
</ol>
<h4 id="diagnostics-not-updating" class="position-relative d-flex align-items-center group">
<span>Diagnostics Not Updating</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="diagnostics-not-updating"
aria-haspopup="dialog"
aria-label="Share link: Diagnostics Not Updating">
<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>: Syntax errors not showing or outdated</p>
<p><strong>Solutions</strong>:</p>
<ol>
<li>
<p>Verify text synchronization mode:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"textDocumentSync"</span><span class="p">:</span> <span class="mi">1</span> <span class="c1">// Full sync mode
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span></code></pre></div></li>
<li>
<p>Check document version numbers are incrementing</p>
</li>
<li>
<p>Force document refresh:</p>
<ul>
<li>Save file (triggers didSave)</li>
<li>Close and reopen file</li>
</ul>
</li>
<li>
<p>Review LSP server logs for errors</p>
</li>
</ol>
<h4 id="high-cpu-usage" class="position-relative d-flex align-items-center group">
<span>High CPU 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="high-cpu-usage"
aria-haspopup="dialog"
aria-label="Share link: High CPU 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><strong>Symptom</strong>: LSP server consuming excessive CPU</p>
<p><strong>Solutions</strong>:</p>
<ol>
<li>
<p>Check for very large files (> 10,000 lines)</p>
<ul>
<li>Parser may be slow on large inputs</li>
</ul>
</li>
<li>
<p>Disable unnecessary features:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"gql.diagnostics.enable"</span><span class="p">:</span> <span class="kc">false</span> <span class="c1">// Disable real-time checking
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span></code></pre></div></li>
<li>
<p>Increase debounce time in IDE:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"editor.quickSuggestionsDelay"</span><span class="p">:</span> <span class="mi">500</span> <span class="c1">// VS Code
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span></code></pre></div></li>
</ol>
<h4 id="memory-leaks" class="position-relative d-flex align-items-center group">
<span>Memory Leaks</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-leaks"
aria-haspopup="dialog"
aria-label="Share link: Memory Leaks">
<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>: LSP server memory usage growing over time</p>
<p><strong>Solutions</strong>:</p>
<ol>
<li>
<p>Restart LSP server periodically</p>
<ul>
<li>Neovim: <code>:LspRestart</code></li>
</ul>
</li>
<li>
<p>Close unused documents:</p>
<ul>
<li>Server maintains state for all open files</li>
</ul>
</li>
<li>
<p>Report issue with reproduction steps</p>
</li>
</ol>
<h3 id="future-enhancements" class="position-relative d-flex align-items-center group">
<span>Future Enhancements</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="future-enhancements"
aria-haspopup="dialog"
aria-label="Share link: Future Enhancements">
<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="planned-features" class="position-relative d-flex align-items-center group">
<span>Planned 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="planned-features"
aria-haspopup="dialog"
aria-label="Share link: Planned 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><strong>Short-term</strong>:</p>
<ol>
<li>Document formatting (pretty-print GQL)</li>
<li>Go-to-definition for variables</li>
<li>Symbol outline (document structure)</li>
<li>Find references</li>
</ol>
<p><strong>Long-term</strong>:</p>
<ol>
<li>Semantic highlighting (textDocument/semanticTokens)</li>
<li>Code actions (quick fixes, refactorings)</li>
<li>Signature help for functions</li>
<li>Inlay hints for types</li>
<li>Call hierarchy</li>
<li>Type hierarchy</li>
<li>Rename refactoring</li>
<li>Workspace symbols</li>
</ol>
<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="file-organization" class="position-relative d-flex align-items-center group">
<span>File Organization</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="file-organization"
aria-haspopup="dialog"
aria-label="Share link: File Organization">
<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>Organize GQL files for optimal LSP experience:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">project/
</span></span><span class="line"><span class="cl">├── queries/
</span></span><span class="line"><span class="cl">│ ├── users.gql
</span></span><span class="line"><span class="cl">│ ├── products.gql
</span></span><span class="line"><span class="cl">│ └── analytics.gql
</span></span><span class="line"><span class="cl">├── schemas/
</span></span><span class="line"><span class="cl">│ └── graph_schema.gql
</span></span><span class="line"><span class="cl">└── .git/
</span></span></code></pre></div>
<h4 id="query-style" class="position-relative d-flex align-items-center group">
<span>Query Style</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-style"
aria-haspopup="dialog"
aria-label="Share link: Query Style">
<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>Write clear, well-formatted 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">Good</span><span class="p">:</span><span class="w"> </span><span class="nc">Clear</span><span class="w"> </span><span class="py">structure</span><span class="p">,</span><span class="w"> </span><span class="py">proper</span><span class="w"> </span><span class="py">indentation</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">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="py">WHERE</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">country</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="py">US</span><span class="err">'</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">p</span><span class="err">.</span><span class="py">category</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="py">Electronics</span><span class="err">'</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">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">price</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">price</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><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">Avoid</span><span class="p">:</span><span class="w"> </span><span class="nc">Single</span><span class="err">-</span><span class="py">line</span><span class="p">,</span><span class="w"> </span><span class="py">hard</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">read</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">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 class="py">WHERE</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">country</span><span class="p">=</span><span class="err">'</span><span class="py">US</span><span class="err">'</span><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">category</span><span class="p">=</span><span class="err">'</span><span class="py">Electronics</span><span class="err">'</span><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="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="py">p</span><span class="err">.</span><span class="py">price</span><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">price</span><span class="w"> </span><span class="py">DESC</span><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="leveraging-hover" class="position-relative d-flex align-items-center group">
<span>Leveraging Hover</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="leveraging-hover"
aria-haspopup="dialog"
aria-label="Share link: Leveraging Hover">
<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>Use hover documentation to learn GQL:</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">Hover</span><span class="w"> </span><span class="py">over</span><span class="w"> </span><span class="py">each</span><span class="w"> </span><span class="py">keyword</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">see</span><span class="w"> </span><span class="py">documentation</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">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="py">WHERE</span><span class="w"> </span><span class="py">n</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">25</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">count</span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">total</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="completion-workflow" class="position-relative d-flex align-items-center group">
<span>Completion Workflow</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-workflow"
aria-haspopup="dialog"
aria-label="Share link: Completion Workflow">
<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>Efficient use of code completion:</p>
<ol>
<li>Type keyword prefix: <code>MAT</code> → <code>MATCH</code></li>
<li>Use trigger characters: <code>n.</code> → property suggestions</li>
<li>Function completion: <code>cou</code> → <code>count()</code></li>
<li>Parameter names: <code>$</code> → parameter suggestions</li>
</ol>
<h3 id="integration-examples" class="position-relative d-flex align-items-center group">
<span>Integration Examples</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="integration-examples"
aria-haspopup="dialog"
aria-label="Share link: Integration Examples">
<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--gql-workflow" class="position-relative d-flex align-items-center group">
<span>VS Code + GQL Workflow</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--gql-workflow"
aria-haspopup="dialog"
aria-label="Share link: VS Code &#43; GQL Workflow">
<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="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"files.associations"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"*.gql"</span><span class="p">:</span> <span class="s2">"gql"</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"editor.formatOnSave"</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">"editor.codeActionsOnSave"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"source.fixAll"</span><span class="p">:</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="nt">"gql.server.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.server.path"</span><span class="p">:</span> <span class="s2">"/usr/local/bin/geode"</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">"off"</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
<h4 id="neovim--treesitter--lsp" class="position-relative d-flex align-items-center group">
<span>Neovim + Treesitter + LSP</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="neovim--treesitter--lsp"
aria-haspopup="dialog"
aria-label="Share link: Neovim &#43; Treesitter &#43; LSP">
<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">-- Complete setup with syntax highlighting and LSP</span>
</span></span><span class="line"><span class="cl"><span class="n">require</span><span class="p">(</span><span class="s1">'nvim-treesitter.configs'</span><span class="p">).</span><span class="n">setup</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">ensure_installed</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"gql"</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="n">highlight</span> <span class="o">=</span> <span class="p">{</span> <span class="n">enable</span> <span class="o">=</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></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.setup</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">on_attach</span> <span class="o">=</span> <span class="n">on_attach</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">capabilities</span> <span class="o">=</span> <span class="n">capabilities</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
<h4 id="vim--ale-alternative" class="position-relative d-flex align-items-center group">
<span>Vim + ALE (Alternative)</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="vim--ale-alternative"
aria-haspopup="dialog"
aria-label="Share link: Vim &#43; ALE (Alternative)">
<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-vim" data-lang="vim"><span class="line"><span class="cl"><span class="k">let</span> <span class="nx">g</span>:<span class="nx">ale_linters</span> <span class="p">=</span> {
</span></span><span class="line"><span class="cl">\ <span class="s1">'gql'</span>: [<span class="s1">'geode-lsp'</span>]<span class="p">,</span>
</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 class="k">let</span> <span class="nx">g</span>:<span class="nx">ale_fixers</span> <span class="p">=</span> {
</span></span><span class="line"><span class="cl">\ <span class="s1">'gql'</span>: [<span class="s1">'geode-format'</span>]<span class="p">,</span>
</span></span><span class="line"><span class="cl">\}
</span></span></code></pre></div>
<h3 id="editor-plugins" class="position-relative d-flex align-items-center group">
<span>Editor Plugins</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-plugins"
aria-haspopup="dialog"
aria-label="Share link: Editor Plugins">
<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="available-plugins" class="position-relative d-flex align-items-center group">
<span>Available Plugins</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="available-plugins"
aria-haspopup="dialog"
aria-label="Share link: Available Plugins">
<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>Complete editor integration packages are available:</p>
<p><strong>Claude Code Plugin</strong> (<code>geode-claude-plugin/</code>):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">claude /plugin install /path/to/geode-claude-plugin
</span></span></code></pre></div><p>Features:</p>
<ul>
<li>Automatic LSP integration for Claude Code</li>
<li>MCP tools for direct Geode access</li>
<li>File extension mapping for .gql, .gcypher, .cypher, .pgql</li>
<li>Auto-installation hooks</li>
</ul>
<p><strong>VS Code Extension</strong> (<code>editors/vscode/</code>):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> editors/vscode
</span></span><span class="line"><span class="cl">npm install <span class="o">&&</span> npm run compile
</span></span><span class="line"><span class="cl">npx vsce package
</span></span></code></pre></div><p>Features:</p>
<ul>
<li>Full syntax highlighting with TextMate grammar</li>
<li>LSP integration via vscode-languageclient</li>
<li>Configurable settings</li>
</ul>
<p><strong>Neovim Configuration</strong> (<code>editors/neovim/</code>):</p>
<ul>
<li><code>gql.lua</code> - nvim-lspconfig setup with key mappings</li>
<li><code>gql.vim</code> - Vim-style syntax highlighting</li>
</ul>
<p>See <code>editors/README.md</code> for complete setup instructions.</p>
<h3 id="next-steps" class="position-relative d-flex align-items-center group">
<span>Next Steps</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="next-steps"
aria-haspopup="dialog"
aria-label="Share link: Next Steps">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p><strong>Explore More</strong>:</p>
<ul>
<li><a
href="/docs/development/repl-advanced/"
>REPL Advanced Features</a>
- Interactive shell</li>
<li><a
href="/docs/guides/testing-strategies/"
>Testing Strategies</a>
- Test your queries</li>
<li><a
href="/docs/query/performance-tuning/"
>Query Performance Tuning</a>
- Optimize queries</li>
</ul>
<p><strong>Related Topics</strong>:</p>
<ul>
<li><a
href="/docs/gql/guide/"
>GQL Guide</a>
- Learn GQL syntax</li>
<li><a
href="/docs/reference/api-reference-complete/"
>API Reference</a>
- Complete function list</li>
<li><a
href="/docs/guides/schema-design/"
>Schema Design</a>
- Graph modeling</li>
</ul>
<p><strong>Community</strong>:</p>
<ul>
<li>Report LSP issues on <a
href="https://gitlab.com/devnw/codepros/geode"
aria-label="GitLab – opens in new window"
target="_blank" rel="noopener noreferrer"
>GitLab
<span aria-hidden="true" class="external-icon">↗</span>
</a>
</li>
<li>Request features in discussions</li>
<li>Contribute editor plugins</li>
</ul>
<hr>
<p><strong>Implementation</strong>: Complete (79/79 tests passing)
<strong>Protocol</strong>: LSP 3.17, JSON-RPC 2.0
<strong>Parser</strong>: ISO/IEC 39075:2024 compliance
<strong>Status</strong>: Production-ready</p>
GQL Language Server Protocol Implementation Guide
Complete guide to Geode's GQL Language Server Protocol (LSP) implementation, providing IDE integration, autocomplete, syntax highlighting, and real-time diagnostics.