<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet href="/static/feed.xsl" type="text/xsl" ?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:quartz="https://quartz.jzhao.xyz/ns">
  <script xmlns="http://www.w3.org/1999/xhtml" src="/static/scripts/xslt-polyfill-214fd525.js"></script>
  <title>/wiki / lsp</title>
  <subtitle>Recent notes in /wiki / lsp on Animesh Mishra</subtitle>
  <link href="https://animishraa05.github.io/wiki/lsp" />
  <link rel="alternate" type="text/html" href="https://animishraa05.github.io/wiki/lsp" />
  <category term="wiki/lsp" />
  <id>https://animishraa05.github.io/wiki/lsp</id>
  <updated>2026-09-02T00:00:00.000Z</updated>
  <contributor>
    <name>Animesh Mishra</name>
    <email>animesh.mishra818@gmail.com</email>
  </contributor>
  <logo>https://animishraa05.github.io/icon.png</logo>
  <icon>https://animishraa05.github.io/icon.png</icon>
  <generator>Quartz v4.6.0 -- quartz.jzhao.xyz</generator>
  <rights type="html">&amp;amp;copy; 2026 Animesh Mishra</rights>
  
  <entry>
    <title>Lsp — Map of Content</title>
    <link href="https://animishraa05.github.io/wiki/lsp/lsp-moc" />
    <link rel="alternate" type="text/markdown" href="https://animishraa05.github.io/wiki/lsp/lsp-moc.md" />
    <summary> Map of Content for Lsp — 7 concepts. Start here to navigate lsp.</summary>
    <published>2026-09-02T00:00:00.000Z</published>
    <updated>2026-09-02T00:00:00.000Z</updated>
    <publishedTime>Sep 02, 2026</publishedTime>
    <updatedTime>Sep 02, 2026</updatedTime>
    <category term="meta" label="meta" />
<category term="lsp" label="lsp" />
    <author>
      <name>Animesh Mishra</name>
      <email>animesh.mishra818@gmail.com</email>
    </author>
    <content type="html">&lt;blockquote&gt;
&lt;p dir=&quot;auto&quot;&gt;Map of Content for &lt;strong&gt;Lsp&lt;/strong&gt; — 7 concepts. Start here to navigate lsp.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;core-concepts&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Core Concepts&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#core-concepts&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;a href=&quot;../../language-server-protocol&quot; class=&quot;internal alias&quot; data-slug=&quot;language-server-protocol&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;true&lt;/a&gt; — concept&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../lsp-client&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-client&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;true&lt;/a&gt; — concept&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../lsp-configuration&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-configuration&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;true&lt;/a&gt; — concept&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../lsp-events&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-events&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;true&lt;/a&gt; — concept&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../lsp-root-markers&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-root-markers&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;true&lt;/a&gt; — concept&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../lsp-semantic-tokens&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-semantic-tokens&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;true&lt;/a&gt; — concept&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../vim-lsp&quot; class=&quot;internal alias&quot; data-slug=&quot;vim-lsp&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;true&lt;/a&gt; — concept&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;mechanisms--how-things-work&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Mechanisms &amp;#x26; How Things Work&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#mechanisms--how-things-work&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;&lt;em&gt;Auto-generated — edit to curate. Pages that explain processes/flows.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;comparisons--tradeoffs&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Comparisons &amp;#x26; Tradeoffs&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#comparisons--tradeoffs&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;em&gt;(No synthesis yet — create via ingest or query —save)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;suggested-reading-order&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Suggested Reading Order&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#suggested-reading-order&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol dir=&quot;auto&quot;&gt;
&lt;li&gt;Browse Core Concepts above — start with most-linked page&lt;/li&gt;
&lt;li&gt;Follow Connections sections for dense graph traversal&lt;/li&gt;
&lt;/ol&gt;</content>
  </entry><entry>
    <title>language-server-protocol</title>
    <link href="https://animishraa05.github.io/wiki/lsp/language-server-protocol" />
    <link rel="alternate" type="text/markdown" href="https://animishraa05.github.io/wiki/lsp/language-server-protocol.md" />
    <summary>The Problem Code editors need to provide intelligent features like go-to-definition, refactoring, and completion.</summary>
    <published>2026-04-12T00:00:00.000Z</published>
    <updated>2026-04-12T00:00:00.000Z</updated>
    <publishedTime>Apr 12, 2026</publishedTime>
    <updatedTime>Apr 12, 2026</updatedTime>
    <category term="dev" label="dev" />
