package editor import ( "context" "errors" "fmt" "log/slog" "runtime/debug" "code.chimeric.al/dwrz/wen/internal/editor/event" ) func (e *Editor) Run(ctx context.Context, files []string) error { ctx, cancel := context.WithCancel(ctx) defer cancel() if err := e.terminal.SetRaw(); err != nil { return fmt.Errorf("failed to set raw mode: %w", err) } e.canvas.Reset() // Log build info. var commit, time string bi, ok := debug.ReadBuildInfo() if ok { for _, s := range bi.Settings { switch s.Key { case "vcs.revision": commit = s.Value case "vcs.time": time = s.Value } } } e.log.Debug( "文 version", slog.String("commit", commit), slog.String("time", time), ) // Reset the terminal before exiting. defer func() { e.canvas.Reset() if err := e.terminal.Reset(); err != nil { e.log.Error( "failed to reset terminal attributes", slog.Any("error", err), ) } }() // Start reading user input. // The reader may be blocked in a read when the editor ends. // The reader stops when the process stops. go func() { if err := e.reader.Run(ctx); err != nil && !errors.Is(err, context.Canceled) { e.events <- event.NewError(err) } }() // Open the files and render the initial state. e.load(files) if err := e.canvas.Render(e.active, e.prompt); err != nil { return fmt.Errorf("failed to render: %w", err) } // Main loop. for { select { case <-ctx.Done(): e.log.DebugContext(ctx, "context done: stopping") return nil case ev := <-e.events: switch t := ev.(type) { case *event.Error: return t case *event.Message: e.prompt.SetText(t.Text()) if err := e.canvas.Render( e.active, e.prompt, ); err != nil { return fmt.Errorf( "failed to render: %w", err, ) } case *event.Quit: return nil } case event := <-e.input: if e.prompt.IsPrompt() { if err := e.promptInput(event); err != nil { return fmt.Errorf( "failed to process input: %w", err, ) } } else { if err := e.bufferInput(event); err != nil { return fmt.Errorf( "failed to process input: %w", err, ) } } if err := e.canvas.Render( e.active, e.prompt, ); err != nil { return fmt.Errorf("failed to render: %w", err) } } } }