Web presence of Neil O'Toole.


shelleditor is a tiny package I’ve put together to call out to the system editor from within a Go CLI. Like most everybody in the Kubernetes ecosystem, I spend a lot of time with the kubectl CLI, and more time than I’d like doing kubectl edit X, to directly edit k8s config for debugging.

Recently, I’ve been working on a complete overhaul of sq’s config mechanism. I may have gone a little overboard.

sq is highly configurable, via flags, via its config file, and via sq config set.

However, when making changes to a sq source, who can remember all the flags? Yes, there’s shell completion for those flags, but there’s a lot of flags. Wouldn’t it be easier to be able to see all the available flags in front of you, and edit them as desired? Kinda like what kubectl edit does?

Enter sq config edit:

sq config edit

That idea’s inception led down a deep rabbit hole, worthy of its own post. But for the purposes of this post, I had an immediate problem to solve: how to call out to the system editor, e.g. vi. I found a standalone package, tj/go-editor, but it didn’t seem to be actively maintained, and anyhow, I was curious to see how kubectl did it. After eventually figuring out how to navigate the Kubernetes source code, I decided I may as well just lift the kubectl edit implementation from them. Alas, a simple import pulled in an ungodly amount of Kubernetes dependencies. So, I extracted the essentials, and the shelleditor package was born.

Usage is simple. Lifted from the example CLI:

package main

import (


func main() {
	if len(os.Args) != 2 {
		fmt.Fprintln(os.Stderr, "Usage: shelleditor PATH")

	ed := shelleditor.NewDefaultEditor("EDITOR")
	if err := ed.Launch(os.Args[1]); err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)

In the program above, the editor implementation to use is controlled via the EDITOR envar. E.g.

# From project root
$ go install ./cmd/shelleditor
$ EDITOR=vim shelleditor hello.txt