<category term="neovim" label="neovim" />
    <author>
      <name>Animesh Mishra</name>
      <email>animesh.mishra818@gmail.com</email>
    </author>
    <content type="html">&lt;h2 id=&quot;the-problem&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;The Problem&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#the-problem&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;Code editors need to provide intelligent features like go-to-definition, refactoring, and completion. Before LSP, each language required custom integration with every editor—a massive N×M problem. LSP standardizes communication between tools and language analyzers.&lt;/p&gt;
&lt;h2 id=&quot;core-idea&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Core Idea&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#core-idea&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;The Language Server Protocol (LSP) is a protocol that defines communication between a code editor (client) and a language analysis tool (server). LSP standardizes features like autocomplete, go-to-definition, find references, hover information, rename, and formatting across all languages.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;How It Works&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#how-it-works&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;Client-Server Architecture&lt;/strong&gt;: The editor acts as an LSP client; the language analyzer runs as a separate process (language server)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JSON-RPC Communication&lt;/strong&gt;: Messages are sent over stdin/stdout using JSON-RPC 2.0&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standardized Methods&lt;/strong&gt;: Features are exposed via methods like &lt;code class=&quot;notranslate&quot;&gt;textDocument/definition&lt;/code&gt;, &lt;code class=&quot;notranslate&quot;&gt;textDocument/completion&lt;/code&gt;, &lt;code class=&quot;notranslate&quot;&gt;textDocument/rename&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Initialization&lt;/strong&gt;: Client and server exchange capabilities during initialization&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Document Synchronization&lt;/strong&gt;: Server receives notifications when files change via &lt;code class=&quot;notranslate&quot;&gt;textDocument/didOpen&lt;/code&gt;, &lt;code class=&quot;notranslate&quot;&gt;textDocument/didChange&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;key-properties&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Key Properties&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#key-properties&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Language-agnostic protocol (works with any programming language)&lt;/li&gt;
&lt;li&gt;Server provides semantic, project-level analysis (unlike ctags)&lt;/li&gt;
&lt;li&gt;Bidirectional: client sends requests, server sends notifications and responses&lt;/li&gt;
&lt;li&gt;Capabilities negotiation: servers declare supported features&lt;/li&gt;
&lt;li&gt;Standardized request/response format&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;connections&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Connections&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#connections&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;Built from:&lt;/strong&gt; JSON-RPC 2.0 — underlying wire protocol&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Builds into:&lt;/strong&gt; Neovim’s vim.lsp — specific client implementation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Related:&lt;/strong&gt; Treesitter — alternative code understanding (syntax parsing vs LSP semantic analysis)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Related:&lt;/strong&gt; Ctags — traditional navigation approach&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;edge-cases--gotchas&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Edge Cases &amp;#x26; Gotchas&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#edge-cases--gotchas&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Servers are third-party; each language requires separate installation&lt;/li&gt;
&lt;li&gt;Not all servers implement all features—check capabilities&lt;/li&gt;
&lt;li&gt;Large projects may have performance issues with file watching&lt;/li&gt;
&lt;li&gt;Dynamic registration allows servers to add capabilities after initialization&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry><entry>
    <title>lsp-client</title>
    <link href="https://animishraa05.github.io/wiki/lsp/lsp-client" />
    <link rel="alternate" type="text/markdown" href="https://animishraa05.github.io/wiki/lsp/lsp-client.md" />
    <summary>The Problem Once an LSP server is started, the editor needs to manage its state—track attached buffers, send requests, handle responses, and monitor capabilities.</summary>
    <published>2026-04-12T00:00:00.000Z</published>
    <updated>2026-04-12T00:00:00.000Z</updated>
    <publishedTime>Apr 12, 2026</publishedTime>
    <updatedTime>Apr 12, 2026</updatedTime>
    <category term="dev" label="dev" />
