TUI view management and input handling cleanup
This commit is contained in:
@@ -11,17 +11,17 @@ import (
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
func (m *Model) HandleInput(msg tea.KeyMsg) (bool, tea.Cmd) {
|
||||
func (m *Model) handleInput(msg tea.KeyMsg) tea.Cmd {
|
||||
switch m.focus {
|
||||
case focusInput:
|
||||
consumed, cmd := m.handleInputKey(msg)
|
||||
if consumed {
|
||||
return true, cmd
|
||||
cmd := m.handleInputKey(msg)
|
||||
if cmd != nil {
|
||||
return cmd
|
||||
}
|
||||
case focusMessages:
|
||||
consumed, cmd := m.handleMessagesKey(msg)
|
||||
if consumed {
|
||||
return true, cmd
|
||||
cmd := m.handleMessagesKey(msg)
|
||||
if cmd != nil {
|
||||
return cmd
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,51 +29,51 @@ func (m *Model) HandleInput(msg tea.KeyMsg) (bool, tea.Cmd) {
|
||||
case "esc":
|
||||
if m.state == pendingResponse {
|
||||
m.stopSignal <- struct{}{}
|
||||
return true, nil
|
||||
return shared.KeyHandled(msg)
|
||||
}
|
||||
return true, func() tea.Msg {
|
||||
return shared.MsgViewChange(shared.StateConversations)
|
||||
return func() tea.Msg {
|
||||
return shared.MsgViewChange(shared.ViewConversations)
|
||||
}
|
||||
case "ctrl+c":
|
||||
if m.state == pendingResponse {
|
||||
m.stopSignal <- struct{}{}
|
||||
return true, nil
|
||||
return shared.KeyHandled(msg)
|
||||
}
|
||||
case "ctrl+p":
|
||||
m.persistence = !m.persistence
|
||||
return true, nil
|
||||
return shared.KeyHandled(msg)
|
||||
case "ctrl+t":
|
||||
m.showToolResults = !m.showToolResults
|
||||
m.rebuildMessageCache()
|
||||
m.updateContent()
|
||||
return true, nil
|
||||
return shared.KeyHandled(msg)
|
||||
case "ctrl+w":
|
||||
m.wrap = !m.wrap
|
||||
m.rebuildMessageCache()
|
||||
m.updateContent()
|
||||
return true, nil
|
||||
return shared.KeyHandled(msg)
|
||||
}
|
||||
return false, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleMessagesKey handles input when the messages pane is focused
|
||||
func (m *Model) handleMessagesKey(msg tea.KeyMsg) (bool, tea.Cmd) {
|
||||
func (m *Model) handleMessagesKey(msg tea.KeyMsg) tea.Cmd {
|
||||
switch msg.String() {
|
||||
case "tab", "enter":
|
||||
m.focus = focusInput
|
||||
m.updateContent()
|
||||
m.input.Focus()
|
||||
return true, nil
|
||||
return shared.KeyHandled(msg)
|
||||
case "e":
|
||||
if m.selectedMessage < len(m.App.Messages) {
|
||||
m.editorTarget = selectedMessage
|
||||
return true, tuiutil.OpenTempfileEditor(
|
||||
return tuiutil.OpenTempfileEditor(
|
||||
"message.*.md",
|
||||
m.App.Messages[m.selectedMessage].Content,
|
||||
"# Edit the message below\n",
|
||||
)
|
||||
}
|
||||
return false, nil
|
||||
return nil
|
||||
case "ctrl+k":
|
||||
if m.selectedMessage > 0 && len(m.App.Messages) == len(m.messageOffsets) {
|
||||
m.selectedMessage--
|
||||
@@ -81,7 +81,7 @@ func (m *Model) handleMessagesKey(msg tea.KeyMsg) (bool, tea.Cmd) {
|
||||
offset := m.messageOffsets[m.selectedMessage]
|
||||
tuiutil.ScrollIntoView(&m.content, offset, m.content.Height/2)
|
||||
}
|
||||
return true, nil
|
||||
return shared.KeyHandled(msg)
|
||||
case "ctrl+j":
|
||||
if m.selectedMessage < len(m.App.Messages)-1 && len(m.App.Messages) == len(m.messageOffsets) {
|
||||
m.selectedMessage++
|
||||
@@ -89,7 +89,7 @@ func (m *Model) handleMessagesKey(msg tea.KeyMsg) (bool, tea.Cmd) {
|
||||
offset := m.messageOffsets[m.selectedMessage]
|
||||
tuiutil.ScrollIntoView(&m.content, offset, m.content.Height/2)
|
||||
}
|
||||
return true, nil
|
||||
return shared.KeyHandled(msg)
|
||||
case "ctrl+h", "ctrl+l":
|
||||
dir := model.CyclePrev
|
||||
if msg.String() == "ctrl+l" {
|
||||
@@ -102,8 +102,7 @@ func (m *Model) handleMessagesKey(msg tea.KeyMsg) (bool, tea.Cmd) {
|
||||
} else if m.selectedMessage > 0 {
|
||||
cmd = m.cycleSelectedReply(&m.App.Messages[m.selectedMessage-1], dir)
|
||||
}
|
||||
|
||||
return cmd != nil, cmd
|
||||
return cmd
|
||||
case "ctrl+r":
|
||||
// resubmit the conversation with all messages up until and including the selected message
|
||||
if m.state == idle && m.selectedMessage < len(m.App.Messages) {
|
||||
@@ -112,14 +111,14 @@ func (m *Model) handleMessagesKey(msg tea.KeyMsg) (bool, tea.Cmd) {
|
||||
cmd := m.promptLLM()
|
||||
m.updateContent()
|
||||
m.content.GotoBottom()
|
||||
return true, cmd
|
||||
return cmd
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleInputKey handles input when the input textarea is focused
|
||||
func (m *Model) handleInputKey(msg tea.KeyMsg) (bool, tea.Cmd) {
|
||||
func (m *Model) handleInputKey(msg tea.KeyMsg) tea.Cmd {
|
||||
switch msg.String() {
|
||||
case "esc":
|
||||
m.focus = focusMessages
|
||||
@@ -132,20 +131,20 @@ func (m *Model) handleInputKey(msg tea.KeyMsg) (bool, tea.Cmd) {
|
||||
}
|
||||
m.updateContent()
|
||||
m.input.Blur()
|
||||
return true, nil
|
||||
return shared.KeyHandled(msg)
|
||||
case "ctrl+s":
|
||||
// TODO: call a "handleSend" function which returns a tea.Cmd
|
||||
if m.state != idle {
|
||||
return false, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
input := strings.TrimSpace(m.input.Value())
|
||||
if input == "" {
|
||||
return true, nil
|
||||
return shared.KeyHandled(msg)
|
||||
}
|
||||
|
||||
if len(m.App.Messages) > 0 && m.App.Messages[len(m.App.Messages)-1].Role == api.MessageRoleUser {
|
||||
return true, shared.WrapError(fmt.Errorf("Can't reply to a user message"))
|
||||
return shared.WrapError(fmt.Errorf("Can't reply to a user message"))
|
||||
}
|
||||
|
||||
m.addMessage(api.Message{
|
||||
@@ -164,11 +163,11 @@ func (m *Model) handleInputKey(msg tea.KeyMsg) (bool, tea.Cmd) {
|
||||
|
||||
m.updateContent()
|
||||
m.content.GotoBottom()
|
||||
return true, tea.Batch(cmds...)
|
||||
return tea.Batch(cmds...)
|
||||
case "ctrl+e":
|
||||
cmd := tuiutil.OpenTempfileEditor("message.*.md", m.input.Value(), "# Edit your input below\n")
|
||||
m.editorTarget = input
|
||||
return true, cmd
|
||||
return cmd
|
||||
}
|
||||
return false, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user