Skip to content

Commit

Permalink
Merge pull request #2 from asciifaceman/feature/userio
Browse files Browse the repository at this point in the history
Overhauled user IO
  • Loading branch information
asciifaceman authored Aug 18, 2023
2 parents ea81106 + b3eb8ff commit 964bcc6
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 55 deletions.
34 changes: 34 additions & 0 deletions coloring.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ import (
"github.com/jedib0t/go-pretty/v6/text"
)

/*
TODO: Should possibly check terminal width and try to nicely wrap to the indent if width is going to exceed
*/

// Icolor prints the given string at the given indent
// to the given os.File with the given text.Color, if colorable
// with newline
func Icolor(indent int, fd *os.File, color text.Color, message string) {
id := Tindent(indent)
if Colorable(fd) {
Expand All @@ -22,6 +27,7 @@ func Icolor(indent int, fd *os.File, color text.Color, message string) {

// Icolorf prints the given format at the given indent
// to the given os.File with the given text.Color, if colorable
// with newline
func Icolorf(indent int, fd *os.File, color text.Color, format string, a ...interface{}) {
id := Tindent(indent)
if Colorable(fd) {
Expand All @@ -32,3 +38,31 @@ func Icolorf(indent int, fd *os.File, color text.Color, format string, a ...inte
Stdlin(fd, fmt.Sprintf(format, a...))
}
}

// Ficolor prints the given string at the given indent
// to the given os.File with the given text.Color, if colorable
// and does not newline
func Ficolor(indent int, fd *os.File, color text.Color, format string, a ...interface{}) {
id := Tindent(indent)
if Colorable(fd) {
fmt.Fprint(fd, id)
Std(fd, color.Sprintf(format, a...))
} else {
fmt.Fprint(fd, id)
Std(fd, fmt.Sprintf(format, a...))
}
}

// Ficolorf prints the given format at the given indent
// to the given os.File with the given text.Color, if colorable
// and does not newline
func Ficolorf(indent int, fd *os.File, color text.Color, format string, a ...interface{}) {
id := Tindent(indent)
if Colorable(fd) {
fmt.Fprint(fd, id)
Std(fd, color.Sprintf(format, a...))
} else {
fmt.Fprint(fd, id)
Std(fd, fmt.Sprintf(format, a...))
}
}
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Hobocode Examples

```
go run prints.go
go run examples.go
```

113 changes: 113 additions & 0 deletions examples/examples.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package main

import (
"fmt"
"os"
"time"

"github.com/asciifaceman/hobocode"
)

func main() {
if len(os.Args) == 1 {
help()
}

arg := os.Args[1]

if arg == "prints" {
prints()
} else if arg == "io" {
userio()
} else {
help()
}
}

func help() {
hobocode.Error("Please select an example to see")
hobocode.Error("prints | io")
os.Exit(0)
}

func prints() {
hobocode.Header("Info")
hobocode.Info("This is an info message")
hobocode.Infof("This is a formatted info message: %v", time.Now().Format("2006/01/02"))
hobocode.Iinfo(1, "This is an info message indented once")
hobocode.Iinfo(2, "This is an info message indented twice")
hobocode.Iinfof(1, "This is a formatted info message indented once: %v", time.Now().Format("2006/01/02"))
hobocode.Iinfof(2, "This is a formatted info message indented twice: %v", time.Now().Format("2006/01/02"))

hobocode.Header("Warn")
hobocode.Warn("This is a warn message")
hobocode.Warnf("This is a formatted warn message: %v", time.Now().Format("2006/01/02"))

hobocode.Header("Error")
hobocode.Error("This is an error message")
hobocode.Errorf("This is a formatted error message: %v", fmt.Errorf("error occured at %v", time.Now().Format("2006/01/02")))

hobocode.Header("Success")
hobocode.Success("This is a success message!")
hobocode.Successf("This is a formatted successs message! %v", time.Now().Format("2006/01/02"))

hobocode.Header("Debug")
hobocode.Debug("This is a debug message!")
hobocode.Debugf("This is a formatted debug message! %v", time.Now().Format("2006/01/02"))

hobocode.HeaderLeft("A left justified header!?")
hobocode.HeaderLeft("Whoa!")
hobocode.HeaderLeft("That's cool")

}

func userio() {
in1 := hobocode.Inputd("nvim", "What is your preferred editor? ")
hobocode.Successf("You chose %s", in1)

options := []string{
"Continue seeing user IO examples",
"Quit seeing user IO examples",
"What does the owl say",
}

resp := hobocode.Selection(options, "Please select from the list", "Your selection (empty is none): ")
if resp == -1 {
hobocode.Error("Error fetching input, exiting")
os.Exit(1)
} else if resp == 0 {
hobocode.Info("Continuing...")
} else if resp == 1 {
hobocode.Info("User exited")
os.Exit(0)
} else if resp == 2 {
hobocode.Success("Hoooo!")
}

options = []string{
"Continue (again!) seeing user IO examples",
"See curerent date and continue",
"Quit seeing user IO examples",
}

resp = hobocode.Selectionr(options, 0, "Please select again from the list", "Your selection: ")
if resp == -1 {
hobocode.Error("Error fetching input, exiting")
os.Exit(1)
} else if resp == 0 {
hobocode.Info("Continuing...")
} else if resp == 1 {
hobocode.Info(time.Now().Format("2006-01-02"))
} else if resp == 2 {
hobocode.Info("User exited...")
os.Exit(0)
}

conf := hobocode.Confirm("All good?")
if conf {
hobocode.Success("Yay!")
} else {
hobocode.Warn("Oh no :(")
}

}
39 changes: 0 additions & 39 deletions examples/prints.go

This file was deleted.

19 changes: 17 additions & 2 deletions hobocode.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,30 @@ import (

// Stdoutln prints with newline to os.Stdout
func Stdoutln(message string) {
fmt.Fprintln(os.Stdout, message)
Stdlin(os.Stdout, message)
}

// Stderrln prints with newline to os.Stderr
func Stderrln(message string) {
fmt.Fprintln(os.Stderr, message)
Stdlin(os.Stderr, message)
}

// Stdout prints without newline to os.Stdout
func Stdout(message string) {
Std(os.Stdout, message)
}

// Stderr prints without newline to os.Stdout
func Stderr(message string) {
Std(os.Stderr, message)
}

// Stdlin prints with newline to *os.File the given message
func Stdlin(fd *os.File, message string) {
fmt.Fprintln(fd, message)
}

// Std prints without newline to *os.FIle
func Std(fd *os.File, message string) {
fmt.Fprint(fd, message)
}
80 changes: 67 additions & 13 deletions userio.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,44 @@ package hobocode

import (
"fmt"
"os"
"strconv"
"strings"

"github.com/jedib0t/go-pretty/v6/text"
)

/*
TODO: User IO stuff is rough and needs attention
*/

// Input acquires user CLI input
func Input(message string) string {
Ficolor(0, out, text.FgHiYellow, message)
var ret string
fmt.Scanln(&ret)
return ret
}

// Inputd acquires user CLI input with a default
// defaultOption is presented as the default and used on nil entry
func Input(defaultOption string, message string) string {
fmt.Print(text.FgHiYellow.Sprintf("%s [%s]: ", message, defaultOption))
func Inputd(defaultOption string, message string) string {
Ficolorf(0, out, text.FgHiYellow, "%s [%s]: ", message, defaultOption)
fmt.Scanln(&defaultOption)
return defaultOption
}

// Inputf acquires user CLI input using a formatted message
// defaultOption is presented as the default and used on nil entry
func Inputf(defaultOption string, format string, a ...interface{}) string {
fmt.Print(text.FgHiYellow.Sprintf(format, a...))
fmt.Scanln(&defaultOption)
return defaultOption
func Inputf(format string, a ...interface{}) string {
var ret string
Ficolorf(0, out, text.FgHiYellow, format, a...)
fmt.Scanln(&ret)
return ret
}

// Confirm is a naive confirmation prompt in HiRed that won't break until an affirmative answer is given
// Confirm is a naive confirmation prompt in HiRed that won't break until an explicit answer is given
func Confirm(message string) bool {
var ret string

for {
fmt.Print(text.FgHiRed.Sprintf("%s [(y)es / (n)o]: ", message))
Ficolorf(0, os.Stdout, text.FgHiWhite, "%s (Y/n): ", message)
fmt.Scanln(&ret)

if strings.ToLower(ret) == "y" || strings.ToLower(ret) == "yes" {
Expand All @@ -43,7 +50,6 @@ func Confirm(message string) bool {
continue
}
}

}

// Confirmf is a naive confirmation prompt in HiRed that won't break until an affirmative answer is given
Expand All @@ -52,3 +58,51 @@ func Confirmf(format string, a ...interface{}) bool {
msg := fmt.Sprintf(format, a...)
return Confirm(msg)
}

// Select allows the user to select from a list of options
// the index of the options is used as the selection and the user
// selection is returned as that int
// a response of -1 indicates a failure to capture input
// message introduces the list selection
// prompt is the input line
func Selection(options []string, message string, prompt string) int {
Icolor(0, out, text.FgHiWhite, message)
for i, opt := range options {
Icolorf(1, out, text.FgHiWhite, "%d): %s", i, opt)
}

resp := Input(prompt)

respInt, err := strconv.Atoi(resp)
if err != nil {
return -1
}

return respInt
}

// Selectr allows the user to select from a list of options with a recommended option
// the index of the options is used as the selection and the user
// selection is returned as that int
// a response of -1 indicates a failure to capture input
// message introduces the list selection
// prompt is the input line
func Selectionr(options []string, recommendedOption int, message string, prompt string) int {
Icolor(0, out, text.FgHiWhite, message)
for i, opt := range options {
if i == recommendedOption {
Icolorf(1, out, text.FgHiWhite, "%d): %s <--", i, opt)
} else {
Icolorf(1, out, text.FgHiWhite, "%d): %s", i, opt)
}
}

resp := Inputd(fmt.Sprintf("%d", recommendedOption), prompt)

respInt, err := strconv.Atoi(resp)
if err != nil {
return -1
}

return respInt
}

0 comments on commit 964bcc6

Please sign in to comment.