Skip to content

Interrupt Handlers

maxlandon edited this page Jan 4, 2023 · 5 revisions

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 a Ctrl-D keystroke.
  • console.ErrCtrlC when receiving a Ctrl-C keystroke.

Writing the handler

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 be 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("")
}

Binding to the menu

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)
}
Clone this wiki locally