forked from tildetown/town
WIP
parent
6b86087c0e
commit
d7adcbf11f
|
@ -1,16 +1,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/MakeNowJust/heredoc/v2"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/rivo/tview"
|
||||
)
|
||||
|
||||
|
@ -61,7 +58,19 @@ func cli(s *streams) error {
|
|||
sidebar := tview.NewTextView()
|
||||
sidebar.SetBorder(true)
|
||||
sidebar.SetDynamicColors(true)
|
||||
sidebar.SetText("[-:-:b]pbbt[-:-:-]")
|
||||
sidebar.SetText(heredoc.Doc(`
|
||||
[-:-:b]hey here are some hints[-:-:-]
|
||||
|
||||
quit by pressing [-:-:b]ctrl-c[-:-:-]
|
||||
(your responses won't be saved)
|
||||
|
||||
type stuff. send it with [-:-:b]ctrl+d[-:-:-]
|
||||
|
||||
try a [-:-:b]verb[-:-:-] using [-:-:b]/[-:-:-] like:
|
||||
|
||||
[-:-:b]/go north[-:-:-]
|
||||
|
||||
`))
|
||||
|
||||
innerFlex.SetDirection(tview.FlexColumn)
|
||||
innerFlex.AddItem(msgScroll, 0, 2, false)
|
||||
|
@ -77,9 +86,52 @@ func cli(s *streams) error {
|
|||
app := tview.NewApplication()
|
||||
app.SetRoot(pages, true)
|
||||
|
||||
player := newCharacter("you", "TODO")
|
||||
|
||||
handleInput := func(msg string) {
|
||||
if strings.HasPrefix(msg, "/") {
|
||||
// TODO handle command
|
||||
}
|
||||
fmt.Fprintln(msgScroll, player.Say(msg))
|
||||
}
|
||||
|
||||
app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
||||
switch event.Key() {
|
||||
case tcell.KeyCtrlD:
|
||||
handleInput(input.GetText())
|
||||
input.SetText("", false)
|
||||
return nil
|
||||
}
|
||||
|
||||
return event
|
||||
})
|
||||
|
||||
return app.Run()
|
||||
}
|
||||
|
||||
type character struct {
|
||||
Name string
|
||||
Description string
|
||||
}
|
||||
|
||||
func newCharacter(name, description string) *character {
|
||||
return &character{
|
||||
Name: name,
|
||||
Description: description,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *character) Say(msg string) string {
|
||||
verb := "says"
|
||||
if c.Name == "you" {
|
||||
verb = "say"
|
||||
}
|
||||
return fmt.Sprintf("[-:-:b]%s[-:-:-] %s: '%s'",
|
||||
c.Name,
|
||||
verb,
|
||||
strings.TrimSpace(msg))
|
||||
}
|
||||
|
||||
func main() {
|
||||
s := &streams{
|
||||
In: os.Stdin,
|
||||
|
@ -93,141 +145,7 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
type Prompter struct {
|
||||
in io.Reader
|
||||
out io.Writer
|
||||
width int
|
||||
}
|
||||
|
||||
func (p *Prompter) Say(m string) {
|
||||
for _, line := range wrap(m, p.width) {
|
||||
fmt.Fprintln(p.out, line)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prompter) CharSay(c, m string) {
|
||||
sayPrefix := fmt.Sprintf("%s says: ", c)
|
||||
prefixWidth := utf8.RuneCountInString(sayPrefix)
|
||||
width := p.width - prefixWidth
|
||||
indent := ""
|
||||
for x := 0; x < utf8.RuneCountInString(sayPrefix); x++ {
|
||||
indent += " "
|
||||
}
|
||||
for i, line := range wrap(m, width) {
|
||||
if i == 0 {
|
||||
fmt.Fprintln(p.out, sayPrefix+line)
|
||||
} else {
|
||||
fmt.Fprintln(p.out, indent+line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type InputAnswer struct {
|
||||
Value string
|
||||
}
|
||||
|
||||
func runeLen(s string) int {
|
||||
return utf8.RuneCountInString(s)
|
||||
}
|
||||
|
||||
func wrap(s string, width int) []string {
|
||||
fielded := strings.Fields(s)
|
||||
out := []string{}
|
||||
line := ""
|
||||
for i, field := range fielded {
|
||||
if runeLen(field)+runeLen(line)+1 < width {
|
||||
line += field + " "
|
||||
} else {
|
||||
out = append(out, line)
|
||||
line = field + " "
|
||||
continue
|
||||
}
|
||||
if i == len(fielded)-1 {
|
||||
out = append(out, line)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (p *Prompter) Confirm(m string) (bool, error) {
|
||||
result := InputAnswer{}
|
||||
|
||||
for {
|
||||
err := p.Ask(m, &result)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
val := strings.TrimSpace(result.Value)
|
||||
|
||||
switch val {
|
||||
case "yes", "y":
|
||||
return true, nil
|
||||
case "no", "n":
|
||||
return false, nil
|
||||
default:
|
||||
p.Say("sorry, please say y or n")
|
||||
p.Pause()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prompter) Ask(m string, result *InputAnswer) error {
|
||||
fmt.Fprintf(p.out, "%s ", m)
|
||||
var val string
|
||||
var err error
|
||||
|
||||
reader := bufio.NewReader(p.in)
|
||||
for val == "" {
|
||||
val, err = reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if val == "" {
|
||||
p.Say("hmm, what was that?")
|
||||
p.Pause()
|
||||
}
|
||||
}
|
||||
|
||||
result.Value = val
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Prompter) AskLong(m string, result *InputAnswer) error {
|
||||
fmt.Fprintf(p.out, "%s\n", m)
|
||||
var val []byte
|
||||
var err error
|
||||
|
||||
reader := bufio.NewReader(p.in)
|
||||
for len(val) == 0 {
|
||||
val, err = ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(val) == 0 {
|
||||
fmt.Fprintf(p.out, "%s\n", m)
|
||||
}
|
||||
}
|
||||
|
||||
result.Value = string(val)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Prompter) Pause() {
|
||||
fmt.Fprintln(p.out)
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
func NewPrompter(width int, s *streams) Prompter {
|
||||
return Prompter{
|
||||
in: s.In,
|
||||
out: s.Out,
|
||||
width: width,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
type answers struct {
|
||||
username string
|
||||
email string
|
||||
|
@ -242,29 +160,6 @@ type answers struct {
|
|||
}
|
||||
|
||||
func _main(args []string, s *streams) error {
|
||||
a := answers{}
|
||||
|
||||
p := NewPrompter(80, s)
|
||||
|
||||
// disable input buffering
|
||||
exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
|
||||
|
||||
// LOL i don't think this will work
|
||||
//reader := bufio.NewReader(p.in)
|
||||
//s, _ := reader.ReadString(4)
|
||||
fmt.Printf("DBG %#v\n", s)
|
||||
//var b []byte = make([]byte, 100)
|
||||
//for {
|
||||
// os.Stdin.Read(b)
|
||||
// fmt.Println("I got the byte", b, "("+string(b)+")")
|
||||
//}
|
||||
|
||||
var ia InputAnswer
|
||||
if err := p.AskLong("lol give me stuff hit ctrl+d", &ia); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("DBG %#v\n", ia.Value)
|
||||
|
||||
p.Say("you are standing in a field.")
|
||||
p.Pause()
|
||||
p.Say("there are flowers around you. you are standing in a slight depression and before you is grass touching a purple sky.")
|
||||
|
@ -345,54 +240,5 @@ func _main(args []string, s *streams) error {
|
|||
|
||||
p.CharSay("cube", "i know that was a lot so i appreciate it. i've got everything written down here. before i carry it off, do you want to review and edit what you wrote?")
|
||||
|
||||
confirmed, err := p.Confirm("type y or n: ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if confirmed {
|
||||
err := edit(s, &a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("DBG %#v\n", confirmed)
|
||||
|
||||
fmt.Printf("DBG %#v\n", a)
|
||||
|
||||
// TODO allow for editing
|
||||
// TODO write answers to disk
|
||||
// TODO add a log
|
||||
// TODO pretty colors
|
||||
// TODO ascii art
|
||||
// TODO IP throttling?
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func edit(s *streams, a *answers) error {
|
||||
// TODO make more real
|
||||
/*
|
||||
username string
|
||||
email string
|
||||
applied time.Time
|
||||
|
||||
howDay string
|
||||
howHeard string
|
||||
reasons string
|
||||
plans string
|
||||
socials string
|
||||
sshKey string
|
||||
*/
|
||||
// TODO add note about tabbing around
|
||||
|
||||
app := tview.NewApplication()
|
||||
form := tview.NewForm().
|
||||
AddInputField("how did you hear about the town?", a.howHeard, 0, nil, nil).
|
||||
AddButton("cool i'm good", nil).
|
||||
AddButton("cancel and discard all this please", func() { app.Stop() })
|
||||
form.SetBorder(true).SetTitle("edit your stuff").SetTitleAlign(tview.AlignCenter)
|
||||
|
||||
return app.SetRoot(form, true).EnableMouse(true).Run()
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -4,6 +4,7 @@ go 1.18
|
|||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.5
|
||||
github.com/MakeNowJust/heredoc/v2 v2.0.1
|
||||
github.com/charmbracelet/glamour v0.5.0
|
||||
github.com/rivo/tview v0.0.0-20230130130022-4a1b7a76c01c
|
||||
github.com/spf13/cobra v1.5.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -1,5 +1,7 @@
|
|||
github.com/AlecAivazis/survey/v2 v2.3.5 h1:A8cYupsAZkjaUmhtTYv3sSqc7LO5mp1XDfqe5E/9wRQ=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.5/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3cWNXgWXOhllqvI=
|
||||
github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A=
|
||||
github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
|
||||
github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek=
|
||||
|
|
Loading…
Reference in New Issue