Files
pybug/ui/update.go
2026-03-29 17:15:20 +02:00

105 lines
2.4 KiB
Go

package ui
import (
"log/slog"
"strings"
"git.pablu.de/pablu/pybug/ui/codeviewer"
tea "github.com/charmbracelet/bubbletea"
)
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
updatedCv, cmd := m.codeViewer.Update(msg)
m.codeViewer = updatedCv.(codeviewer.CodeViewer)
switch msg := msg.(type) {
case tea.KeyMsg:
return m.HandleKeyMsg(msg)
case tea.WindowSizeMsg:
return m.UpdateWindowSize(msg)
case StdoutMsg:
m.messages = append(m.messages, string(msg))
m.stdoutOutput.SetContent(strings.Join(m.messages, ""))
m.stdoutOutput.GotoBottom()
return m, ListenBridge(m.listenBridge)
case codeviewer.ExecutionStoppedMsg:
return m, tea.Batch(ListenBridgeExecutionsStopped(m.listenBridgeExecutionsStopped), m.GetLocals())
case LocalsMsg:
m.currLocals = map[string]any(msg)
m.localsViewer.SetContent(strings.Join(flattenDict(m.currLocals, 0), "\n"))
}
return m, cmd
}
func (m Model) GetLocals() tea.Cmd {
return func() tea.Msg {
vars, err := m.bridge.Locals()
if err != nil {
slog.Error("couldnt get vars", "error", err)
return nil
}
return LocalsMsg(vars)
}
}
func (m Model) UpdateWindowSize(msg tea.WindowSizeMsg) (tea.Model, tea.Cmd) {
m.width = msg.Width
m.height = msg.Height
editorHeight := msg.Height * 70 / 100
outputHeight := msg.Height - editorHeight - 4
m.codeViewer.Width = msg.Width
m.codeViewer.Height = editorHeight - 2
m.stdoutOutput.Width = msg.Width / 2
m.stdoutOutput.Height = outputHeight
m.localsViewer.Width = msg.Width / 2
m.localsViewer.Height = outputHeight
m.stdoutOutput.SetContent(strings.Join(m.messages, ""))
return m, nil
}
func (m Model) HandleKeyMsg(key tea.KeyMsg) (tea.Model, tea.Cmd) {
switch key.String() {
case "q", "ctrl+c":
return m, tea.Quit
case "b":
lineNumber := m.codeViewer.Cursor + 1
m.bridge.Breakpoint(m.currentFile, lineNumber)
if file, ok := m.breakpoints[m.currentFile]; ok {
m.breakpoints[m.currentFile] = append(file, lineNumber)
} else {
m.breakpoints[m.currentFile] = []int{
lineNumber,
}
}
return m, func() tea.Msg {
// check if this is in currently viewed file
return codeviewer.BreakpointMsg{
Added: true,
Line: lineNumber,
}
}
case "s":
m.bridge.Step()
case "c":
m.bridge.Continue()
case "r":
m.messages = make([]string, 0)
m.stdoutOutput.SetContent("")
err := m.bridge.Start()
if err != nil {
slog.Error("could not start brige", "error", err)
}
}
return m, nil
}