simplify this

This commit is contained in:
Robin Olsen
2026-03-22 19:09:15 +01:00
parent 84c73b7b94
commit a6d4144d8c

View File

@@ -28,11 +28,10 @@ Type 'status' to check task progress.`
) )
type REPL struct { type REPL struct {
feedbackChan chan ValidationFeedback feedbackChan chan ValidationFeedback
quitChan chan bool quitChan chan bool
submitChan chan<- struct{} submitChan chan<- struct{}
completionChan chan struct{} app *App
app *App
currentFeedback ValidationFeedback currentFeedback ValidationFeedback
exitRequested bool exitRequested bool
@@ -49,7 +48,6 @@ func (r *REPL) Run(ctx context.Context, config app.Config) error {
r.taskCompleted = false r.taskCompleted = false
r.exitRequested = false r.exitRequested = false
r.currentFeedback = ValidationFeedback{} r.currentFeedback = ValidationFeedback{}
r.completionChan = make(chan struct{}, 1)
// Save terminal state to restore on exit // Save terminal state to restore on exit
oldState, err := term.GetState(int(os.Stdin.Fd())) oldState, err := term.GetState(int(os.Stdin.Fd()))
@@ -81,33 +79,23 @@ func (r *REPL) Run(ctx context.Context, config app.Config) error {
go r.watchValidation() go r.watchValidation()
} }
// Goroutine to inject newline when task completes to wake up blocked prompt
go func() {
for range r.completionChan {
if tty, err := os.OpenFile("/dev/tty", os.O_WRONLY, 0); err == nil {
tty.Write([]byte("\n"))
tty.Close()
}
}
}()
// history keeps track of command history. // history keeps track of command history.
var history []string var history []string
// Start the REPL loop // Start the REPL loop
replLoop: replLoop:
for !r.exitRequested { for !r.exitRequested || r.taskCompleted {
// Check if we should exit before prompting (non-blocking check)
if r.exitRequested {
break
}
// Check if task completed before showing prompt // Check if task completed before showing prompt
if r.taskCompleted { if r.taskCompleted {
fmt.Println("\nTask completed successfully!") fmt.Scanln()
break replLoop break replLoop
} }
// Check if we should exit before prompting
if r.exitRequested {
break
}
// Prompt the user for input, and provide suggestions. // Prompt the user for input, and provide suggestions.
input := prompt.Input( input := prompt.Input(
PromptPrefix, PromptPrefix,
@@ -117,12 +105,11 @@ replLoop:
// Check if task completed while at prompt (will be true if newline was injected) // Check if task completed while at prompt (will be true if newline was injected)
if r.taskCompleted { if r.taskCompleted {
fmt.Println("\nTask completed successfully!")
break replLoop break replLoop
} }
// Check again after prompt returns (in case validation completed while waiting) // Check again after prompt returns (in case validation completed while waiting)
if r.exitRequested { if r.exitRequested && !r.taskCompleted {
break break
} }
@@ -185,16 +172,15 @@ func (r *REPL) watchValidation() {
} }
if feedback.Success { if feedback.Success {
r.taskCompleted = true r.taskCompleted = true
if r.completionChan != nil { // Print completion message immediately
select { fmt.Fprintf(os.Stderr, "\n\nTASK COMPLETED\n%s\nPress Enter to exit...\n\n", feedback.Message)
case r.completionChan <- struct{}{}: os.Stderr.Sync()
default:
}
}
return return
} }
case <-r.quitChan: case <-r.quitChan:
r.exitRequested = true if !r.taskCompleted {
r.exitRequested = true
}
return return
} }
} }