<rss version="2.0">
  <channel>
    <title>~ptrckd</title>
    <link>https://www.ptrckd.com</link>
    <description>~ptrckd - Blog</description>
    <generator>Zine -- https://zine-ssg.io</generator>
    <language>en-US</language>
    <lastBuildDate>Tue, 25 Aug 2026 05:48:53 +0000</lastBuildDate>
    
      <item>
        <title>nvim &lt;-----&gt; term</title>
        <description>&lt;h1&gt;nvim &lt;——&gt; term&lt;/h1&gt;&lt;p&gt;I’m a bit of a tinkerer when it comes to tools that I’ve used consistently throughout the years. Recently I thought it might be &lt;em&gt;fun&lt;/em&gt; to use nvim as my default terminal environment. Fairly quickly I ran into instances where some tools I use would invoke &lt;code&gt;$EDITOR&lt;/code&gt; or I’d try to run nvim while already inside nvim and this would result in a nested nvim instance. Not a big deal but it did feel like a scuff mark on my &lt;a href=&quot;https://martinsos.com/posts/may-recommend-emacs-home-base&quot;&gt;fortress of solitude&lt;/a&gt;. I was aware that git plugins I’ve used somehow manage to handle this gracefully so I decided to have a closer look.&lt;/p&gt;&lt;h1&gt;How it’s done - mini.git&lt;/h1&gt;&lt;p&gt;The &lt;a href=&quot;https://echasnovski.com/&quot;&gt;author&lt;/a&gt; of the &lt;a href=&quot;https://nvim-mini.org/mini.nvim/&quot;&gt;&lt;code&gt;mini.nvim&lt;/code&gt;&lt;/a&gt; plugins is an nvim team member and prolific plugin creator so I was very interested in their approach. &lt;a href=&quot;https://nvim-mini.org/mini.nvim/readmes/mini-git.html&quot;&gt;&lt;code&gt;mini.git&lt;/code&gt;&lt;/a&gt; creates a Lua script that will fire an RPC request back to the nvim instance that created the script. This request calls a Lua function with arguments indicating the file to edit and the socket of the nvim instance that sent the request.&lt;/p&gt;&lt;pre&gt;
  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;-spell&quot;&gt;-- Start editing file from first argument (as how `GIT_EDITOR` works) in&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;-spell&quot;&gt;-- current instance and don&apos;t close until explicitly closed later from this&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;-spell&quot;&gt;-- instance as set up in `MiniGit._edit()`&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Red&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;Aqua&quot;&gt;&apos;lua &amp;lt;&amp;lt; EOF&apos;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Special&quot;&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;format&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Aqua&quot;&gt;&apos;local channel = vim.fn.sockconnect(&amp;quot;pipe&amp;quot;, %s, { rpc = true })&apos;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;inspect&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;v&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;servername&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;Aqua&quot;&gt;&apos;local ins = vim.inspect&apos;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;Aqua&quot;&gt;&apos;local lua_cmd = string.format(&amp;quot;MiniGit._edit(%s, %s)&amp;quot;, ins(vim.fn.argv(0)), ins(vim.v.servername))&apos;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;Aqua&quot;&gt;&apos;vim.rpcrequest(channel, &amp;quot;nvim_exec_lua&amp;quot;, lua_cmd, {})&apos;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;Aqua&quot;&gt;&apos;EOF&apos;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;writefile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;H&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;git_editor_config&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;The script is invoked by setting the &lt;code&gt;GIT_EDITOR&lt;/code&gt; variable to start an nvim instance that runs without a UI and only loads the aforementioned script.&lt;/p&gt;&lt;pre&gt;
  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;-spell&quot;&gt;-- NOTE: use `vim.v.progpath` to have same runtime&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Red&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;editor&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;H&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;cli_escape&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;v&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;progpath&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;Aqua&quot;&gt;&apos; --clean --headless -u &apos;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;H&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;cli_escape&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;H&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;git_editor_config&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;The requested function will then open the requested file in a new buffer and register a cleanup function using the magic of autocommands. Once the relevant event is fired the cleanup function will instruct the nvim instance that made the request to &lt;code&gt;qa!&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;
  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;-spell&quot;&gt;-- Create a private function responsible for editing Git file&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Fg&quot;&gt;MiniGit&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;_edit&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Red&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;path&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;servername&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;-spell&quot;&gt;-- Define editor state before and after editing path&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;H&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;skip_timeout&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;H&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;skip_sync&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Purple&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Purple&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;Red&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Green&quot;&gt;cleanup&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Red&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;Red&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;channel&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Green&quot;&gt;&lt;span class=&quot;Green&quot;&gt;pcall&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;sockconnect&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Aqua&quot;&gt;&apos;pipe&apos;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;servername&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;{&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;rpc&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Purple&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Green&quot;&gt;&lt;span class=&quot;Green&quot;&gt;pcall&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;rpcnotify&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Aqua&quot;&gt;&apos;nvim_exec2&apos;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Aqua&quot;&gt;&apos;quitall!&apos;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;H&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;skip_timeout&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;H&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;skip_sync&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Purple&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Purple&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;Red&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;-spell&quot;&gt;-- Start file edit with proper modifiers in a special window&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;Fg&quot;&gt;mods&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;H&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;ensure_mods_is_split&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;mods&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;cmd&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;mods&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;Aqua&quot;&gt;&apos; split &apos;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;fnameescape&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;H&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;define_minigit_window&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;cleanup&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;Red&quot;&gt;end&lt;/span&gt;

&lt;/pre&gt;
&lt;p&gt;This causes the &lt;code&gt;$GIT_EDITOR&lt;/code&gt; to exit with code &lt;code&gt;0&lt;/code&gt; and everyone is happy. This approach &lt;em&gt;feels&lt;/em&gt; a bit funny but I guess the alternative would be implementing your own server that speaks &lt;a href=&quot;https://msgpack.org/index.html&quot;&gt;MessagePack&lt;/a&gt;, runs everywhere nvim does, and wiring up the &lt;a href=&quot;https://neovim.io/doc/user/api/#api-rpc&quot;&gt;nvim RPC API&lt;/a&gt; which is slightly not spec compliant. So… I guess this approach actually makes a lot of sense.&lt;/p&gt;&lt;h2&gt;So now what?&lt;/h2&gt;&lt;p&gt;While I originally just wanted to avoid nested nvim instances, this gave me some other ideas related to having “&lt;a href=&quot;https://www.chiply.dev/post-icr-primer&quot;&gt;completion as a substrate&lt;/a&gt;”. Would it be enjoyable to make use of a tool like &lt;a href=&quot;https://nvim-mini.org/mini.nvim/readmes/mini-pick.html&quot;&gt;&lt;code&gt;mini.pick&lt;/code&gt;&lt;/a&gt; to search through my shell history? Let’s wire it up and see what happens.&lt;/p&gt;&lt;p&gt;There’s just a few extra bits of knowledge we need to make this work:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;We can (ab)use fish shell’s &lt;a href=&quot;https://fishshell.com/docs/current/language.html#command-lookup&quot;&gt;command lookup&lt;/a&gt; to register fish functions that will take precedence over everything else in &lt;code&gt;$PATH&lt;/code&gt;. Useful when you want to change the behaviour of a command if you detect that you are running from within nvim.&lt;/li&gt;&lt;li&gt;The nvim terminal environment sets its &lt;code&gt;servername&lt;/code&gt; in the &lt;code&gt;$NVIM&lt;/code&gt; environment variable.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;So with a little bit of plumbing we can connect fish&lt;/p&gt;&lt;pre&gt;
&lt;span class=&quot;Keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;Normal&quot;&gt;hh&lt;/span&gt;
&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;Normal&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;Operator&quot;&gt;$NVIM&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;Function&quot;&gt;nvim&lt;/span&gt; &lt;span class=&quot;Normal&quot;&gt;--clean&lt;/span&gt; &lt;span class=&quot;Normal&quot;&gt;--headless&lt;/span&gt; &lt;span class=&quot;Normal&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;Operator&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;Normal&quot;&gt;/.local/bin/command.lua&lt;/span&gt; &lt;span class=&quot;Operator&quot;&gt;$NVIM&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&amp;quot;history&amp;quot;&lt;/span&gt; &lt;span class=&quot;Delimiter&quot;&gt;&amp;amp;&lt;/span&gt;
&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;to an nvim instance that exists only to send a single RPC request&lt;/p&gt;&lt;pre&gt;
&lt;span class=&quot;Red&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;pipe&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;argv&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Purple&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;Red&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;argv&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Purple&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;Red&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;channel&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;fn&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;sockconnect&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Aqua&quot;&gt;&amp;quot;pipe&amp;quot;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;{&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;rpc&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Purple&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;Red&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;Aqua&quot;&gt;&amp;quot;history&amp;quot;&lt;/span&gt; &lt;span class=&quot;Red&quot;&gt;then&lt;/span&gt;
&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;rpcrequest&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Aqua&quot;&gt;&amp;quot;nvim_exec2&amp;quot;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Aqua&quot;&gt;&amp;quot;History&amp;quot;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;Red&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;cmd&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Aqua&quot;&gt;&apos;&lt;span class=&quot;Red&quot;&gt;qall&lt;/span&gt;&lt;span class=&quot;Blue&quot;&gt;!&lt;/span&gt;&apos;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;that will invoke &lt;code&gt;mini.pick&lt;/code&gt; with our shell history and print our selection back to the terminal.&lt;/p&gt;&lt;pre&gt;
&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;M&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;history&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Red&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;command_args&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;pick&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;builtin&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;cli&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;{&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;command&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;{&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Aqua&quot;&gt;&apos;fish&apos;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Aqua&quot;&gt;&apos;-c&apos;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Aqua&quot;&gt;&apos;history&apos;&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;{&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;source&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;{&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;choose&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;H&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;print_to_term&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;Red&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;M&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;setup&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Orange&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Red&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;opts&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;Whitespace&quot;&gt;»       &lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;api&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;&lt;span class=&quot;Green&quot;&gt;nvim_create_user_command&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Aqua&quot;&gt;&amp;quot;History&amp;quot;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;M&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Blue&quot;&gt;history&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Grey&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;&lt;span class=&quot;Fg&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Fg&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;Red&quot;&gt;end&lt;/span&gt;

&lt;/pre&gt;
&lt;p&gt;The result is actually pretty nice.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://www.ptrckd.com/blog/nvim-term/nvim-history.png&quot;&gt;&lt;/p&gt;&lt;h3&gt;Note!&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;I did end up solving my original problem but that felt less interesting to include.&lt;/li&gt;&lt;li&gt;I’ve omitted a chunk of boring code for brevity. Maybe someday I’ll push up the repo when I’m happy with it.&lt;/li&gt;&lt;li&gt;Note the usage of &lt;code&gt;command&lt;/code&gt; in my fish function. That one can be important to avoid potential infinite loops… Which I may have learnt first hand.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;What else could I have done?&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;&gt; Just use terminal mode bindings!&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I use space as my &lt;code&gt;&amp;lt;leader&amp;gt;&lt;/code&gt; key. Having that be part of my terminal bindings causes annoying stutter when I’m typing.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&gt; Just escape to normal mode and use your existing bindings!&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Is that fun?&lt;/p&gt;&lt;p&gt;There is some tension between moving more shell into nvim instead of bringing nvim into the shell. Let’s see where this takes us.&lt;/p&gt;&lt;p&gt;Happy hacking, &lt;br&gt; ptrckd&lt;/p&gt;</description>
        <link>https://www.ptrckd.com/blog/nvim-term/</link>
        <pubDate>Thu, 13 Aug 2026 00:00:00 +0000</pubDate>
        <guid>https://www.ptrckd.com/blog/nvim-term/</guid>
      </item>
    
  </channel>
</rss>
