package app import ( "os/exec" "git.sr.ht/~rockorager/vaxis" "git.sr.ht/~rockorager/vaxis/widgets/term" "git.tilde.town/nbsp/welcome/ui" ) type Shell struct{} func (view *Shell) Draw(state *ui.State) { win := state.Window() win.Print(vaxis.Segment{Text: ` ──── using the shell ──── as mentioned before, interaction with stuff on tilde town is done primarily via the `}, vaxis.Segment{Text: "terminal", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: `. good news, you've been using the terminal this whole time! it's simply the text application with which you've been talking to the server so far. the method of navigation between programs inside our shared computer, however, is called a `}, vaxis.Segment{Text: "shell", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: `. it's an interface that takes in commands, like "open a text editor" or "show me my flower", in a language that doesn't take too long to get used to. the most popular shell is called `}, vaxis.Segment{Text: "bash", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: `, and while there are more, there's no reason to switch unless you're looking for something different. below is a terminal session. try typing `}, vaxis.Segment{Text: "ls", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: ` to list a folder, or `}, vaxis.Segment{Text: "echo", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: ` to make the shell say anything you want it to. run `}, vaxis.Segment{Text: "exit", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: ` to continue the tutorial, whenever you're ready.`}, ) } func (view *Shell) Event(state *ui.State, event vaxis.Event) (processed bool) { if key, ok := event.(vaxis.Key); ok && key.EventType == vaxis.EventPress { switch key.String() { case "Ctrl+c", "Ctrl+d": close(ui.Quit) case "Enter": ui.ViewChange <- &Settings{} } processed = true } win := state.Window() view.Draw(state) vt := term.New() vt.Draw(win.New(0, 15, 80, 80)) vt.Attach(state.PostEvent()) vt.Focus() err := vt.Start(exec.Command("bash", "-i")) if err != nil { panic(err) } defer vt.Close() for ev := range state.Events() { switch ev.(type) { case term.EventClosed: state.HideCursor() state.Window().Clear() ui.ViewChange <- &Introduction{} return case vaxis.Redraw: view.Draw(state) vt.Draw(win.New(0, 15, 80, 80)) state.Render() continue } // for some reason vaxis doubles all events for Press/Release so this just ignores releases if key, ok := ev.(vaxis.Key); ok && key.EventType == vaxis.EventPress { vt.Update(ev) } } return }