<category term="neovim" label="neovim" />
    <author>
      <name>Animesh Mishra</name>
      <email>animesh.mishra818@gmail.com</email>
    </author>
    <content type="html">&lt;h2 id=&quot;the-problem&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;The Problem&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#the-problem&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;Once an LSP server is started, the editor needs to manage its state—track attached buffers, send requests, handle responses, and monitor capabilities. This requires an abstraction representing the active LSP connection.&lt;/p&gt;
&lt;h2 id=&quot;core-idea&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Core Idea&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#core-idea&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;An LSP Client is a Neovim object representing an active connection to a language server. It holds the server’s capabilities, attached buffers, pending requests, and methods for interaction.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;How It Works&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#how-it-works&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;Creation&lt;/strong&gt;: &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.start()&lt;/code&gt; or &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.enable()&lt;/code&gt; creates a client from a config&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Retrieval&lt;/strong&gt;: &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.get_client_by_id(id)&lt;/code&gt;, &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.get_clients({filter})&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Capabilities&lt;/strong&gt;: &lt;code class=&quot;notranslate&quot;&gt;client.server_capabilities&lt;/code&gt; exposes what the server supports&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Request tracking&lt;/strong&gt;: &lt;code class=&quot;notranslate&quot;&gt;client.pending_requests&lt;/code&gt; tracks in-flight requests&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Buffer association&lt;/strong&gt;: &lt;code class=&quot;notranslate&quot;&gt;client.attached_buffers&lt;/code&gt; maps to buffers using LSP&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Methods&lt;/strong&gt;: &lt;code class=&quot;notranslate&quot;&gt;client.request()&lt;/code&gt;, &lt;code class=&quot;notranslate&quot;&gt;client.notify()&lt;/code&gt;, &lt;code class=&quot;notranslate&quot;&gt;client.cancel_request()&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;key-properties&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Key Properties&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#key-properties&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Unique &lt;code class=&quot;notranslate&quot;&gt;id&lt;/code&gt; for referencing the client&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;notranslate&quot;&gt;name&lt;/code&gt; from config or default&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;notranslate&quot;&gt;server_capabilities&lt;/code&gt; populated after initialization&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;notranslate&quot;&gt;root_dir&lt;/code&gt; derived from config or root_markers&lt;/li&gt;
&lt;li&gt;Can attach to multiple buffers simultaneously&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;connections&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Connections&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#connections&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;Built from:&lt;/strong&gt; &lt;a href=&quot;../../lsp-configuration&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-configuration&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP Configuration&lt;/a&gt; — config creates client&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Builds into:&lt;/strong&gt; &lt;a href=&quot;../../vim-lsp&quot; class=&quot;internal alias&quot; data-slug=&quot;vim-lsp&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;vim.lsp&lt;/a&gt; — clients are managed by vim.lsp&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Related:&lt;/strong&gt; &lt;a href=&quot;../../lsp-events&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-events&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP Events&lt;/a&gt; — events fired based on client activity&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;edge-cases--gotchas&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Edge Cases &amp;#x26; Gotchas&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#edge-cases--gotchas&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Client may not be fully initialized when first returned&lt;/li&gt;
&lt;li&gt;Dynamic registration can add capabilities after LspAttach&lt;/li&gt;
&lt;li&gt;Stopped clients return nil from get_client_by_id&lt;/li&gt;
&lt;li&gt;Request cancellation triggers LspRequest event with type=cancel&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry><entry>
    <title>lsp-configuration</title>
    <link href="https://animishraa05.github.io/wiki/lsp/lsp-configuration" />
    <link rel="alternate" type="text/markdown" href="https://animishraa05.github.io/wiki/lsp/lsp-configuration.md" />
    <summary>The Problem Different language servers need different startup commands, file type associations, and workspace detection rules.</summary>
    <published>2026-04-12T00:00:00.000Z</published>
    <updated>2026-04-12T00:00:00.000Z</updated>
    <publishedTime>Apr 12, 2026</publishedTime>
    <updatedTime>Apr 12, 2026</updatedTime>
    <category term="dev" label="dev" />
<category term="neovim" label="neovim" />
    <author>
      <name>Animesh Mishra</name>
      <email>animesh.mishra818@gmail.com</email>
    </author>
    <content type="html">&lt;h2 id=&quot;the-problem&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;The Problem&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#the-problem&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;Different language servers need different startup commands, file type associations, and workspace detection rules. Users and plugins need a unified way to define and share LSP configurations without code duplication.&lt;/p&gt;
