src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

run.go (1937B)


      1 package editor
      2 
      3 import (
      4 	"context"
      5 	"fmt"
      6 	"runtime/debug"
      7 
      8 	"code.dwrz.net/src/pkg/editor/event"
      9 )
     10 
     11 func (e *Editor) Run(ctx context.Context, files []string) error {
     12 	if err := e.terminal.SetRaw(); err != nil {
     13 		return fmt.Errorf("failed to set raw mode: %w", err)
     14 	}
     15 	e.canvas.Reset()
     16 
     17 	// Log build info.
     18 	var commit, time, hostname string
     19 	bi, ok := debug.ReadBuildInfo()
     20 	if ok {
     21 		for _, s := range bi.Settings {
     22 			switch s.Key {
     23 			case "vcs.revision":
     24 				commit = s.Value
     25 			case "vcs.time":
     26 				time = s.Value
     27 			}
     28 		}
     29 	}
     30 	e.log.Debug.Printf(
     31 		"文 version %s; built at %s on %s",
     32 		commit, time, hostname,
     33 	)
     34 
     35 	// Reset the terminal before exiting.
     36 	defer func() {
     37 		e.canvas.Reset()
     38 
     39 		if err := e.terminal.Reset(); err != nil {
     40 			e.log.Error.Printf(
     41 				"failed to reset terminal attributes: %v", err,
     42 			)
     43 		}
     44 	}()
     45 
     46 	// Start reading user input.
     47 	go func() {
     48 		if err := e.reader.Run(ctx); err != nil {
     49 			e.events <- event.NewError(err)
     50 		}
     51 	}()
     52 
     53 	// Open the files.
     54 	go e.load(files)
     55 
     56 	// Main loop.
     57 	for {
     58 		select {
     59 		case <-ctx.Done():
     60 			e.log.Debug.Printf("context done: stopping")
     61 			return nil
     62 
     63 		case ev := <-e.events:
     64 			switch t := ev.(type) {
     65 			case *event.Error:
     66 				return t
     67 
     68 			case *event.Message:
     69 				e.prompt.SetText(t.Text())
     70 
     71 				if err := e.canvas.Render(
     72 					e.active, e.prompt,
     73 				); err != nil {
     74 					return fmt.Errorf(
     75 						"failed to render: %w", err,
     76 					)
     77 				}
     78 
     79 			case *event.Quit:
     80 				return nil
     81 			}
     82 
     83 		case event := <-e.input:
     84 			if e.prompt.IsPrompt() {
     85 				if err := e.promptInput(event); err != nil {
     86 					return fmt.Errorf(
     87 						"failed to process input: %w",
     88 						err,
     89 					)
     90 				}
     91 			} else {
     92 				if err := e.bufferInput(event); err != nil {
     93 					return fmt.Errorf(
     94 						"failed to process input: %w",
     95 						err,
     96 					)
     97 				}
     98 			}
     99 
    100 			if err := e.canvas.Render(
    101 				e.active, e.prompt,
    102 			); err != nil {
    103 				return fmt.Errorf("failed to render: %w", err)
    104 			}
    105 		}
    106 	}
    107 }