diff --git a/filter/command.go b/filter/command.go index ba8e293..80c2331 100644 --- a/filter/command.go +++ b/filter/command.go @@ -46,7 +46,7 @@ func (o Options) Run() error { m := tm.(model) if m.aborted { - os.Exit(exit.Aborted) + return exit.ErrAborted } if len(m.matches) > m.selected && m.selected >= 0 { fmt.Println(m.matches[m.selected].Str) diff --git a/input/command.go b/input/command.go index fc25a1f..c487910 100644 --- a/input/command.go +++ b/input/command.go @@ -42,7 +42,7 @@ func (o Options) Run() error { m := tm.(model) if m.aborted { - os.Exit(exit.Aborted) + return exit.ErrAborted } fmt.Println(m.textinput.Value()) diff --git a/internal/exit/exit.go b/internal/exit/exit.go index 2001bf3..ff3a2b9 100644 --- a/internal/exit/exit.go +++ b/internal/exit/exit.go @@ -1,4 +1,9 @@ package exit -// Aborted is the exit code for aborted commands. -const Aborted = 130 +import "fmt" + +// StatusAborted is the exit code for aborted commands. +const StatusAborted = 130 + +// ErrAborted is the error to return when a gum command is aborted by Ctrl + C. +var ErrAborted = fmt.Errorf("aborted") diff --git a/main.go b/main.go index d2b3744..a63ba8b 100644 --- a/main.go +++ b/main.go @@ -1,11 +1,13 @@ package main import ( + "errors" "fmt" "os" "runtime/debug" "github.com/alecthomas/kong" + "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/lipgloss" "github.com/muesli/termenv" ) @@ -56,6 +58,9 @@ func main() { }, ) if err := ctx.Run(); err != nil { + if errors.Is(err, exit.ErrAborted) { + os.Exit(exit.StatusAborted) + } fmt.Println(err) os.Exit(1) } diff --git a/spin/command.go b/spin/command.go index 5643c6b..c5e727c 100644 --- a/spin/command.go +++ b/spin/command.go @@ -7,6 +7,7 @@ import ( "github.com/alecthomas/kong" "github.com/charmbracelet/bubbles/spinner" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/style" ) @@ -33,8 +34,11 @@ func (o Options) Run() error { fmt.Print(m.output) } - os.Exit(m.status) + if m.aborted { + return exit.ErrAborted + } + os.Exit(m.status) return nil } diff --git a/spin/spin.go b/spin/spin.go index ff308ae..7e49eb9 100644 --- a/spin/spin.go +++ b/spin/spin.go @@ -26,6 +26,7 @@ type model struct { spinner spinner.Model title string command []string + aborted bool status int output string @@ -76,6 +77,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.KeyMsg: switch msg.String() { case "ctrl+c": + m.aborted = true return m, tea.Quit } } diff --git a/write/command.go b/write/command.go index c7244a5..08f9d08 100644 --- a/write/command.go +++ b/write/command.go @@ -7,6 +7,7 @@ import ( "github.com/alecthomas/kong" "github.com/charmbracelet/bubbles/textarea" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/gum/style" ) @@ -45,8 +46,13 @@ func (o Options) Run() error { a.SetValue(o.Value) p := tea.NewProgram(model{textarea: a}, tea.WithOutput(os.Stderr)) - m, err := p.StartReturningModel() - fmt.Println(m.(model).textarea.Value()) + tm, err := p.StartReturningModel() + m := tm.(model) + if m.aborted { + return exit.ErrAborted + } + + fmt.Println(m.textarea.Value()) return err } diff --git a/write/write.go b/write/write.go index 41d06d8..b756542 100644 --- a/write/write.go +++ b/write/write.go @@ -14,6 +14,7 @@ import ( ) type model struct { + aborted bool quitting bool textarea textarea.Model } @@ -29,7 +30,10 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch msg.Type { - case tea.KeyEscape, tea.KeyCtrlC, tea.KeyCtrlD: + case tea.KeyCtrlC: + m.aborted = true + fallthrough + case tea.KeyEscape, tea.KeyCtrlD: m.quitting = true return m, tea.Quit }