<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Neotest on Haseeb Majid</title>
    <link>https://haseebmajid.dev/tags/neotest/</link>
    <description>Recent content in Neotest on Haseeb Majid</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Sun, 02 Nov 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://haseebmajid.dev/tags/neotest/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Yak Shaving: Neotest Edition</title>
      <link>https://haseebmajid.dev/posts/2025-11-02-yak-shaving-neotest-edition/</link>
      <pubDate>Sun, 02 Nov 2025 00:00:00 +0000</pubDate>
      
      <guid>https://haseebmajid.dev/posts/2025-11-02-yak-shaving-neotest-edition/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; The fix is in this commit: &lt;a href=&#34;https://gitlab.com/hmajid2301/nixicle/-/commit/cfababc9e3a1dfdd1917d0b87cb17fcdd655bfdc&#34;&gt;https://gitlab.com/hmajid2301/nixicle/-/commit/cfababc9e3a1dfdd1917d0b87cb17fcdd655bfdc&lt;/a&gt;  Fixing stuff is fun! 🥳&lt;/p&gt;
&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;I use Neovim (btw!) and Nix (btw btw!!!). I mean, half the reason to use these tools is to tell other people you use them, right? 😉 Otherwise, why would I go through the pain I experienced today? &amp;ldquo;What pain?&amp;rdquo; you ask. Good question!&lt;/p&gt;
&lt;p&gt;A few weeks ago, I noticed that running tests in Neovim was failing with a &lt;code&gt;no test found&lt;/code&gt; error. I&amp;rsquo;m using &lt;code&gt;neotest&lt;/code&gt; and &lt;code&gt;neotest-golang&lt;/code&gt; to run tests within Neovim.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>TL;DR:</strong> The fix is in this commit: <a href="https://gitlab.com/hmajid2301/nixicle/-/commit/cfababc9e3a1dfdd1917d0b87cb17fcdd655bfdc">https://gitlab.com/hmajid2301/nixicle/-/commit/cfababc9e3a1dfdd1917d0b87cb17fcdd655bfdc</a>  Fixing stuff is fun! 🥳</p>
<h2 id="background">Background</h2>
<p>I use Neovim (btw!) and Nix (btw btw!!!). I mean, half the reason to use these tools is to tell other people you use them, right? 😉 Otherwise, why would I go through the pain I experienced today? &ldquo;What pain?&rdquo; you ask. Good question!</p>
<p>A few weeks ago, I noticed that running tests in Neovim was failing with a <code>no test found</code> error. I&rsquo;m using <code>neotest</code> and <code>neotest-golang</code> to run tests within Neovim.</p>
<p>Here&rsquo;s a <a href="https://gitlab.com/hmajid2301/nixicle/-/blob/main/modules/home/cli/editors/neovim/lua/myLuaConf/test/init.lua">link to my config</a>.</p>
<p>I&rsquo;m also using the nightly build of Neovim, so getting the latest version isn&rsquo;t great if you want stability. Things can break at any moment, like running tests. Anyway, today (November 1st), I had some free time and decided to spend most of the day fixing this issue.  poświęcenie</p>
<h2 id="setup">Setup</h2>
<p>I&rsquo;m using NixOS (should I do another &ldquo;btw&rdquo; joke??? 🤔), so I want to manage all my dependencies with Nix. I&rsquo;m also using NixCats, which allows me to configure Neovim with Lua but package it with Nix (it has a few other features I don&rsquo;t really use, but others might).</p>
<p>One of the nice features of NixCats is that we can easily add Neovim plugins that aren&rsquo;t in <a href="https://search.nixos.org/packages?type=packages&amp;query=vimPLugins&amp;channel=unstable"><code>nixpkgs</code></a> using our flake inputs:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="n">plugins-neotest-golang</span> <span class="err">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">url</span> <span class="o">=</span> <span class="s2">&#34;github:fredrikaverpil/neotest-golang&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">flake</span> <span class="o">=</span> <span class="no">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>We just need to add <code>plugins-x</code>, and then we can reference it in our NixCats config like <code>pkgs.neovimPlugins.neotest-golang</code>. It&rsquo;s tied to my flake, so I can just run <code>nix flake update</code> to update those Neovim plugins along with every other input. Then I upgrade my setup, as you might with <code>apt upgrade</code>, but with <code>nh os switch</code> or <code>nh home switch</code>.</p>
<h2 id="debugging-">Debugging 🐛</h2>
<p>This setup means I can use the latest version of this plugin (v2.5.0 at the time of writing), but even upgrading to the latest version wasn&rsquo;t enough. I probably shouldn&rsquo;t have tied it to the main branch. 😅</p>
<p>I found this <a href="https://github.com/fredrikaverpil/neotest-golang/issues/386">issue</a>, which made me think I should try the latest version.</p>
<p>After a lot of (wasted) debugging, I finally read the <a href="https://fredrikaverpil.github.io/neotest-golang/install/">migration guide</a>. An amateur mistake, I know. 🤦</p>
<h3 id="nvim-treesitter">nvim-treesitter</h3>
<p>It turns out I need to use <code>nvim-treesitter</code>, but the <code>main</code> branch, not the <code>master</code> branch, which is frozen and no longer under development. There&rsquo;s an <a href="https://github.com/iofq/nvim-treesitter-main">existing overlay</a> we can use so we don&rsquo;t have to change how we install our dependencies.</p>
<p>Like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="n">nvim-treesitter-main</span> <span class="err">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">url</span> <span class="o">=</span> <span class="s2">&#34;github:iofq/nvim-treesitter-main&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">inputs</span><span class="o">.</span><span class="n">nixpkgs</span><span class="o">.</span><span class="n">follows</span> <span class="o">=</span> <span class="s2">&#34;nixpkgs&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>I&rsquo;m also using <code>snowfall-lib</code>, so I can add a new overlay like so in my <code>flake.nix</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="n">overlays</span> <span class="err">=</span> <span class="k">with</span> <span class="n">inputs</span><span class="p">;</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># ...</span>
</span></span><span class="line"><span class="cl">    <span class="n">nvim-treesitter-main</span><span class="o">.</span><span class="n">overlays</span><span class="o">.</span><span class="n">default</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span></code></pre></div><p>I also created a new overlay file, <code>overlays/nvim-treesitter-main/default.nix</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="n">inputs</span><span class="p">:</span> <span class="n">final</span><span class="p">:</span> <span class="n">prev</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">vimPlugins</span> <span class="o">=</span> <span class="n">prev</span><span class="o">.</span><span class="n">vimPlugins</span> <span class="o">//</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">nvim-treesitter</span> <span class="o">=</span> <span class="n">prev</span><span class="o">.</span><span class="n">vimPlugins</span><span class="o">.</span><span class="n">nvim-treesitter</span><span class="o">.</span><span class="n">withAllGrammars</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">nvim-treesitter-textobjects</span> <span class="o">=</span> <span class="n">prev</span><span class="o">.</span><span class="n">vimPlugins</span><span class="o">.</span><span class="n">nvim-treesitter-textobjects</span><span class="o">.</span><span class="n">overrideAttrs</span> <span class="p">(</span><span class="n">old</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">dependencies</span> <span class="o">=</span> <span class="k">with</span> <span class="n">prev</span><span class="o">.</span><span class="n">vimPlugins</span><span class="p">;</span> <span class="p">[</span> <span class="n">nvim-treesitter</span> <span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>You can also add the cache to save some time rebuilding all the grammars on your own machine:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="n">trusted-substituters</span> <span class="err">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;https://nvim-treesitter-main.cachix.org&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span></code></pre></div><p>Then, in my Neovim config, I updated the setup to look like this:</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="s2">&#34;nvim-treesitter&#34;</span><span class="p">).</span><span class="n">setup</span><span class="p">()</span>
</span></span></code></pre></div><p>After this, when I opened a Markdown document, I noticed it was all white. But using <code>InspectTree</code>, the AST looked correct. It seemed like highlighting wasn&rsquo;t working, which, again, if I had read the docs, I would&rsquo;ve seen that I need to create an autocommand.</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">vim.api</span><span class="p">.</span><span class="n">nvim_create_autocmd</span><span class="p">(</span><span class="s2">&#34;FileType&#34;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="n">pattern</span> <span class="o">=</span> <span class="s2">&#34;*&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	<span class="n">callback</span> <span class="o">=</span> <span class="kr">function</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">		<span class="c1">-- Add error handling to prevent crashes during session restore</span>
</span></span><span class="line"><span class="cl">		<span class="kd">local</span> <span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="n">pcall</span><span class="p">(</span><span class="kr">function</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">			<span class="c1">-- Check if parser is available before starting</span>
</span></span><span class="line"><span class="cl">			<span class="kd">local</span> <span class="n">lang</span> <span class="o">=</span> <span class="n">vim.bo</span><span class="p">[</span><span class="n">args.buf</span><span class="p">].</span><span class="n">filetype</span>
</span></span><span class="line"><span class="cl">			<span class="kd">local</span> <span class="n">ts_lang</span> <span class="o">=</span> <span class="n">vim.treesitter</span><span class="p">.</span><span class="n">language.get_lang</span><span class="p">(</span><span class="n">lang</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">			<span class="kr">if</span> <span class="n">ts_lang</span> <span class="kr">then</span>
</span></span><span class="line"><span class="cl">				<span class="n">vim.treesitter</span><span class="p">.</span><span class="n">start</span><span class="p">(</span><span class="n">args.buf</span><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 class="kr">end</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">		<span class="kr">if</span> <span class="ow">not</span> <span class="n">success</span> <span class="kr">then</span>
</span></span><span class="line"><span class="cl">			<span class="c1">-- Silently fail if treesitter can&#39;t start for this buffer</span>
</span></span><span class="line"><span class="cl">			<span class="n">vim.notify</span><span class="p">(</span><span class="s2">&#34;Treesitter failed to start for &#34;</span> <span class="o">..</span> <span class="n">vim.bo</span><span class="p">[</span><span class="n">args.buf</span><span class="p">].</span><span class="n">filetype</span> <span class="o">..</span> <span class="s2">&#34;: &#34;</span> <span class="o">..</span> <span class="n">err</span><span class="p">,</span> <span class="n">vim.log</span><span class="p">.</span><span class="n">levels.DEBUG</span><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 class="kr">end</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><h4 id="textobjects">textobjects</h4>
<p>To set up textobjects, we need to set up the plugin separately as well, also using the <code>main</code> branch. It now looks something like this:</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="s2">&#34;nvim-treesitter-textobjects&#34;</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">select</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">lookahead</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">selection_modes</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="p">[</span><span class="s2">&#34;@parameter.outer&#34;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&#34;v&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="p">[</span><span class="s2">&#34;@function.outer&#34;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&#34;V&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="p">[</span><span class="s2">&#34;@class.outer&#34;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&#34;&lt;c-v&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="n">include_surrounding_whitespace</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="n">move</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">set_jumps</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 class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">-- Set up select keymaps using the new API</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="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;o&#34;</span> <span class="p">},</span> <span class="s2">&#34;af&#34;</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">require</span><span class="p">(</span><span class="s2">&#34;nvim-treesitter-textobjects.select&#34;</span><span class="p">).</span><span class="n">select_textobject</span><span class="p">(</span><span class="s2">&#34;@function.outer&#34;</span><span class="p">,</span> <span class="s2">&#34;textobjects&#34;</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">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">({</span> <span class="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;o&#34;</span> <span class="p">},</span> <span class="s2">&#34;if&#34;</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">require</span><span class="p">(</span><span class="s2">&#34;nvim-treesitter-textobjects.select&#34;</span><span class="p">).</span><span class="n">select_textobject</span><span class="p">(</span><span class="s2">&#34;@function.inner&#34;</span><span class="p">,</span> <span class="s2">&#34;textobjects&#34;</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">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">({</span> <span class="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;o&#34;</span> <span class="p">},</span> <span class="s2">&#34;ac&#34;</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">require</span><span class="p">(</span><span class="s2">&#34;nvim-treesitter-textobjects.select&#34;</span><span class="p">).</span><span class="n">select_textobject</span><span class="p">(</span><span class="s2">&#34;@class.outer&#34;</span><span class="p">,</span> <span class="s2">&#34;textobjects&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="kr">end</span><span class="p">)</span>
</span></span></code></pre></div><p>Notice how we now set up the textobjects as keybindings. Then, for <code>swap</code> and <code>repeatable</code>, assuming you were using those, it looks something like this:</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">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;&lt;leader&gt;a&#34;</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">require</span><span class="p">(</span><span class="s2">&#34;nvim-treesitter-textobjects.swap&#34;</span><span class="p">).</span><span class="n">swap_next</span><span class="p">(</span><span class="s2">&#34;@parameter.inner&#34;</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">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;&lt;leader&gt;A&#34;</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">require</span><span class="p">(</span><span class="s2">&#34;nvim-treesitter-textobjects.swap&#34;</span><span class="p">).</span><span class="n">swap_previous</span><span class="p">(</span><span class="s2">&#34;@parameter.outer&#34;</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></span><span class="line"><span class="cl"><span class="kd">local</span> <span class="n">ts_repeat_ok</span><span class="p">,</span> <span class="n">ts_repeat_move</span> <span class="o">=</span> <span class="n">pcall</span><span class="p">(</span><span class="n">require</span><span class="p">,</span> <span class="s2">&#34;nvim-treesitter-textobjects.repeatable_move&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="kr">if</span> <span class="n">ts_repeat_ok</span> <span class="kr">then</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="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;o&#34;</span> <span class="p">},</span> <span class="s2">&#34;;&#34;</span><span class="p">,</span> <span class="n">ts_repeat_move.repeat_last_move_next</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="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;o&#34;</span> <span class="p">},</span> <span class="s2">&#34;,&#34;</span><span class="p">,</span> <span class="n">ts_repeat_move.repeat_last_move_previous</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="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;o&#34;</span> <span class="p">},</span> <span class="s2">&#34;f&#34;</span><span class="p">,</span> <span class="n">ts_repeat_move.builtin_f_expr</span><span class="p">,</span> <span class="p">{</span> <span class="n">expr</span> <span class="o">=</span> <span class="kc">true</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="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;o&#34;</span> <span class="p">},</span> <span class="s2">&#34;F&#34;</span><span class="p">,</span> <span class="n">ts_repeat_move.builtin_F_expr</span><span class="p">,</span> <span class="p">{</span> <span class="n">expr</span> <span class="o">=</span> <span class="kc">true</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="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;o&#34;</span> <span class="p">},</span> <span class="s2">&#34;t&#34;</span><span class="p">,</span> <span class="n">ts_repeat_move.builtin_t_expr</span><span class="p">,</span> <span class="p">{</span> <span class="n">expr</span> <span class="o">=</span> <span class="kc">true</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="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;o&#34;</span> <span class="p">},</span> <span class="s2">&#34;T&#34;</span><span class="p">,</span> <span class="n">ts_repeat_move.builtin_T_expr</span><span class="p">,</span> <span class="p">{</span> <span class="n">expr</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></span></code></pre></div><h4 id="incremental-selection">incremental selection</h4>
<p>You can now do this via the LSP instead of the textobjects plugin, so I added the following plugins:</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">vim.keymap</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;&lt;c-space&gt;&#34;</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.selection_range</span><span class="p">(</span><span class="s2">&#34;outer&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="kr">end</span><span class="p">,</span> <span class="p">{</span> <span class="n">desc</span> <span class="o">=</span> <span class="s2">&#34;Expand selection (incremental)&#34;</span> <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</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="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;&lt;M-space&gt;&#34;</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.selection_range</span><span class="p">(</span><span class="s2">&#34;inner&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="kr">end</span><span class="p">,</span> <span class="p">{</span> <span class="n">desc</span> <span class="o">=</span> <span class="s2">&#34;Shrink selection (incremental)&#34;</span> <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</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="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;&lt;c-space&gt;&#34;</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.cmd</span><span class="p">(</span><span class="s2">&#34;normal! v&#34;</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.selection_range</span><span class="p">(</span><span class="s2">&#34;outer&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="kr">end</span><span class="p">,</span> <span class="p">{</span> <span class="n">desc</span> <span class="o">=</span> <span class="s2">&#34;Start incremental selection&#34;</span> <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</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="s2">&#34;x&#34;</span><span class="p">,</span> <span class="s2">&#34;&lt;c-s&gt;&#34;</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.selection_range</span><span class="p">(</span><span class="s2">&#34;outer&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="kr">end</span><span class="p">,</span> <span class="p">{</span> <span class="n">desc</span> <span class="o">=</span> <span class="s2">&#34;Expand to scope&#34;</span> <span class="p">})</span>
</span></span></code></pre></div><h2 id="neotest">Neotest</h2>
<p>I thought that would be enough, but I noticed in my <code>~/.local/state/nvim/neotest.log</code> that I was getting the following error:</p>
<pre tabindex="0"><code>WARN | 2025-11-01T20:10:40Z+0000 | ...eovimPackages/opt/neotest/lua/neotest/lib/subprocess.lua:203 | CHILD | Error in remote call ...Packages/opt/neotest/lua/neotest/lib/treesitter/init.lua:130: attempt to index a nil value
stack traceback:
    ...Packages/opt/neotest/lua/neotest/lib/treesitter/init.lua:130: in function &#39;get__parse_root&#39;
    ...Packages/opt/neotest/lua/neotest/lib/treesitter/init.lua:162: in function &#39;parse_positions_from_string&#39;
    ...Packages/opt/neotest/lua/neotest/lib/treesitter/init.lua:209: in function &#39;func&#39;
    ...eovimPackages/opt/neotest/lua/neotest/lib/subprocess.lua:195: in function &lt;...eovimPackages/opt/neotest/lua/neotest/lib/subprocess.lua:194&gt;
    [C]: in function &#39;xpcall&#39;
    ...eovimPackages/opt/neotest/lua/neotest/lib/subprocess.lua:194: in function &lt;...eovimPackages/opt/neotest/lua/neotest/lib/subprocess.lua:193&gt;
WARN | 2025-11-01T20:10:40Z+0000 | ...eovimPackages/opt/neotest/lua/neotest/lib/subprocess.lua:203 | CHILD | Error in remote call ...Packages/opt/neotest/lua/neotest/lib/treesitter/init.lua:130: attempt to index a nil val
</code></pre><p>I found this <a href="https://github.com/nvim-neotest/neotest/issues/552">issue</a> and this <a href="https://github.com/nvim-neotest/neotest/pull/548">fix</a>. Then I updated Neotest to the latest version by again adding it as an input:</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">plugins</span><span class="o">-</span><span class="n">neotest</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">url</span> <span class="o">=</span> <span class="s2">&#34;github:nvim-neotest/neotest&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">flake</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>and</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nix" data-lang="nix"><span class="line"><span class="cl"><span class="n">test</span> <span class="err">=</span> <span class="k">with</span> <span class="n">pkgs</span><span class="o">.</span><span class="n">vimPlugins</span><span class="p">;</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="n">pkgs</span><span class="o">.</span><span class="n">neovimPlugins</span><span class="o">.</span><span class="n">neotest</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span></code></pre></div><h2 id="finally-fixed-">Finally fixed? 🙏</h2>
<p>Then I ran <code>nh home switch</code> (similar to <code>home-manager switch --flake ~/nixicle#haseeb@workstation</code>). I reloaded Neovim, and voila, it works now! That was my day of yak shaving and fixing random broken stuff. 🐐</p>
<p>I guess it goes without saying that if you&rsquo;re running on the bleeding edge, things will break. The advantage is that usually only one thing breaks at a time, whereas with a major upgrade, multiple things might break, and you have to fix them all at once.</p>
<p>Also, this <a href="https://www.youtube.com/watch?v=CrJUhtHdGQ8">classic video</a> is a must-watch!!!! 🤣</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
