Documentation ¶
Overview ¶
Package editor allows your CLI users to edit arbitrary data in their preferred editor.
It's just like editing messages in "git commit" or resources with "kubectl edit".
Existing File ¶
The most basic usage is to prompt the user to edit an existing file. This may be useful to edit the application configuration or a system file, for example.
edit := editor.NewEditor() err := edit.Launch("/etc/bashrc")
Arbitrary Data ¶
Most of the time, the data you want your user to edit isn't in an local file. In these cases, if you can represent your data in a human editable format (txt, yaml, hcl, json, etc), then go-editor will enable the user to edit it.
Provide any "io.Reader" with the initial contents:
original := bytes.NewBufferString("something to be edited\n") edit := editor.NewEditor() edited, file, err := edit.LaunchTempFile("example", original) defer os.Remove(file) if err != nil { // handle it }
The library leaves it up to you to cleanup the temp file.
This enables your CLI to validate the edited data and prompt the user to continue editing where they left off, rather than starting over. And if that's what you want...
Input Validation ¶
If you would like to validate the edited data, use a ValidatingEditor instead. This will prompt the user to continue editing until validation succeeds or the edit is cancelled.
Simply create a schema and pass it to the editor:
schema := &mySchema{} edit := editor.NewValidatingEditor(schema)
A schema must implement the Schema interface: https://godoc.org/github.com/confluentinc/go-editor#Schema
Example (Basic) ¶
edit := editor.NewEditor() // Simulate user making changes edit.LaunchFn = func(command, file string) error { return os.WriteFile(file, []byte("something else here"), 0777) } contents, file, err := edit.LaunchTempFile("example", bytes.NewBufferString("something to be edited\n")) defer os.Remove(file) if err != nil { fmt.Println("error: " + err.Error()) os.Exit(1) } fmt.Println(string(contents))
Output: something else here
Example (Validating) ¶
package main import ( "bytes" "fmt" "os" "strings" "github.com/confluentinc/go-editor" ) // Example schema that expects a string prefix match type prefixSchema struct { prefix string } func (s *prefixSchema) ValidateBytes(data []byte) error { if !strings.HasPrefix(string(data), s.prefix) { return fmt.Errorf("data missing prefix") } return nil } func main() { schema := &prefixSchema{prefix: "something"} edit := editor.NewValidatingEditor(schema) // Simulate user making changes edit.LaunchFn = func(command, file string) error { return os.WriteFile(file, []byte("something else here"), 0777) } obj := bytes.NewBufferString("something else") contents, file, err := edit.LaunchTempFile("example", obj) defer os.Remove(file) if err != nil { fmt.Println("error: " + err.Error()) os.Exit(1) } fmt.Println(string(contents)) }
Output: something else here
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BasicEditor ¶
type BasicEditor struct { Command string // this is only for testing LaunchFn func(command, file string) error }
BasicEditor launches an editor given by a specific command.
func NewEditor ¶
func NewEditor() *BasicEditor
NewEditor launches an instance of the users preferred editor. The editor to use is determined by reading the $VISUAL and $EDITOR environment variables. If neither of these are present, vim or notepad (on Windows) is used.
func (*BasicEditor) Launch ¶
func (e *BasicEditor) Launch(file string) error
Launch opens the given file path in the external editor or returns an error.
func (*BasicEditor) LaunchTempFile ¶
LaunchTempFile launches the users preferred editor on a temporary file. This file is initialized with contents from the provided stream and named with the given prefix.
Returns the modified data, the path to the temporary file so the caller can clean it up, and an error.
A file may be present even when an error is returned. Please clean it up.
type CancelEditingFn ¶
CancelEditingFn is a function with which you can cancel editing and provide a suitable error message.
type PreserveFileFn ¶
PreserveFileFn is a function with which you can inspect the preserved file, edited data, and resulting error.
type ValidatingEditor ¶
type ValidatingEditor struct { *BasicEditor // Schema is used to validate the edited data. Schema Schema // InvalidFn is called when a Schema fails to validate data. InvalidFn ValidationFailedFn // OriginalUnchangedFn is called when no changes were made from the original data. OriginalUnchangedFn CancelEditingFn // EmptyFileFn is called when the edited data is (effectively) empty; the file doesn't have any uncommented lines (ignoring whitespace) EmptyFileFn CancelEditingFn // PreserveFileFn is called when a non-recoverable error has occurred and the users edits have been preserved in a temp file. PreserveFileFn PreserveFileFn // CommentChars is a list of comment string prefixes for determining "empty" files. Defaults to "#" and "//". CommentChars []string }
ValidatingEditor is an Editor which validates data against a schema. This will prompt the user to continue editing until validation succeeds or the edit is cancelled.
func NewValidatingEditor ¶
func NewValidatingEditor(schema Schema) *ValidatingEditor
NewValidatingEditor returns a new ValidatingEditor.
This extends the BasicEditor with schema validation capabilities.
func (*ValidatingEditor) LaunchTempFile ¶
LaunchTempFile launches the users preferred editor on a temporary file. This file is initialized with contents from the provided stream and named with the given prefix.
Returns the modified data, the path to the temporary file so the caller can clean it up, and an error.
A file may be present even when an error is returned. Please clean it up.
The last byte of "obj" must be a newline to cancel editing if no changes are made. (This is because many editors like vim automatically add a newline when saving.)
type ValidationFailedFn ¶
ValidationFailedFn is a function with which you can handle a validation error.