func (sh *Shell) launchEditor(fpath string) (bool, error) {
	fi, err := os.Stat(fpath)
	if err != nil {
		return false, err
	}
	dt1 := fi.ModTime()  
	cmd := exec.Command(sh.editorName, fpath)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Start()
	if err != nil {
		return false, err
	}
	err = cmd.Wait()
	if err != nil {
		return false, err
	}
	fi, err = os.Stat(fpath)
	if err != nil {
		return false, err
	}
	dt2 := fi.ModTime()  
	if !dt1.Before(dt2) {
		return false, nil
	}
	f, err := os.Open(fpath)
	defer f.Close()
	if err != nil {
		return false, err
	}
	b, err := ioutil.ReadAll(f)
	if err != nil {
		return false, err
	}
	sh.input = string(b)
	return true, nil
}
Launch external editor such as nano, vim or subl
package main
import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"
	"github.com/johnwilson/bytengine/client"
	"github.com/peterh/liner"
	"github.com/robertkrimen/otto"
)
type stateFn func(*Shell) stateFn
const (
	OpenBQLEditor        string = "\\e"
	OpenJavascriptEditor string = "\\es"
	RunJavascript        string = "\\s"
	Quit                 string = "\\q"
)
type Shell struct {
	historyFile   string
	editorFileBQL string
	editorFileJS  string
	BEClient      *client.Client
	state         stateFn
	line          *liner.State
	jsengine      *otto.Otto  
	input         string
	lastresult    string  
	editorName    string
}
func (sh *Shell) write(msg string) {
	fmt.Println(msg)
}
func (sh *Shell) writeError(e error) {
	fmt.Printf("error: %s\n", e)
}