// command_input.go implements a vim-style command input overlay. Opened // with the command_mode keybind (:), it accepts commands like :q, :quit, // and :logout. Unknown commands are silently ignored. package chat import ( "github.com/ayn2op/tview" "github.com/ayn2op/tview/keybind" "github.com/ayn2op/tview/layers" ) const commandInputLayerName = "commandInput" type commandInput struct { *tview.InputField chatView *Model } func newCommandInput(chatView *Model) *commandInput { ci := &commandInput{ InputField: tview.NewInputField(), chatView: chatView, } ci.SetLabel(":") ci.SetFieldWidth(0) return ci } func (ci *commandInput) HandleEvent(event tview.Event) tview.Command { switch event := event.(type) { case *tview.KeyEvent: switch { case keybind.Matches(event, keybind.NewKeybind(keybind.WithKeys("enter"))): text := ci.GetText() ci.SetText("") ci.chatView.closeCommandInput() return ci.execute(text) case keybind.Matches(event, keybind.NewKeybind(keybind.WithKeys("esc"))): ci.SetText("") ci.chatView.closeCommandInput() return nil } } return ci.InputField.HandleEvent(event) } func (ci *commandInput) execute(cmd string) tview.Command { switch cmd { case "q", "quit": return func() tview.Event { return &QuitEvent{} } case "logout": return tview.Batch(ci.chatView.closeState(), ci.chatView.logout()) default: return nil } } func (m *Model) openCommandInput() { m.AddLayer( m.commandInput, layers.WithName(commandInputLayerName), layers.WithResize(true), layers.WithVisible(true), layers.WithOverlay(), ).SendToFront(commandInputLayerName) m.app.SetFocus(m.commandInput) } func (m *Model) closeCommandInput() { m.RemoveLayer(commandInputLayerName) }