-
Notifications
You must be signed in to change notification settings - Fork 6
Interrupt Handlers
Continuing with our example application with two different menus (main and client),
here we show how you can bind special interrupt handlers to each menu. In our current
example, and as seen in various cases, sometimes one needs to exit a current context
(here a menu) without exiting the entire application, with CtrlC
/CtrlD
.
Those handlers, currently, can only be bound to errors that are returned by the underlying readline shell. The latter returns:
-
io.EOF
error when receiving aCtrl-D
keystroke. -
console.ErrCtrlC
when receiving aCtrl-C
keystroke.
In addition, the console will return handle the following os.Signal
s even when
a command is being executed (they are being wrapped into an error for matching):
errors.New(syscall.SIGINT.String())
errors.New(syscall.SIGTERM.String())
errors.New(syscall.SIGQUIT.String())
The following shows two different handlers.
The first is used in the main menu, to exit the application.
// exitCtrlD is a custom interrupt handler to use when the shell
// readline receives an io.EOF error, which is returned with CtrlD.
func exitCtrlD(c *console.Console) {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Confirm exit (Y/y): ")
text, _ := reader.ReadString('\n')
answer := strings.TrimSpace(text)
if (answer == "Y") || (answer == "y") {
os.Exit(0)
}
}
The second is used in our client
menu, and which will switch back to the main menu.
func switchMenu(c *console.Console) {
fmt.Println("Switching to main menu")
c.SwitchMenu("")
}
We can bind both of our handlers like this:
import (
"io"
"github.com/reeflective/console"
)
func main() {
app := console.New()
// Main menu interrupts
menu := app.CurrentMenu()
menu.AddInterrupt(io.EOF, exitCtrlD)
// Client menu interrupts
clientMenu := console.Menu("client")
clientMenu.AddInterrupt(console.ErrCtrlC, switchMenu)
}