diff --git a/options.go b/options.go index 51c7789044..37fc41e8d6 100644 --- a/options.go +++ b/options.go @@ -161,3 +161,13 @@ func WithoutJobControl() ProgramOption { p.disableSuspendOnCtrlZ = true } } + +// WithoutGoStandardAbort disables support for sending SIGQUIT +// to the process (and generating a goroutine dump) when +// Ctrl+\ is pressed. By default, Ctrl+\ causes SIGQUIT to be +// emitted, this is a standard Go feature. +func WithoutGoStandardAbort() ProgramOption { + return func(p *Program) { + p.disableGoStandardAbort = true + } +} diff --git a/tea.go b/tea.go index 70cdac1a6c..e46bb337c1 100644 --- a/tea.go +++ b/tea.go @@ -118,6 +118,10 @@ type Program struct { // (suspend process). disableSuspendOnCtrlZ bool + // disableGoStandardAbort removes direct bubbletea support for Ctrl+\ + // (SIGQUIT / goroutine dump). + disableGoStandardAbort bool + // Stores the original reference to stdin for cases where input is not a // TTY on windows and we've automatically opened CONIN$ to receive input. // When the program exits this will be restored. @@ -319,10 +323,21 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) { }() case KeyMsg: - if !p.disableSuspendOnCtrlZ && msg.Type == KeyCtrlZ && !msg.Alt { + if !p.disableSuspendOnCtrlZ && !msg.Alt && msg.Type == KeyCtrlZ { cmds <- Suspend() continue } + if !p.disableGoStandardAbort && !msg.Alt && msg.Type == KeyCtrlBackslash { + cmds <- Exec(fnAsCommand(func() { + pr, err := os.FindProcess(os.Getpid()) + if err != nil { + // No-op. + return + } + _ = pr.Signal(syscall.SIGQUIT) + }), nil) + continue + } case suspendMsg: if canSuspendProcess {