Implemented basic system

This commit is contained in:
2018-04-02 15:40:10 +01:00
parent 080d61728c
commit 3a482ca3f7
11 changed files with 135 additions and 30 deletions

View File

@@ -7,11 +7,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Unreleased
### Added
- Background colors codes and template helpers
- `AllowEdit` for prompt to prevent deletion of the default value by any key
- Added `StartInSearchMode` to allow starting the prompt in search mode
### Fixed
- `<Enter>` key press on Windows
- `juju/ansiterm` dependency
- `chzyer/readline#136` new api with ReadCloser
## [0.2.1] - 2017-11-30
### Fixed
- `SelectWithAdd` panicking on `.Run` due to lack of keys setup
- Backspace key on Windows
## [0.2.0] - 2017-11-16

View File

@@ -124,6 +124,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "160169cbbea61d01890b2670b2cc5448b5b8dd6ebbb18f57bd677c0c7d1f8a42"
inputs-digest = "b683f37352cca49de9eefac440a2fbc8d84e1946237577881122b2fe86c9d950"
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -12,5 +12,5 @@ required=[
branch = "master"
[[constraint]]
name = "github.com/juju/master"
name = "github.com/juju/ansiterm"
branch = "master"

View File

@@ -33,6 +33,18 @@ const (
FGWhite
)
// Background color attributes
const (
BGBlack attribute = iota + 40
BGRed
BGGreen
BGYellow
BGBlue
BGMagenta
BGCyan
BGWhite
)
// ResetCode is the character code used to reset the terminal formatting
var ResetCode = fmt.Sprintf("%s%dm", esc, reset)
@@ -53,6 +65,14 @@ var FuncMap = template.FuncMap{
"magenta": Styler(FGMagenta),
"cyan": Styler(FGCyan),
"white": Styler(FGWhite),
"bgBlack": Styler(BGBlack),
"bgRed": Styler(BGRed),
"bgGreen": Styler(BGGreen),
"bgYellow": Styler(BGYellow),
"bgBlue": Styler(BGBlue),
"bgMagenta": Styler(BGMagenta),
"bgCyan": Styler(BGCyan),
"bgWhite": Styler(BGWhite),
"bold": Styler(FGBold),
"faint": Styler(FGFaint),
"italic": Styler(FGItalic),

25
vendor/github.com/manifoldco/promptui/keycodes.go generated vendored Normal file
View File

@@ -0,0 +1,25 @@
// +build !windows
package promptui
import "github.com/chzyer/readline"
var (
// KeyEnter is the default key for submission/selection
KeyEnter rune = readline.CharEnter
// KeyBackspace is the default key for deleting input text
KeyBackspace rune = readline.CharBackspace
// KeyPrev is the default key to go up during selection
KeyPrev rune = readline.CharPrev
// KeyNext is the default key to go down during selection
KeyNext rune = readline.CharNext
// KeyBackward is the default key to page up during selection
KeyBackward rune = readline.CharBackward
// KeyForward is the default key to page down during selection
KeyForward rune = readline.CharForward
)

View File

@@ -0,0 +1,25 @@
package promptui
// source: https://msdn.microsoft.com/en-us/library/aa243025(v=vs.60).aspx
var (
// KeyEnter is the default key for submission/selection
KeyEnter rune = 13
// KeyBackspace is the default key for deleting input text
KeyBackspace rune = 8
// FIXME: keys below are not triggered by readline, not working on Windows
// KeyPrev is the default key to go up during selection
KeyPrev rune = 38
// KeyNext is the default key to go down during selection
KeyNext rune = 40
// KeyBackward is the default key to page up during selection
KeyBackward rune = 37
// KeyForward is the default key to page down during selection
KeyForward rune = 39
)

View File

@@ -20,6 +20,10 @@ type Prompt struct {
Default string // Default is the initial value to populate in the prompt
// AllowEdit lets the user edit the default value. If false, any key press
// other than <Enter> automatically clears the default value.
AllowEdit bool
// Validate is optional. If set, this function is used to validate the input
// after each character entry.
Validate ValidateFunc
@@ -32,11 +36,14 @@ type Prompt struct {
// default templates are used.
Templates *PromptTemplates
// IsConfirm sets the prompt to be a [y/N] question.
IsConfirm bool
// IsVimMode enables vi-like movements (hjkl) and editing.
IsVimMode bool
stdin io.Reader
stdout io.Writer
stdin io.ReadCloser
stdout io.WriteCloser
}
// PromptTemplates allow a prompt to be customized following stdlib
@@ -122,7 +129,10 @@ func (p *Prompt) Run() (string, error) {
var inputErr error
input := p.Default
eraseDefault := input != ""
if p.IsConfirm {
input = ""
}
eraseDefault := input != "" && !p.AllowEdit
c.SetListener(func(line []rune, pos int, key rune) ([]rune, int, bool) {
if line != nil {
@@ -131,15 +141,16 @@ func (p *Prompt) Run() (string, error) {
switch key {
case 0: // empty
case readline.CharEnter:
case KeyEnter:
return nil, 0, false
case readline.CharBackspace:
case KeyBackspace:
if eraseDefault {
eraseDefault = false
input = ""
}
if len(input) > 0 {
input = input[:len(input)-1]
r := []rune(input)
input = string(r[:len(r)-1])
}
default:
if eraseDefault {
@@ -220,9 +231,12 @@ func (p *Prompt) Run() (string, error) {
prompt := render(p.Templates.valid, p.Label)
prompt = append(prompt, []byte(echo)...)
if p.IsConfirm && strings.ToLower(echo) != "y" {
prompt = render(p.Templates.invalid, p.Label)
err = ErrAbort
if p.IsConfirm {
lowerDefault := strings.ToLower(p.Default)
if strings.ToLower(echo) != "y" && (lowerDefault != "y" || (lowerDefault == "y" && echo != "")) {
prompt = render(p.Templates.invalid, p.Label)
err = ErrAbort
}
}
sb.Reset()
@@ -247,7 +261,6 @@ func (p *Prompt) prepareTemplates() error {
bold := Styler(FGBold)
if p.IsConfirm {
p.Default = ""
if tpls.Confirm == "" {
confirm := "y/N"
if strings.ToLower(p.Default) == "y" {

View File

@@ -43,6 +43,9 @@ type Select struct {
// Searcher can be implemented to teach the select how to search for items.
Searcher list.Searcher
// Starts the prompt in search mode.
StartInSearchMode bool
label string
list *list.List
@@ -150,11 +153,11 @@ func (s *Select) innerRun(starting int, top rune) (int, string, error) {
var searchInput []rune
canSearch := s.Searcher != nil
searchMode := false
searchMode := s.StartInSearchMode
c.SetListener(func(line []rune, pos int, key rune) ([]rune, int, bool) {
switch {
case key == readline.CharEnter:
case key == KeyEnter:
return nil, 0, true
case key == s.Keys.Next.Code || (key == 'j' && !searchMode):
s.list.Next()
@@ -172,7 +175,7 @@ func (s *Select) innerRun(starting int, top rune) (int, string, error) {
} else {
searchMode = true
}
case key == readline.CharBackspace:
case key == KeyBackspace:
if !canSearch || !searchMode {
break
}
@@ -442,10 +445,10 @@ func (s *Select) setKeys() {
return
}
s.Keys = &SelectKeys{
Prev: Key{Code: readline.CharPrev, Display: "↑"},
Next: Key{Code: readline.CharNext, Display: "↓"},
PageUp: Key{Code: readline.CharBackward, Display: "←"},
PageDown: Key{Code: readline.CharForward, Display: "→"},
Prev: Key{Code: KeyPrev, Display: "↑"},
Next: Key{Code: KeyNext, Display: "↓"},
PageUp: Key{Code: KeyBackward, Display: "←"},
PageDown: Key{Code: KeyForward, Display: "→"},
Search: Key{Code: '/', Display: "/"},
}
}