Don't prompt the user when the terminal is not interactive

pull/6/head
Mickaël Menu 3 years ago
parent eb130a8107
commit 1b905dacfd
No known key found for this signature in database
GPG Key ID: 53D73664CD359895

@ -1,4 +1,4 @@
package tty
package term
import (
"fmt"
@ -20,7 +20,7 @@ type PromptOpt struct {
// Prompt displays a message and waits for the user to input one of the
// available options.
// Returns the selected option index.
func (t *TTY) Prompt(msg string, defaultOpt int, options []PromptOpt) int {
func (t *Terminal) Prompt(msg string, defaultOpt int, options []PromptOpt) int {
responses := ""
for i, opt := range options {
if i == len(options)-1 {
@ -42,8 +42,7 @@ func (t *TTY) Prompt(msg string, defaultOpt int, options []PromptOpt) int {
for {
fmt.Printf("%s\n%s > ", msg, responses)
// Don't prompt when --no-input is on.
if t.NoInput {
if !t.IsInteractive() {
fmt.Println(options[defaultOpt].AllowedResponses[0])
return defaultOpt
}
@ -68,7 +67,7 @@ func (t *TTY) Prompt(msg string, defaultOpt int, options []PromptOpt) int {
}
// Confirm is a shortcut to prompt a yes/no question to the user.
func (t *TTY) Confirm(msg string, yesDescription string, noDescription string) bool {
func (t *Terminal) Confirm(msg string, yesDescription string, noDescription string) bool {
return t.Prompt(msg, 1, []PromptOpt{
{
Label: t.MustStyle("y", style.RuleEmphasis) + "es",

@ -1,4 +1,4 @@
package tty
package term
import (
"fmt"
@ -7,8 +7,8 @@ import (
"github.com/mickael-menu/zk/core/style"
)
// Style implements style.Styler using ANSI escape codes to be used with a TTY.
func (t *TTY) Style(text string, rules ...style.Rule) (string, error) {
// Style implements style.Styler using ANSI escape codes to be used with a terminal.
func (t *Terminal) Style(text string, rules ...style.Rule) (string, error) {
if text == "" {
return text, nil
}
@ -22,7 +22,7 @@ func (t *TTY) Style(text string, rules ...style.Rule) (string, error) {
return color.New(attrs...).Sprint(text), nil
}
func (t *TTY) MustStyle(text string, rules ...style.Rule) string {
func (t *Terminal) MustStyle(text string, rules ...style.Rule) string {
text, err := t.Style(text, rules...)
if err != nil {
panic(err.Error())

@ -1,4 +1,4 @@
package tty
package term
import (
"testing"
@ -8,42 +8,42 @@ import (
"github.com/mickael-menu/zk/util/test/assert"
)
func createTTY() *TTY {
func createTerminal() *Terminal {
color.NoColor = false // Otherwise the color codes are not injected during tests
return New()
}
func TestStyleNoRule(t *testing.T) {
res, err := createTTY().Style("Hello")
res, err := createTerminal().Style("Hello")
assert.Nil(t, err)
assert.Equal(t, res, "Hello")
}
func TestStyleOneRule(t *testing.T) {
res, err := createTTY().Style("Hello", style.Rule("red"))
res, err := createTerminal().Style("Hello", style.Rule("red"))
assert.Nil(t, err)
assert.Equal(t, res, "\033[31mHello\033[0m")
}
func TestStyleMultipleRule(t *testing.T) {
res, err := createTTY().Style("Hello", style.Rule("red"), style.Rule("bold"))
res, err := createTerminal().Style("Hello", style.Rule("red"), style.Rule("bold"))
assert.Nil(t, err)
assert.Equal(t, res, "\033[31;1mHello\033[0m")
}
func TestStyleUnknownRule(t *testing.T) {
_, err := createTTY().Style("Hello", style.Rule("unknown"))
_, err := createTerminal().Style("Hello", style.Rule("unknown"))
assert.Err(t, err, "unknown styling rule: unknown")
}
func TestStyleEmptyString(t *testing.T) {
res, err := createTTY().Style("", style.Rule("bold"))
res, err := createTerminal().Style("", style.Rule("bold"))
assert.Nil(t, err)
assert.Equal(t, res, "")
}
func TestStyleAllRules(t *testing.T) {
styler := createTTY()
styler := createTerminal()
test := func(rule string, expected string) {
res, err := styler.Style("Hello", style.Rule(rule))
assert.Nil(t, err)

@ -0,0 +1,22 @@
package term
import (
"os"
"github.com/mattn/go-isatty"
)
// Terminal offers utilities to interact with the terminal.
type Terminal struct {
NoInput bool
}
func New() *Terminal {
return &Terminal{}
}
// IsInteractive returns whether the app is attached to an interactive terminal
// and can prompt the user.
func (t *Terminal) IsInteractive() bool {
return !t.NoInput && isatty.IsTerminal(os.Stdin.Fd())
}

@ -1,9 +0,0 @@
package tty
type TTY struct {
NoInput bool
}
func New() *TTY {
return &TTY{}
}

@ -7,7 +7,7 @@ import (
"github.com/mickael-menu/zk/adapter/handlebars"
"github.com/mickael-menu/zk/adapter/markdown"
"github.com/mickael-menu/zk/adapter/sqlite"
"github.com/mickael-menu/zk/adapter/tty"
"github.com/mickael-menu/zk/adapter/term"
"github.com/mickael-menu/zk/core/note"
"github.com/mickael-menu/zk/core/zk"
"github.com/mickael-menu/zk/util"
@ -18,7 +18,7 @@ import (
type Container struct {
Date date.Provider
Logger util.Logger
TTY *tty.TTY
Terminal *term.Terminal
templateLoader *handlebars.Loader
}
@ -29,14 +29,14 @@ func NewContainer() *Container {
Logger: util.NewStdLogger("zk: ", 0),
// zk is short-lived, so we freeze the current date to use the same
// date for any rendering during the execution.
Date: &date,
TTY: tty.New(),
Date: &date,
Terminal: term.New(),
}
}
func (c *Container) TemplateLoader(lang string) *handlebars.Loader {
if c.templateLoader == nil {
handlebars.Init(lang, c.Logger, c.TTY)
handlebars.Init(lang, c.Logger, c.Terminal)
c.templateLoader = handlebars.NewLoader()
}
return c.templateLoader
@ -48,7 +48,7 @@ func (c *Container) Parser() *markdown.Parser {
func (c *Container) NoteFinder(tx sqlite.Transaction) note.Finder {
notes := sqlite.NewNoteDAO(tx, c.Logger)
return fzf.NewNoteFinder(notes, c.TTY)
return fzf.NewNoteFinder(notes, c.Terminal)
}
// Database returns the DB instance for the given slip box, after executing any

@ -46,7 +46,7 @@ func (cmd *Edit) Run(container *Container) error {
if count > 0 {
if !cmd.Force && count > 2 {
if !container.TTY.Confirm(
if !container.Terminal.Confirm(
fmt.Sprintf("Are you sure you want to open %v notes in the editor?", count),
"Open all the notes",
"Don't open any note",

@ -43,7 +43,7 @@ func (cmd *List) Run(container *Container) error {
}
templates := container.TemplateLoader(zk.Config.Lang)
styler := container.TTY
styler := container.Terminal
format := opt.NewNotEmptyString(cmd.Format)
formatter, err := note.NewFormatter(zk.Path, wd, format, templates, styler)
if err != nil {

@ -14,6 +14,7 @@ require (
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/lestrrat-go/strftime v1.0.3
github.com/mattn/go-isatty v0.0.12
github.com/mattn/go-runewidth v0.0.10 // indirect
github.com/mattn/go-sqlite3 v1.14.6
github.com/mickael-menu/pretty v0.2.3

@ -37,6 +37,6 @@ func main() {
type NoInput bool
func (f NoInput) BeforeApply(container *cmd.Container) error {
container.TTY.NoInput = true
container.Terminal.NoInput = true
return nil
}

@ -16,7 +16,7 @@ import (
osutil "github.com/mickael-menu/zk/util/os"
)
// Pager writes text to a TTY using the user's pager.
// Pager writes text to a terminal using the user's pager.
type Pager struct {
io.WriteCloser
done chan bool
@ -31,7 +31,7 @@ var PassthroughPager = &Pager{
isCloseable: false,
}
// New creates a pager.Pager to be used to write a paginated text to the TTY.
// New creates a pager.Pager to be used to write a paginated text to the terminal.
func New(pagerCmd opt.String, logger util.Logger) (*Pager, error) {
wrap := errors.Wrapper("failed to paginate the output, try again with --no-pager or fix your PAGER environment variable")

Loading…
Cancel
Save