Skip to content

Commit 360fb95

Browse files
chore: add message and colour to select prompts
1 parent 164402b commit 360fb95

File tree

1 file changed

+73
-24
lines changed

1 file changed

+73
-24
lines changed

cli/cliui/select.go

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"golang.org/x/xerrors"
1111

1212
"github.com/coder/coder/v2/codersdk"
13+
"github.com/coder/pretty"
1314
"github.com/coder/serpent"
1415
)
1516

@@ -80,6 +81,7 @@ func Select(inv *serpent.Invocation, opts SelectOptions) (string, error) {
8081
hideSearch: opts.HideSearch,
8182
options: opts.Options,
8283
height: opts.Size,
84+
message: opts.Message,
8385
}
8486

8587
if initialModel.height == 0 {
@@ -110,6 +112,7 @@ type selectModel struct {
110112
options []string
111113
cursor int
112114
height int
115+
message string
113116
selected string
114117
canceled bool
115118
hideSearch bool
@@ -170,22 +173,33 @@ func (m selectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
170173
func (m selectModel) View() string {
171174
var s string
172175

173-
if m.hideSearch {
174-
s += "? [Use arrows to move]\n"
175-
} else {
176-
s += fmt.Sprintf("? %s [Use arrows to move, type to filter]\n", m.search.View())
177-
}
176+
msg := pretty.Sprintf(pretty.Bold(), "? %s", m.message)
178177

179-
options, start := m.viewableOptions()
180-
181-
for i, option := range options {
182-
// Is this the currently selected option?
183-
cursor := " "
184-
if m.cursor == start+i {
185-
cursor = ">"
178+
if m.selected == "" {
179+
if m.hideSearch {
180+
s += fmt.Sprintf("%s [Use arrows to move]\n", msg)
181+
} else {
182+
s += fmt.Sprintf("%s %s[Use arrows to move, type to filter]\n", msg, m.search.View())
186183
}
187184

188-
s += fmt.Sprintf("%s %s\n", cursor, option)
185+
options, start := m.viewableOptions()
186+
187+
for i, option := range options {
188+
// Is this the currently selected option?
189+
style := pretty.Wrap(" ", "")
190+
if m.cursor == start+i {
191+
style = pretty.Style{
192+
pretty.Wrap("> ", ""),
193+
pretty.FgColor(Green),
194+
}
195+
}
196+
197+
s += pretty.Sprint(style, option)
198+
s += "\n"
199+
}
200+
} else {
201+
selected := pretty.Sprint(DefaultStyles.Keyword, m.selected)
202+
s += fmt.Sprintf("%s %s\n", msg, selected)
189203
}
190204

191205
return s
@@ -238,11 +252,18 @@ func MultiSelect(inv *serpent.Invocation, opts MultiSelectOptions) ([]string, er
238252
options := make([]multiSelectOption, len(opts.Options))
239253
for i, option := range opts.Options {
240254
options[i].option = option
255+
256+
for _, d := range opts.Defaults {
257+
if option == d {
258+
options[i].chosen = true
259+
}
260+
}
241261
}
242262

243263
initialModel := multiSelectModel{
244264
search: textinput.New(),
245265
options: options,
266+
message: opts.Message,
246267
}
247268

248269
initialModel.search.Prompt = ""
@@ -278,7 +299,9 @@ type multiSelectModel struct {
278299
search textinput.Model
279300
options []multiSelectOption
280301
cursor int
302+
message string
281303
canceled bool
304+
selected bool
282305
}
283306

284307
func (multiSelectModel) Init() tea.Cmd {
@@ -297,12 +320,13 @@ func (m multiSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
297320

298321
case tea.KeyEnter:
299322
if len(m.options) != 0 {
323+
m.selected = true
300324
return m, tea.Quit
301325
}
302326

303327
case tea.KeySpace:
304328
if len(m.options) != 0 {
305-
m.options[m.cursor].chosen = true
329+
m.options[m.cursor].chosen = !m.options[m.cursor].chosen
306330
}
307331

308332
case tea.KeyUp:
@@ -343,21 +367,46 @@ func (m multiSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
343367
}
344368

345369
func (m multiSelectModel) View() string {
346-
s := fmt.Sprintf("? %s [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]\n", m.search.View())
370+
var s string
347371

348-
for i, option := range m.options {
349-
cursor := " "
350-
if m.cursor == i {
351-
cursor = ">"
352-
}
372+
msg := pretty.Sprintf(pretty.Bold(), "? %s", m.message)
353373

354-
chosen := "[ ]"
355-
if option.chosen {
356-
chosen = "[x]"
374+
if !m.selected {
375+
s += fmt.Sprintf("%s %s[Use arrows to move, space to select, <right> to all, <left> to none, type to filter]\n", msg, m.search.View())
376+
377+
for i, option := range m.options {
378+
cursor := " "
379+
if m.cursor == i {
380+
cursor = pretty.Sprint(pretty.FgColor(Green), "> ")
381+
}
382+
383+
chosen := "[ ]"
384+
if option.chosen {
385+
chosen = pretty.Sprint(pretty.FgColor(Green), "[x]")
386+
}
387+
388+
o := option.option
389+
if m.cursor == i {
390+
o = pretty.Sprint(pretty.FgColor(Green), o)
391+
}
392+
393+
s += fmt.Sprintf("%s%s %s\n", cursor, chosen, o)
357394
}
395+
} else {
396+
selected := pretty.Sprint(DefaultStyles.Keyword, strings.Join(m.SelectedOptions(), ", "))
358397

359-
s += fmt.Sprintf("%s %s %s\n", cursor, chosen, option.option)
398+
s += fmt.Sprintf("%s %s\n", msg, selected)
360399
}
361400

362401
return s
363402
}
403+
404+
func (m multiSelectModel) SelectedOptions() []string {
405+
selected := []string{}
406+
for _, o := range m.options {
407+
if o.chosen {
408+
selected = append(selected, o.option)
409+
}
410+
}
411+
return selected
412+
}

0 commit comments

Comments
 (0)