&lt;h2 id=&quot;core-idea&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Core Idea&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#core-idea&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;LSP Configuration in Neovim uses &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.config()&lt;/code&gt; to define server settings, with a merge chain that allows global defaults, plugin configs, and user overrides to coexist.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;How It Works&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#how-it-works&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;Definition&lt;/strong&gt;: &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.config(&#039;server-name&#039;, {cmd = {...}, filetypes = {...}, root_markers = {...}})&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enable&lt;/strong&gt;: &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.enable(&#039;server-name&#039;)&lt;/code&gt; activates auto-attachment for matching buffers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Merge Priority&lt;/strong&gt; (lowest to highest):
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Global config (&lt;code class=&quot;notranslate&quot;&gt;vim.lsp.config(&#039;*&#039;, {...})&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;notranslate&quot;&gt;lsp/&amp;#x3C;name&gt;.lua&lt;/code&gt; files in runtimepath&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;notranslate&quot;&gt;after/lsp/&amp;#x3C;name&gt;.lua&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;Direct config calls in init.lua&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Config sources&lt;/strong&gt;: Can also use &lt;code class=&quot;notranslate&quot;&gt;lsp/&amp;#x3C;name&gt;.lua&lt;/code&gt; files in runtimepath&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;key-properties&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Key Properties&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#key-properties&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Wildcard &lt;code class=&quot;notranslate&quot;&gt;*&lt;/code&gt; config applies to all servers&lt;/li&gt;
&lt;li&gt;root_markers can be nested for equal-priority markers: &lt;code class=&quot;notranslate&quot;&gt;{{&#039;a&#039;, &#039;b&#039;}, &#039;c&#039;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Config merging uses &lt;code class=&quot;notranslate&quot;&gt;vim.tbl_deep_extend&lt;/code&gt; with “force” behavior&lt;/li&gt;
&lt;li&gt;Config files in runtimepath may be eagerly evaluated (performance note)&lt;/li&gt;
&lt;li&gt;“after/” directory follows standard Vim after-directory semantics&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;connections&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Connections&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#connections&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;Built from:&lt;/strong&gt; &lt;a href=&quot;../../vim-lsp&quot; class=&quot;internal alias&quot; data-slug=&quot;vim-lsp&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;vim.lsp&lt;/a&gt; — the framework providing config()&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Builds into:&lt;/strong&gt; &lt;a href=&quot;../../lsp-client&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-client&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP Client&lt;/a&gt; — configs become client instances via enable/start&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Related:&lt;/strong&gt; &lt;a href=&quot;../../lsp-root-markers&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-root-markers&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;Root Markers&lt;/a&gt; — part of config that determines workspace&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Related:&lt;/strong&gt; &lt;a href=&quot;../../lsp-events&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-events&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP Events&lt;/a&gt; — lifecycle events triggered for configured clients&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;edge-cases--gotchas&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Edge Cases &amp;#x26; Gotchas&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#edge-cases--gotchas&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Using &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.config[&#039;name&#039;]&lt;/code&gt; has side-effect of resolving config&lt;/li&gt;
&lt;li&gt;Prefer &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.is_enabled()&lt;/code&gt; to check status without resolving&lt;/li&gt;
&lt;li&gt;Place configs in &lt;code class=&quot;notranslate&quot;&gt;after/lsp/&lt;/code&gt; to override plugin defaults&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry><entry>
    <title>lsp-events</title>
    <link href="https://animishraa05.github.io/wiki/lsp/lsp-events" />
    <link rel="alternate" type="text/markdown" href="https://animishraa05.github.io/wiki/lsp/lsp-events.md" />
    <summary>The Problem Plugins and users need to react to LSP lifecycle events—attach to buffers, respond to progress, handle document changes.</summary>
    <published>2026-04-12T00:00:00.000Z</published>
    <updated>2026-04-12T00:00:00.000Z</updated>
    <publishedTime>Apr 12, 2026</publishedTime>
    <updatedTime>Apr 12, 2026</updatedTime>
    <category term="dev" label="dev" />
<category term="neovim" label="neovim" />
    <author>
      <name>Animesh Mishra</name>
      <email>animesh.mishra818@gmail.com</email>
    </author>
    <content type="html">&lt;h2 id=&quot;the-problem&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;The Problem&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#the-problem&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;Plugins and users need to react to LSP lifecycle events—attach to buffers, respond to progress, handle document changes. Neovim needs a way to signal when these events occur so users can customize behavior.&lt;/p&gt;
&lt;h2 id=&quot;core-idea&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Core Idea&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#core-idea&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;LSP Events are Neovim autocmd events triggered during LSP client lifecycle: LspAttach (client initializes), LspDetach (client disconnects), LspProgress (server sends progress), LspRequest (request status changes), LspNotify (notification sent), LspTokenUpdate (semantic token changed).&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;How It Works&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#how-it-works&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;LspAttach&lt;/strong&gt;: Fired after client initializes and attaches to buffer; provides &lt;code class=&quot;notranslate&quot;&gt;client_id&lt;/code&gt; in event data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LspDetach&lt;/strong&gt;: Fired just before client detaches; clean up custom handlers here&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LspProgress&lt;/strong&gt;: Triggered on progress notifications; use for statusline updates&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LspRequest&lt;/strong&gt;: Fires on request send, completion, or cancellation; track pending work&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LspNotify&lt;/strong&gt;: Fires after each successful notification to server&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LspTokenUpdate&lt;/strong&gt;: Fires when semantic tokens change; for custom token highlighting&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;key-properties&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Key Properties&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#key-properties&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Use &lt;code class=&quot;notranslate&quot;&gt;vim.api.nvim_create_autocmd()&lt;/code&gt; with event name&lt;/li&gt;
&lt;li&gt;Event data passed to callback contains client_id, method, params, etc.&lt;/li&gt;
&lt;li&gt;LspProgress pattern can be filtered by work done kind (begin/report/end)&lt;/li&gt;
&lt;li&gt;Dynamic registration may add capabilities after LspAttach&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;connections&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Connections&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#connections&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;Built from:&lt;/strong&gt; &lt;a href=&quot;../../lsp-client&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-client&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP Client&lt;/a&gt; — events relate to client lifecycle&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Builds into:&lt;/strong&gt; &lt;a href=&quot;../../vim-lsp&quot; class=&quot;internal alias&quot; data-slug=&quot;vim-lsp&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;vim.lsp&lt;/a&gt; — vim.lsp triggers these events&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Related:&lt;/strong&gt; &lt;a href=&quot;../../lsp-semantic-tokens&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-semantic-tokens&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;Semantic Tokens&lt;/a&gt; — LspTokenUpdate for token changes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;edge-cases--gotchas&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Edge Cases &amp;#x26; Gotchas&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#edge-cases--gotchas&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Dynamic registration can happen after LspAttach; handle registerCapability event&lt;/li&gt;
&lt;li&gt;LspDetach is the place to remove buffer-local autocmds (like format on save)&lt;/li&gt;
&lt;li&gt;LspRequest with type=complete deletes pending request after handler runs&lt;/li&gt;
&lt;li&gt;LspTokenUpdate is experimental beyond calling highlight_token()&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry><entry>
    <title>lsp-root-markers</title>
    <link href="https://animishraa05.github.io/wiki/lsp/lsp-root-markers" />
    <link rel="alternate" type="text/markdown" href="https://animishraa05.github.io/wiki/lsp/lsp-root-markers.md" />
    <summary>The Problem LSP servers need to know the project root to provide accurate analysis—finding dependencies, resolving imports, understanding project structure.</summary>
    <published>2026-04-12T00:00:00.000Z</published>
    <updated>2026-04-12T00:00:00.000Z</updated>
    <publishedTime>Apr 12, 2026</publishedTime>
    <updatedTime>Apr 12, 2026</updatedTime>
    <category term="dev" label="dev" />
<category term="neovim" label="neovim" />
    <author>
      <name>Animesh Mishra</name>
      <email>animesh.mishra818@gmail.com</email>
    </author>
    <content type="html">&lt;h2 id=&quot;the-problem&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;The Problem&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#the-problem&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;LSP servers need to know the project root to provide accurate analysis—finding dependencies, resolving imports, understanding project structure. Without knowing the root, the server might behave incorrectly or provide incomplete results.&lt;/p&gt;
&lt;h2 id=&quot;core-idea&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Core Idea&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#core-idea&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;Root Markers are files or directories (like &lt;code class=&quot;notranslate&quot;&gt;.git&lt;/code&gt;, &lt;code class=&quot;notranslate&quot;&gt;package.json&lt;/code&gt;, &lt;code class=&quot;notranslate&quot;&gt;pyproject.toml&lt;/code&gt;) that Neovim uses to identify the project workspace root. When a buffer matches a config’s filetypes, Neovim searches upward for root markers to determine where the LSP server operates.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;How It Works&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#how-it-works&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol dir=&quot;auto&quot;&gt;
&lt;li&gt;Config specifies &lt;code class=&quot;notranslate&quot;&gt;root_markers: {&#039;.git&#039;, &#039;package.json&#039;, &#039;pyproject.toml&#039;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;When enabling LSP for a buffer, Neovim searches upward from the buffer’s directory&lt;/li&gt;
&lt;li&gt;First marker found determines the root; search stops at that directory&lt;/li&gt;
&lt;li&gt;Multiple markers in nested array have equal priority: &lt;code class=&quot;notranslate&quot;&gt;{{&#039;a&#039;, &#039;b&#039;}, &#039;c&#039;}&lt;/code&gt; means find either a or b first, else c&lt;/li&gt;
&lt;li&gt;If &lt;code class=&quot;notranslate&quot;&gt;root_dir&lt;/code&gt; is explicitly defined, root_markers are ignored&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;key-properties&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Key Properties&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#key-properties&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Marker can be a file or directory name&lt;/li&gt;
&lt;li&gt;Order in the array determines search priority&lt;/li&gt;
&lt;li&gt;Nested arrays indicate equal-priority markers&lt;/li&gt;
&lt;li&gt;Can be overridden by explicit &lt;code class=&quot;notranslate&quot;&gt;root_dir&lt;/code&gt; function&lt;/li&gt;
&lt;li&gt;Used by &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.enable()&lt;/code&gt; for auto-activation decisions&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;connections&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Connections&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#connections&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;Built from:&lt;/strong&gt; &lt;a href=&quot;../../lsp-configuration&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-configuration&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP Configuration&lt;/a&gt; — part of config&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Builds into:&lt;/strong&gt; &lt;a href=&quot;../../lsp-client&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-client&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP Client&lt;/a&gt; — root_dir becomes client property&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Related:&lt;/strong&gt; &lt;a href=&quot;../../vim-lsp&quot; class=&quot;internal alias&quot; data-slug=&quot;vim-lsp&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;vim.lsp&lt;/a&gt; — used by enable() for workspace detection&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;edge-cases--gotchas&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Edge Cases &amp;#x26; Gotchas&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#edge-cases--gotchas&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Without matching root markers, LSP won’t auto-activate&lt;/li&gt;
&lt;li&gt;Search traverses upward until root filesystem or found&lt;/li&gt;
&lt;li&gt;Polyglot projects may need careful marker ordering&lt;/li&gt;
&lt;li&gt;Some languages have specific markers (e.g., &lt;code class=&quot;notranslate&quot;&gt;.clangd&lt;/code&gt; for clangd)&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry><entry>
    <title>lsp-semantic-tokens</title>
    <link href="https://animishraa05.github.io/wiki/lsp/lsp-semantic-tokens" />
    <link rel="alternate" type="text/markdown" href="https://animishraa05.github.io/wiki/lsp/lsp-semantic-tokens.md" />
    <summary>The Problem Syntax highlighting shows code structure (keywords, strings, comments) but not semantic meaning (is this a function? a class? deprecated?).</summary>
    <published>2026-04-12T00:00:00.000Z</published>
    <updated>2026-04-12T00:00:00.000Z</updated>
    <publishedTime>Apr 12, 2026</publishedTime>
    <updatedTime>Apr 12, 2026</updatedTime>
    <category term="dev" label="dev" />
<category term="neovim" label="neovim" />
    <author>
      <name>Animesh Mishra</name>
      <email>animesh.mishra818@gmail.com</email>
    </author>
    <content type="html">&lt;h2 id=&quot;the-problem&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;The Problem&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#the-problem&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;Syntax highlighting shows code structure (keywords, strings, comments) but not semantic meaning (is this a function? a class? deprecated?). Treesitter provides syntax-level highlighting, but LSP servers have additional semantic knowledge about the code that can enhance the editing experience.&lt;/p&gt;
&lt;h2 id=&quot;core-idea&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Core Idea&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#core-idea&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;Semantic Tokens are LSP protocol extensions that let servers provide additional highlighting based on semantic meaning—identifying functions, variables, classes, parameters, and their modifiers (readonly, async, deprecated, etc.). This works alongside Treesitter, not replacing it.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;How It Works&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#how-it-works&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol dir=&quot;auto&quot;&gt;
&lt;li&gt;Server advertises &lt;code class=&quot;notranslate&quot;&gt;textDocument/semanticTokens&lt;/code&gt; capability during initialization&lt;/li&gt;
&lt;li&gt;Server sends tokens as ranges with type (function, variable, class) and modifiers (readonly, async)&lt;/li&gt;
&lt;li&gt;Neovim applies highlight groups: &lt;code class=&quot;notranslate&quot;&gt;@lsp.type.&amp;#x3C;type&gt;.&amp;#x3C;filetype&gt;&lt;/code&gt;, &lt;code class=&quot;notranslate&quot;&gt;@lsp.mod.&amp;#x3C;mod&gt;.&amp;#x3C;filetype&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Can combine type+modifiers: &lt;code class=&quot;notranslate&quot;&gt;@lsp.typemod.&amp;#x3C;type&gt;.&amp;#x3C;mod&gt;.&amp;#x3C;filetype&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;LspTokenUpdate event fires when tokens change (for custom highlighting)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;key-properties&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Key Properties&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#key-properties&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Adds to Treesitter highlighting, doesn’t replace it&lt;/li&gt;
&lt;li&gt;Standard types: class, function, method, variable, parameter, etc.&lt;/li&gt;
&lt;li&gt;Standard modifiers: readonly, async, deprecated, static, abstract&lt;/li&gt;
&lt;li&gt;Highlight groups can be customized via &lt;code class=&quot;notranslate&quot;&gt;hi&lt;/code&gt; or &lt;code class=&quot;notranslate&quot;&gt;nvim_set_hl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Priority: @lsp.type._ = semantic_tokens, @lsp.mod._ +1, @lsp.typemod.* +2&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;connections&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Connections&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#connections&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;Related:&lt;/strong&gt; &lt;a href=&quot;../../treesitter&quot; class=&quot;internal alias&quot; data-slug=&quot;treesitter&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;Treesitter&lt;/a&gt; — provides syntax-level highlighting&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Builds into:&lt;/strong&gt; &lt;a href=&quot;../../lsp-events&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-events&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP Events&lt;/a&gt; — LspTokenUpdate for token changes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Related:&lt;/strong&gt; &lt;a href=&quot;../../vim-lsp&quot; class=&quot;internal alias&quot; data-slug=&quot;vim-lsp&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;vim.lsp&lt;/a&gt; — handles semantic token integration&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;edge-cases--gotchas&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Edge Cases &amp;#x26; Gotchas&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#edge-cases--gotchas&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Semantic highlights are additive to Treesitter—not a replacement&lt;/li&gt;
&lt;li&gt;Servers may use non-standard types/modifiers beyond the specification&lt;/li&gt;
&lt;li&gt;Disable by clearing highlight groups in ColorScheme autocmd&lt;/li&gt;
&lt;li&gt;LspTokenUpdate only supports highlight_token() call; other uses experimental&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry><entry>
    <title>vim-lsp</title>
    <link href="https://animishraa05.github.io/wiki/lsp/vim-lsp" />
    <link rel="alternate" type="text/markdown" href="https://animishraa05.github.io/wiki/lsp/vim-lsp.md" />
    <summary>The Problem Neovim needs a built-in way to connect to LSP servers without requiring external plugins.</summary>
    <published>2026-04-12T00:00:00.000Z</published>
    <updated>2026-04-12T00:00:00.000Z</updated>
    <publishedTime>Apr 12, 2026</publishedTime>
    <updatedTime>Apr 12, 2026</updatedTime>
    <category term="dev" label="dev" />
<category term="neovim" label="neovim" />
    <author>
      <name>Animesh Mishra</name>
      <email>animesh.mishra818@gmail.com</email>
    </author>
    <content type="html">&lt;h2 id=&quot;the-problem&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;The Problem&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#the-problem&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;Neovim needs a built-in way to connect to LSP servers without requiring external plugins. The built-in LSP client should handle the complexity of starting servers, managing clients, and exposing a Lua API for interacting with language servers.&lt;/p&gt;
&lt;h2 id=&quot;core-idea&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Core Idea&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#core-idea&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;&lt;code class=&quot;notranslate&quot;&gt;vim.lsp&lt;/code&gt; is Neovim’s built-in Lua framework for creating LSP clients and building LSP-powered tools. It provides functions to start/configure language servers, handle LSP methods, and implement editor features using semantic analysis.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;How It Works&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#how-it-works&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;Configuration&lt;/strong&gt;: Use &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.config()&lt;/code&gt; to define server configurations (cmd, filetypes, root_markers)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Activation&lt;/strong&gt;: Use &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.enable()&lt;/code&gt; to auto-start LSP for matching buffers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Client Management&lt;/strong&gt;: &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.start()&lt;/code&gt; creates a client; &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.get_clients()&lt;/code&gt; retrieves active clients&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Buffer Operations&lt;/strong&gt;: &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.buf.*&lt;/code&gt; functions operate on the current buffer (definition, references, hover)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handler System&lt;/strong&gt;: Custom handlers can intercept/override LSP responses at multiple levels&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;key-properties&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Key Properties&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#key-properties&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Built-in (no plugin required for basic LSP)&lt;/li&gt;
&lt;li&gt;Lua-native API (&lt;code class=&quot;notranslate&quot;&gt;vim.lsp.buf&lt;/code&gt;, &lt;code class=&quot;notranslate&quot;&gt;vim.lsp.client&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Config merging from multiple sources (global, runtimepath, after/)&lt;/li&gt;
&lt;li&gt;Built-in keymaps and buffer-local options for common features&lt;/li&gt;
&lt;li&gt;Event-driven: LspAttach, LspDetach, LspProgress, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;connections&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Connections&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#connections&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;&lt;strong&gt;Built from:&lt;/strong&gt; &lt;a href=&quot;../../language-server-protocol&quot; class=&quot;internal alias&quot; data-slug=&quot;language-server-protocol&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP&lt;/a&gt; — the protocol it implements&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Builds into:&lt;/strong&gt; &lt;a href=&quot;../../lsp-configuration&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-configuration&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP Configuration&lt;/a&gt;, &lt;a href=&quot;../../lsp-client&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-client&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP Client&lt;/a&gt;, &lt;a href=&quot;../../lsp-events&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-events&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;LSP Events&lt;/a&gt;, &lt;a href=&quot;../../lsp-semantic-tokens&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-semantic-tokens&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;Semantic Tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Related:&lt;/strong&gt; &lt;a href=&quot;../../lsp-root-markers&quot; class=&quot;internal alias&quot; data-slug=&quot;lsp-root-markers&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;Root Markers&lt;/a&gt; — workspace detection&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contrasts with:&lt;/strong&gt; Treesitter — syntax parsing vs semantic analysis&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;edge-cases--gotchas&quot; dir=&quot;auto&quot;&gt;&lt;span class=&quot;highlight-span&quot;&gt;Edge Cases &amp;#x26; Gotchas&lt;/span&gt;&lt;a data-role=&quot;anchor&quot; data-no-popover href=&quot;#edge-cases--gotchas&quot; class=&quot;internal&quot;&gt;&lt;span class=&quot;indicator-hook&quot;&gt;&lt;/span&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;use href=&quot;#github-anchor&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;Config files in runtimepath are eagerly evaluated&lt;/li&gt;
&lt;li&gt;Global keymaps are created unconditionally on startup&lt;/li&gt;
&lt;li&gt;Default buffer-local settings (omnifunc, tagfunc, formatexpr) can conflict with other plugins&lt;/li&gt;
&lt;li&gt;Large workspaces: file watching can cause performance issues on Linux&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
</feed>