command_input.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // command_input.go implements a vim-style command input overlay. Opened
  2. // with the command_mode keybind (:), it accepts commands like :q, :quit,
  3. // and :logout. Unknown commands are silently ignored.
  4. package chat
  5. import (
  6. "github.com/ayn2op/tview"
  7. "github.com/ayn2op/tview/keybind"
  8. "github.com/ayn2op/tview/layers"
  9. )
  10. const commandInputLayerName = "commandInput"
  11. type commandInput struct {
  12. *tview.InputField
  13. chatView *Model
  14. }
  15. func newCommandInput(chatView *Model) *commandInput {
  16. ci := &commandInput{
  17. InputField: tview.NewInputField(),
  18. chatView: chatView,
  19. }
  20. ci.SetLabel(":")
  21. ci.SetFieldWidth(0)
  22. return ci
  23. }
  24. func (ci *commandInput) HandleEvent(event tview.Event) tview.Command {
  25. switch event := event.(type) {
  26. case *tview.KeyEvent:
  27. switch {
  28. case keybind.Matches(event, keybind.NewKeybind(keybind.WithKeys("enter"))):
  29. text := ci.GetText()
  30. ci.SetText("")
  31. ci.chatView.closeCommandInput()
  32. return ci.execute(text)
  33. case keybind.Matches(event, keybind.NewKeybind(keybind.WithKeys("esc"))):
  34. ci.SetText("")
  35. ci.chatView.closeCommandInput()
  36. return nil
  37. }
  38. }
  39. return ci.InputField.HandleEvent(event)
  40. }
  41. func (ci *commandInput) execute(cmd string) tview.Command {
  42. switch cmd {
  43. case "q", "quit":
  44. return func() tview.Event {
  45. return &QuitEvent{}
  46. }
  47. case "logout":
  48. return tview.Batch(ci.chatView.closeState(), ci.chatView.logout())
  49. default:
  50. return nil
  51. }
  52. }
  53. func (m *Model) openCommandInput() {
  54. m.AddLayer(
  55. m.commandInput,
  56. layers.WithName(commandInputLayerName),
  57. layers.WithResize(true),
  58. layers.WithVisible(true),
  59. layers.WithOverlay(),
  60. ).SendToFront(commandInputLayerName)
  61. m.app.SetFocus(m.commandInput)
  62. }
  63. func (m *Model) closeCommandInput() {
  64. m.RemoveLayer(commandInputLayerName)
  65. }