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

6
Gopkg.lock generated
View File

@@ -23,14 +23,14 @@
revision = "d14193dfc626125c831501c1c42340b4248e1f5a"
[[projects]]
branch = "master"
name = "github.com/manifoldco/promptui"
packages = [
".",
"list",
"screenbuf"
]
revision = "f6438f6153008ee1b9ba5446d5333bbe63b622b7"
version = "v0.2.1"
revision = "c0c0d3afc6a03bcb5c1df10b70b862a650db9f9b"
[[projects]]
name = "github.com/mattn/go-colorable"
@@ -53,6 +53,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "cf91849954be7c3fae75bdd76d47e30e3722e6f17661cadf45058fc4d1a70b3c"
inputs-digest = "c5a19c2965341aa002c255d5d4897641f71d9b408c488d91893ad7c8ce3f1c42"
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -27,7 +27,7 @@
[[constraint]]
name = "github.com/manifoldco/promptui"
version = "0.2.1"
branch = "master"
[prune]
go-tests = true

20
main.go
View File

@@ -23,6 +23,7 @@ import (
"os"
"os/user"
"strings"
"os/exec"
)
type host struct {
@@ -94,11 +95,12 @@ func main() {
return strings.Contains(name, input)
}
hostTemplate := "{{\"[\" | bold}}{{.Name | cyan | bold }}{{\"]\" | bold}} {{ .User |bold }} @ {{ .HostName | bold }}"
templates := &promptui.SelectTemplates{
Label: "{{ . }}",
Active: ">{{ .User | cyan }}@({{ .HostName | red }})",
Inactive: " {{ .User | cyan }}@({{ .HostName | red }})",
Selected: "{{ .User | cyan }}@({{ .HostName | red }})",
Active: fmt.Sprintf(">%s", hostTemplate),
Inactive: fmt.Sprintf(" %s", hostTemplate),
Selected: "{{\"Connecting to\"|bold}} {{.Name|cyan|bold}}",
}
prompt := promptui.Select{
@@ -109,12 +111,16 @@ func main() {
Searcher: searcher,
}
i, _, err := prompt.Run()
i, _, promptErr := prompt.Run()
if err != nil {
fmt.Printf("Prompt failed %v\n", err)
if promptErr != nil {
fmt.Print("No option selected")
return
}
fmt.Printf("You choose number %d: %s\n", i+1, hosts[i].Name)
cmd := exec.Command("ssh", hosts[i].Name)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
}

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: "/"},
}
}