2
1
Fork 0
swim/main.go

168 lines
3.3 KiB
Go

package main
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
"os/user"
"path/filepath"
"strings"
"tildegit.org/sloum/swim/termios"
)
var board Board
var fp string
func ExpandedAbsFilepath(p string) string {
if strings.HasPrefix(p, "~/") {
usr, _ := user.Current()
homedir := usr.HomeDir
p = filepath.Join(homedir, p[2:])
}
path, _ := filepath.Abs(p)
return path
}
func Getch() rune {
reader := bufio.NewReader(os.Stdin)
char, _, err := reader.ReadRune()
if err != nil {
return 0
}
return char
}
func GetLine(prefix string) (string, error) {
defer termios.SetCharMode()
termios.SetLineMode()
reader := bufio.NewReader(os.Stdin)
fmt.Print(prefix)
fmt.Print("\033[?25h")
text, err := reader.ReadString('\n')
if err != nil {
return "", err
}
fmt.Print("\033[?25l")
return text[:len(text)-1], nil
}
func GetCommandLine(prefix string) (string, error) {
fmt.Print(upAndLeft) // Move up one and over all
fmt.Print(style.Input)
line, err := GetLine(prefix)
fmt.Print(cursorEnd)
return line, err
}
func GetAndConfirmCommandLine(prefix string) (string, error) {
var conf rune
var err error
var line string
for {
line, err = GetCommandLine(prefix)
if err != nil {
return line, err
}
if line == "" {
return line, fmt.Errorf("Cancelled input")
}
VerifyQuery: fmt.Print(upAndLeft) // Move up one and over all
fmt.Print(style.Input)
fmt.Printf("%s%s%sIs %q correct? (y/n/c)", cursorEnd, upAndLeft, style.Input, line)
conf = Getch()
if conf == 'y' || conf == '\n' {
break
} else if conf == 'n' {
fmt.Print(cursorEnd)
continue
} else if conf == 'c' {
err = fmt.Errorf("Cancelled input")
break
} else {
fmt.Print(cursorEnd)
goto VerifyQuery
}
}
return line, err
}
// Adapted From:
// https://gist.github.com/kennwhite/306317d81ab4a885a965e25aa835b8ef
func WrapText(text string, lineWidth int) string {
var wrapped strings.Builder
words := strings.Fields(strings.TrimSpace(text))
if len(words) == 0 {
return text
}
wrapped.WriteString(words[0])
spaceLeft := lineWidth - wrapped.Len()
for _, word := range words[1:] {
if len(word)+1 > spaceLeft {
wrapped.WriteRune('\n')
wrapped.WriteString(word)
spaceLeft = lineWidth - len(word)
} else {
wrapped.WriteRune(' ')
wrapped.WriteString(word)
spaceLeft -= 1 + len(word)
}
}
return wrapped.String()
}
func Quit() {
termios.Restore()
fmt.Print(cursorEnd)
fmt.Print("\033[0m\n\033[?25h")
os.Exit(0)
}
func LoadFile(path string, cols, rows int) {
p := ExpandedAbsFilepath(path)
bytes, err := ioutil.ReadFile(p)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not open file %q\n", path)
os.Exit(1)
}
fp = p
err = json.Unmarshal(bytes, &board)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not understand input file:\n%s\n", err.Error())
os.Exit(1)
}
board.width = cols
board.height = rows
board.message = fmt.Sprintf("Loaded file: %s", path)
}
func main() {
flag.Parse()
args := flag.Args()
style.Init(SimpleColor)
cols, rows := termios.GetWindowSize()
if len(args) > 0 {
LoadFile(args[0], cols, rows)
} else {
fp = ""
board = Board{
Title: "My Test Board",
Lanes: make([]Lane, 0, 1),
Current: -1,
laneOff: 0,
message: "Welcome to SWIM",
msgErr: false,
width: cols,
height: rows,
Zoom: 3}
}
board.Run()
}