package app import ( "os" "os/exec" "os/user" "git.sr.ht/~rockorager/vaxis" "git.sr.ht/~rockorager/vaxis/widgets/term" "git.tilde.town/nbsp/welcome/ui" ) type Shell struct { loaded bool } func (view *Shell) Draw(state *ui.State) (row int) { win := state.Window().New(0, 0, 80, state.Window().Height) user, _ := user.Current() _, row = win.Wrap(vaxis.Segment{Text: `──── using the shell ──── `, Style: vaxis.Style{Foreground: vaxis.IndexColor(5)}}, vaxis.Segment{Text: `Interaction with 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! The tool we use to navigate between programs *within* the terminal, however, is called a `}, vaxis.Segment{Text: "shell", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: `. It's an interface that accepts commands, like "open a text editor" or "show me my flower", in a special language. 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 adventure. below is a shell prompt. Here are some shell commands for you to try out; type them and hit Enter to run them: • `}, vaxis.Segment{Text: "ls", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: " list the contents of a folder\n• "}, vaxis.Segment{Text: "cd", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: " change (move) into a directory (folder)\n• "}, vaxis.Segment{Text: "mkdir", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: " make a new directory (folder) with a given name\n• "}, vaxis.Segment{Text: "cat", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: " output the contents of a file (try running "}, vaxis.Segment{Text: "cat welcome_" + user.Username + ".txt", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: "!)\n• "}, vaxis.Segment{Text: "echo", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: " make the shell repeat what you say to it\ntype "}, vaxis.Segment{Text: "exit", Style: vaxis.Style{Foreground: vaxis.IndexColor(3)}}, vaxis.Segment{Text: ` and hit Enter to continue the tutorial, whenever you're ready.`}, ) return } func (view *Shell) Event(state *ui.State, event vaxis.Event) (processed bool) { if view.loaded { return } view.loaded = true row := view.Draw(state) win := state.Window().New(0, row+2, 80, 80) vt := term.New() vt.TERM = os.Getenv("TERM") vt.Attach(state.PostEvent()) vt.Focus() err := vt.Start(exec.Command("bash", "-l")) if err != nil { panic(err) } defer vt.Close() for ev := range state.Events() { switch ev.(type) { case term.EventClosed: state.HideCursor() vt.Detach() vt.Close() state.Window().Clear() ui.ViewChange <- &Editor{} return case vaxis.Redraw: view.Draw(state) vt.Draw(win) state.Render() continue } vt.Update(ev) } return }