Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding key for quit in SelectKeys #155

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions select.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import (
// SelectWithAdd's logic.
const SelectedAdd = -1

// ExitCode is default exit code. It will be returned on application exit.
const ExitCode = 0

// Select represents a list of items used to enable selections, they can be used as search engines, menus
// or as a list of items in a cli based prompt.
type Select struct {
Expand Down Expand Up @@ -78,6 +81,10 @@ type Select struct {
// A function that determines how to render the cursor
Pointer Pointer

// A value that can de returned as result of Run() on ExitKey pressing.
// If not defined, application will be closed on ExitKey pressing.
ExitValue string

Stdin io.ReadCloser
Stdout io.WriteCloser
}
Expand All @@ -99,6 +106,9 @@ type SelectKeys struct {

// Search is the key used to trigger the search mode for the list. Default to the "/" key.
Search Key

// Exit is the key used to correctly shutdown the process. Default to the "q" key.
Exit Key
}

// Key defines a keyboard code and a display representation for the help menu.
Expand Down Expand Up @@ -220,6 +230,8 @@ func (s *Select) RunCursorAt(cursorPos, scroll int) (int, string, error) {
}

func (s *Select) innerRun(cursorPos, scroll int, top rune) (int, string, error) {
isExit := bool(false)

c := &readline.Config{
Stdin: s.Stdin,
Stdout: s.Stdout,
Expand Down Expand Up @@ -273,6 +285,8 @@ func (s *Select) innerRun(cursorPos, scroll int, top rune) (int, string, error)
} else {
searchMode = true
}
case key == s.Keys.Exit.Code:
isExit = true
case key == KeyBackspace:
if !canSearch || !searchMode {
break
Expand All @@ -295,6 +309,10 @@ func (s *Select) innerRun(cursorPos, scroll int, top rune) (int, string, error)
}
}

if isExit {
closeReadlineInstance(rl)
}

if searchMode {
header := SearchPrompt + cur.Format()
sb.WriteString(header)
Expand Down Expand Up @@ -356,6 +374,11 @@ func (s *Select) innerRun(cursorPos, scroll int, top rune) (int, string, error)
for {
_, err = rl.Readline()

if isExit {
err = nil
break
}

if err != nil {
switch {
case err == readline.ErrInterrupt, err.Error() == "Interrupt":
Expand Down Expand Up @@ -385,6 +408,14 @@ func (s *Select) innerRun(cursorPos, scroll int, top rune) (int, string, error)
return 0, "", err
}

if isExit {
clearScreen(sb)
if s.ExitValue != "" {
return s.list.Index(), fmt.Sprintf("%v", s.ExitValue), err
}
os.Exit(ExitCode)
}

items, idx := s.list.Items()
item := items[idx]

Expand Down Expand Up @@ -513,6 +544,9 @@ type SelectWithAdd struct {
// a function that defines how to render the cursor
Pointer Pointer

// A value that can de returned on exit as result of Run()
ExitValue string

// HideHelp sets whether to hide help information.
HideHelp bool
}
Expand Down Expand Up @@ -541,6 +575,7 @@ func (sa *SelectWithAdd) Run() (int, string, error) {
Size: 5,
list: list,
Pointer: sa.Pointer,
ExitValue: sa.ExitValue,
}
s.setKeys()

Expand Down Expand Up @@ -578,6 +613,7 @@ func (s *Select) setKeys() {
PageUp: Key{Code: KeyBackward, Display: KeyBackwardDisplay},
PageDown: Key{Code: KeyForward, Display: KeyForwardDisplay},
Search: Key{Code: '/', Display: "/"},
Exit: Key{Code: 'q', Display: "q"},
}
}

Expand Down Expand Up @@ -635,3 +671,9 @@ func clearScreen(sb *screenbuf.ScreenBuf) {
sb.Clear()
sb.Flush()
}

func closeReadlineInstance(rl *readline.Instance) {
rl.Write([]byte(showCursor))
rl.Clean()
rl.Close()
}