Introduction

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 how it could help me improve and also seeing open source developers convincing people write one, I figured it could at least help me get better at writing, even if nobody ever reads it.

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 Neovim plugin for devcontainers. I have initially hosted on GitHub, but later I have decided it's better to host it on a free and open source platform, like Codeberg or Sourcehut. I have still left a mirror on GitHub, since that'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).

Alternatives

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 nvim-remote-containers, which did not offer much besides starting containers defined in devcontainer.json 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 a small one before, but it barely offered any functionality).

The plugin

Initial commit

Looking back at the initial commit, I guess I just wanted to experiment with idea of embedding Neovim in a container and connecting to it from current Neovim instance.

Goal of this plugin is to provide functionality similar to
VSCode's [remote container development](https://code.visualstudio.com/docs/remote/containers)
plugin and other functionality that enables development in docker container.
This plugin is inspired by [jamestthompson3/nvim-remote-containers](https://github.com/jamestthompson3/nvim-remote-containers),
but aims to enable having neovim embedded in docker container.

A lot has changed since then and I have set other goals for the plugin, while the original one isn't yet completed the way I wanted it initially.

First release

Two weeks after the initial commit, I had prepared the first release. 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's connected directly to the Neovim instance in the container. That made that feature confusing, since it wasn't clear that there's an embedded Neovim running, but I hoped that new Neovim release would make it easy to implement my initial idea.

Starting containers defined in .devcontainer.json is probably the only useful feature of the first release

Next releases

Next 2 releases came fast, after I realised that I haven't thought the whole plugin through and that it wasn'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 0.2.0 I have stopped versioning the plugin, even though more commits have been made after that release, than since the initial commit.

Later updates

Podman support

Shortly after release, there was a request to enable more container tools to be used (like Podman). Since I wasn't interested in making the plugin even more complicated by using Engine API, I just patched in support for podman and podman-compose and that was the moment the plugin started diverging from the idea of mimicking VSCode's plugin.

Commands changes

The initial release offered 14 different commands out of which most would probably never be used (since there were combinations of build, run and attach sub commands). The latest version offers only 8, 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's not as confusing as the original set and it offers only a single way of starting containers (with DevcontainerStart), compared to 5 in the first release.

Use of arguments for DevcontainerAttach and DevcontainerExec made it possible to run arbitrary commands on running devcontainer (or any other running container) and also attach to them in an embedded terminal.

UI

Later updates also started using vim.ui to make it more clear what is happening when certain commands are started (like DevcontainerStart, 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.

The plugin now asks before installing Neovim, since it's a long process

nvim-dev-container now

After 2 years of occasional development of the plugin, it now offers:

Please note that demo above includes my full configuration, including plugins for different UI elements. The plugin does not add any UI itself, but it just uses default configured elements.

Future of the plugin

Ever since I have added podman support to the plugin, I realised that my goal shouldn't be reaching parity with VSCode's plugin, but providing utilities that enable Neovim users easier time when working with containers. Following the spec of .devcontainer.json as close as possible is still a goal, since it's important when working in teams, considering that different developers may prefer different tools.

Lately I haven't been using the plugin much. It's still in my configuration and it'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:

I hope that you liked my short introduction of this plugin. Give it a try and let me know your thoughts.