<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>Ensar Sarajčić</title>
      <link>https://www.ensarsarajcic.com</link>
      <description>My personal blog and my open-source projects</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://www.ensarsarajcic.com/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Wed, 24 Jan 2024 14:04:06 +0000</lastBuildDate>
      <item>
          <title>Devcontainer support for Neovim</title>
          <pubDate>Mon, 22 Jan 2024 00:00:00 +0000</pubDate>
          <author>blog@ensarsarajcic.com (Ensar Sarajčić)</author>
          <link>https://www.ensarsarajcic.com/blog/nvim-dev-container-intro/</link>
          <guid>https://www.ensarsarajcic.com/blog/nvim-dev-container-intro/</guid>
          <description xml:base="https://www.ensarsarajcic.com/blog/nvim-dev-container-intro/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;Ever since I started reading blogs, I always wanted to start writing one myself,
but I could not get myself to do it. Reading about &lt;a href=&quot;https:&#x2F;&#x2F;mastermind.dev&#x2F;why-every-developer-should-write&quot;&gt;how it could help me
improve&lt;&#x2F;a&gt; and also
&lt;a href=&quot;https:&#x2F;&#x2F;drewdevault.com&#x2F;make-a-blog.html&quot;&gt;seeing open source developers convincing people write one&lt;&#x2F;a&gt;,
I figured it could at least help me get better at writing, even if
nobody ever reads it.&lt;&#x2F;p&gt;
&lt;p&gt;After making the decision to write a blog post, I had to pick a topic,
so for my first blog post ever and I have decided to write about my open
source project with the most reach so far, my &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&quot;&gt;Neovim plugin for
devcontainers&lt;&#x2F;a&gt;. I have
initially &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;esensar&#x2F;nvim-dev-container&#x2F;&quot;&gt;hosted on GitHub&lt;&#x2F;a&gt;,
but later I have decided it&#x27;s better to host it on a free and open
source platform, like &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&quot;&gt;Codeberg&lt;&#x2F;a&gt; or &lt;a href=&quot;https:&#x2F;&#x2F;sr.ht&quot;&gt;Sourcehut&lt;&#x2F;a&gt;.
I have still left a mirror on GitHub, since that&#x27;s where most of Neovim plugins
are and where most plugin managers expect to find plugins (even though most
of them support other platforms too).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alternatives&quot;&gt;Alternatives&lt;&#x2F;h2&gt;
&lt;p&gt;In 2021, I worked on projects that required me to use containers in my
workflow. Looking at available Neovim plugins, the only one I found was
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jamestthompson3&#x2F;nvim-remote-containers&quot;&gt;nvim-remote-containers&lt;&#x2F;a&gt;,
which did not offer much besides starting containers
defined in &lt;code&gt;devcontainer.json&lt;&#x2F;code&gt; file. Even though I did not really have a need
for such a plugin anymore, I had some extra time and wanted to try building a proper
Neovim plugin (I have made &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;vimwiki-reviews&#x2F;vimwiki-reviews-lua&quot;&gt;a small one before&lt;&#x2F;a&gt;,
but it barely offered any functionality).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-plugin&quot;&gt;The plugin&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;initial-commit&quot;&gt;Initial commit&lt;&#x2F;h3&gt;
&lt;p&gt;Looking back at the &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;commit&#x2F;575feebf8b060fb1a6b93013d404acf05ecf118a&quot;&gt;initial commit&lt;&#x2F;a&gt;,
I guess I just wanted to experiment with idea of embedding Neovim in a container
and connecting to it from current Neovim instance.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;markdown&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-markdown &quot;&gt;&lt;code class=&quot;language-markdown&quot; data-lang=&quot;markdown&quot;&gt;&lt;span&gt;Goal of this plugin is to provide functionality similar to
&lt;&#x2F;span&gt;&lt;span&gt;VSCode&amp;#39;s &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;[remote container development](https:&#x2F;&#x2F;code.visualstudio.com&#x2F;docs&#x2F;remote&#x2F;containers)
&lt;&#x2F;span&gt;&lt;span&gt;plugin and other functionality that enables development in docker container.
&lt;&#x2F;span&gt;&lt;span&gt;This plugin is inspired by &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;[jamestthompson3&#x2F;nvim-remote-containers](https:&#x2F;&#x2F;github.com&#x2F;jamestthompson3&#x2F;nvim-remote-containers)&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;but aims to enable having neovim embedded in docker container.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A lot has changed since then and I have set other goals for the plugin, while
the &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;issues&#x2F;30&quot;&gt;original one isn&#x27;t yet completed the way I wanted it initially&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;first-release&quot;&gt;First release&lt;&#x2F;h3&gt;
&lt;p&gt;Two weeks after the initial commit, I had prepared the &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;releases&#x2F;tag&#x2F;0.1.0&quot;&gt;first release&lt;&#x2F;a&gt;.
It had reached the original goal, but in a hacky way, by attaching to the
container in a terminal buffer and hiding statusline from host Neovim instance,
to make it seem like it&#x27;s connected directly to the Neovim instance in the
container. That made that feature confusing, since it wasn&#x27;t clear that
there&#x27;s an embedded Neovim running, but I hoped that new Neovim release would
make it easy to &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;issues&#x2F;30&quot;&gt;implement my initial idea&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;script async id=&quot;asciicast-W1OybeSGRVd80dN9wlogHO2De&quot; src=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;W1OybeSGRVd80dN9wlogHO2De.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;noscript&gt;&lt;a href=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;W1OybeSGRVd80dN9wlogHO2De&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;asciinema&quot; src=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;W1OybeSGRVd80dN9wlogHO2De.svg&quot;&#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;noscript&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Starting containers defined in .devcontainer.json is probably the only useful feature of the first release&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;next-releases&quot;&gt;Next releases&lt;&#x2F;h3&gt;
&lt;p&gt;Next 2 releases came fast, after I realised that I haven&#x27;t thought the
whole plugin through and that it wasn&#x27;t providing the main features in
an obvious way. I have also realised almost nobody cares about releases
when it comes to Neovim plugins, since most users just use main branch as the target,
so after &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;releases&#x2F;tag&#x2F;0.2.0&quot;&gt;0.2.0&lt;&#x2F;a&gt;
I have stopped versioning the plugin, even though more commits have been made
after that release, than since the initial commit.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;later-updates&quot;&gt;Later updates&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;podman-support&quot;&gt;Podman support&lt;&#x2F;h4&gt;
&lt;p&gt;Shortly after release, there was a request to enable more container tools to be
used (like &lt;a href=&quot;https:&#x2F;&#x2F;podman.io&#x2F;&quot;&gt;Podman&lt;&#x2F;a&gt;). Since I wasn&#x27;t interested in making
the plugin even more complicated by using Engine API, I just &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;pulls&#x2F;81&quot;&gt;patched in support
for &lt;code&gt;podman&lt;&#x2F;code&gt; and &lt;code&gt;podman-compose&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
and that was the moment the plugin started diverging from the idea of mimicking
VSCode&#x27;s plugin.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;commands-changes&quot;&gt;Commands changes&lt;&#x2F;h4&gt;
&lt;p&gt;The initial release offered &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;src&#x2F;commit&#x2F;97622e72652642df41b97914b0d6072ca2af7638&#x2F;README.md#commands&quot;&gt;14 different commands&lt;&#x2F;a&gt;
out of which most would probably never be used (since there were combinations of build,
run and attach sub commands). The latest version offers &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;src&#x2F;commit&#x2F;47927e2df27503debf3bfbfe90afefbac73e002f#commands&quot;&gt;only 8&lt;&#x2F;a&gt;,
but offers more functionality compared to the original 14. This could probably
be further reduced, since some of these are still less used, but at least it&#x27;s
not as confusing as the original set and it offers only a single way of starting
containers (with &lt;code&gt;DevcontainerStart&lt;&#x2F;code&gt;), compared to 5 in the first release.&lt;&#x2F;p&gt;
&lt;p&gt;Use of arguments for &lt;code&gt;DevcontainerAttach&lt;&#x2F;code&gt; and &lt;code&gt;DevcontainerExec&lt;&#x2F;code&gt; made it
possible to run arbitrary commands on running devcontainer (or any other running
container) and also attach to them in an embedded terminal.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;ui&quot;&gt;UI&lt;&#x2F;h4&gt;
&lt;p&gt;Later updates also started using &lt;code&gt;vim.ui&lt;&#x2F;code&gt; to make it more clear what is
happening when certain commands are started (like &lt;code&gt;DevcontainerStart&lt;&#x2F;code&gt;, or when
autocommands are used), which has also helped reduce the number of commands,
since the plugin would now prompt the user if they would like to proceed to the
next step, be it starting or attaching the container.&lt;&#x2F;p&gt;
&lt;script async id=&quot;asciicast-f5MnREoZKScifLz2mPdGPUiYm&quot; src=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;f5MnREoZKScifLz2mPdGPUiYm.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;noscript&gt;&lt;a href=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;f5MnREoZKScifLz2mPdGPUiYm&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;asciinema&quot; src=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;f5MnREoZKScifLz2mPdGPUiYm.svg&quot;&#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;noscript&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The plugin now asks before installing Neovim, since it&#x27;s a long process&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;nvim-dev-container-now&quot;&gt;nvim-dev-container now&lt;&#x2F;h3&gt;
&lt;p&gt;After 2 years of occasional development of the plugin, it now offers:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;support for &lt;code&gt;podman&lt;&#x2F;code&gt;, &lt;code&gt;docker&lt;&#x2F;code&gt;, &lt;code&gt;devcontainer&lt;&#x2F;code&gt; CLI, &lt;code&gt;podman-compose&lt;&#x2F;code&gt;,
&lt;code&gt;docker-compose&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;attaching to any command (defaulting to &lt;code&gt;nvim&lt;&#x2F;code&gt;) and any container (defaulting
to container defined in &lt;code&gt;.devcontainer.json&lt;&#x2F;code&gt;, named &lt;code&gt;devcontainer&lt;&#x2F;code&gt; in the
command)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;lists.sr.ht&#x2F;~esensar&#x2F;nvim-dev-container-discuss&#x2F;%3C825d912d-9da5-467c-a2e9-f3ee5db44122%40app.fastmail.com%3E&quot;&gt;enabling users to manually add support for installing neovim in any container&lt;&#x2F;a&gt;,
by defining commands to run based on which package manager is available in the
container&lt;&#x2F;li&gt;
&lt;li&gt;optional autocommands for starting devcontainers automatically, removing them
when exiting Neovim and restarting then &lt;code&gt;.devcontainer.json&lt;&#x2F;code&gt; is changed&lt;&#x2F;li&gt;
&lt;li&gt;caching images after adding Neovim, since it takes too long to install it&lt;&#x2F;li&gt;
&lt;li&gt;custom mounts and mounting local neovim configuration&lt;&#x2F;li&gt;
&lt;li&gt;small extras, like &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;wiki&#x2F;Recipes#statusbar&quot;&gt;build progress for statusline&lt;&#x2F;a&gt;,
UI prompts for some of the features, &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;src&#x2F;commit&#x2F;0c20c26781ee996c98cf49815ec650ab9f0cdb03&#x2F;doc&#x2F;devcontainer.txt#L1093&quot;&gt;autocommand events&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;script async id=&quot;asciicast-uL5hgnqI9B5bTQRcY14wDZ2UI&quot; src=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;uL5hgnqI9B5bTQRcY14wDZ2UI.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;noscript&gt;&lt;a href=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;uL5hgnqI9B5bTQRcY14wDZ2UI&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;asciinema&quot; src=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;uL5hgnqI9B5bTQRcY14wDZ2UI.svg&quot;&#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;noscript&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Please note that demo above includes &lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;dotfiles&#x2F;src&#x2F;branch&#x2F;main&#x2F;symlinks&#x2F;config&#x2F;nvim&quot;&gt;my full configuration&lt;&#x2F;a&gt;, including plugins for different UI elements. The plugin does not add any UI itself, but it just uses default configured elements.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;future-of-the-plugin&quot;&gt;Future of the plugin&lt;&#x2F;h3&gt;
&lt;p&gt;Ever since I have added &lt;code&gt;podman&lt;&#x2F;code&gt; support to the plugin, I realised that my goal
shouldn&#x27;t be reaching parity with VSCode&#x27;s plugin, but providing utilities that
enable Neovim users easier time when working with containers. Following the spec
of &lt;code&gt;.devcontainer.json&lt;&#x2F;code&gt; as close as possible is still a goal, since it&#x27;s
important when working in teams, considering that different developers may
prefer different tools.&lt;&#x2F;p&gt;
&lt;p&gt;Lately I haven&#x27;t been using the plugin much. It&#x27;s still in my configuration and
it&#x27;s most often used to automatically start containers related to the project when
starting Neovim, but that is pretty much it. That is one of the reasons that I
am not motivated enough to tackle some of the more difficult issues, which have
been around since the first version, like:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;issues&#x2F;20&quot;&gt;integration with LSP&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;issues&#x2F;30&quot;&gt;proper implementation of Neovim remote UI&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;issues&#x2F;66&quot;&gt;netman.nvim integration&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;esensar&#x2F;nvim-dev-container&#x2F;issues&#x2F;94&quot;&gt;integration with DAP&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I hope that you liked my short introduction of this plugin. Give it a try and
let me know your thoughts.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>First Post</title>
          <pubDate>Thu, 29 Oct 2020 00:00:00 +0000</pubDate>
          <author>blog@ensarsarajcic.com (Ensar Sarajčić)</author>
          <link>https://www.ensarsarajcic.com/blog/init/</link>
          <guid>https://www.ensarsarajcic.com/blog/init/</guid>
          <description xml:base="https://www.ensarsarajcic.com/blog/init/">&lt;h1 id=&quot;hello-world&quot;&gt;Hello world&lt;&#x2F;h1&gt;
</description>
      </item>
    </channel>
</rss>
