Skip to content

Commit

Permalink
fix(cli): ensure correct help bar shown
Browse files Browse the repository at this point in the history
Also consolidates help-bar construction logic
  • Loading branch information
SKalt committed Nov 11, 2020
1 parent 4b813d8 commit 3ec2b00
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 53 deletions.
52 changes: 9 additions & 43 deletions cmd/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import (
"strings"

tea "github.com/charmbracelet/bubbletea"
"github.com/muesli/termenv"
"github.com/skalt/git-cc/pkg/breaking_change_input"
"github.com/skalt/git-cc/pkg/config"
"github.com/skalt/git-cc/pkg/description_editor"
"github.com/skalt/git-cc/pkg/parser"
"github.com/skalt/git-cc/pkg/single_select"
"github.com/skalt/git-cc/pkg/scope_selector"
"github.com/skalt/git-cc/pkg/type_selector"
)

type componentIndex int
Expand All @@ -32,21 +32,14 @@ var (
type InputComponent interface {
View() string
Value() string

// Update(tea.Msg) (tea.Model, tea.Cmd)
// // tea.Model // Init() tea.Cmd, Update(tea.Msg) (tea.Model, tea.Cmd), View() string
// Focus() tea.Cmd // should focus any internals, i.e. text inputs
// // Cancel() // should clean up any resources (i.e. open channels)
// Submit() // send the input to the output channel
}

type model struct {
// components [done]InputComponent
commit [doneIndex]string
viewing componentIndex

typeInput single_select.Model
scopeInput single_select.Model
typeInput type_selector.Model
scopeInput scope_selector.Model
descriptionInput description_editor.Model
breakingChangeInput breaking_change_input.Model

Expand Down Expand Up @@ -101,19 +94,8 @@ func (m model) currentComponent() InputComponent {
// function that returns the initialize function and is typically how you would
// pass arguments to a tea.Init function.
func initialModel(choice chan string, cc *parser.CC, cfg config.Cfg) model {
typeModel := single_select.NewModel(
termenv.String("select a commit type: ").Faint().String(), // context
cc.Type, // value
cfg.CommitTypes,
)
scopeModel := single_select.NewModel(
termenv.String("select a scope:").Faint().String(),
cc.Scope,
append(
[]map[string]string{{"": "unscoped; affects the entire project"}},
cfg.Scopes...,
),
) // TODO: Option to add new scope?
typeModel := type_selector.NewModel(cc, cfg)
scopeModel := scope_selector.NewModel(cc, cfg)
descModel := description_editor.NewModel(
cfg.HeaderMaxLength, cc.Description, cfg.EnforceMaxLength,
)
Expand Down Expand Up @@ -145,7 +127,6 @@ func initialModel(choice chan string, cc *parser.CC, cfg config.Cfg) model {
m = m.submit().advance()
m.descriptionInput = m.descriptionInput.SetPrefix(m.contextValue())
}

return m
}

Expand All @@ -166,24 +147,9 @@ func (m model) updateCurrentInput(msg tea.Msg) model {
func (m model) shouldSkip(component componentIndex) bool {
switch component {
case commitTypeIndex:
commitType := m.commit[commitTypeIndex]
for _, opt := range m.typeInput.Options {
if commitType == opt {
return true
}
}
return false
return m.typeInput.ShouldSkip(m.commit[commitTypeIndex])
case scopeIndex:
if len(m.scopeInput.Options) == 0 {
return true
}
scope := m.commit[scopeIndex]
for _, opt := range m.scopeInput.Options {
if scope == opt && opt != "" {
return true
}
}
return false
return m.scopeInput.ShouldSkip(m.commit[scopeIndex])
default:
return false
}
Expand Down Expand Up @@ -218,7 +184,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.viewing--
}
return m, cmd
case tea.KeyEnter:
case tea.KeyEnter, tea.KeyTab:
switch m.viewing {
default:
m = m.submit().advance()
Expand Down
8 changes: 7 additions & 1 deletion pkg/breaking_change_input/breaking_change_input.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package breaking_change_input

// TODO: refactor to a better name ^
import (
"strings"

"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/muesli/termenv"
Expand All @@ -12,12 +14,16 @@ type Model struct {
input textinput.Model
}

var helpBar = termenv.String(strings.Join(
[]string{config.HelpSubmit, config.HelpBack, config.HelpCancel}, "; "),
).Faint().String()

func (m Model) Value() string {
return m.input.Value()
}

func (m Model) View() string {
return m.input.View() + "\n\n" + config.HelpBar
return m.input.View() + "\n\n" + helpBar + "\n"
}

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
Expand Down
16 changes: 15 additions & 1 deletion pkg/config/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,23 @@ var (
{"refactor": "changes the code without changing behavior"},
{"revert": "reverts prior changes"},
}
HelpBar = termenv.String("submit: enter; go back: shift+tab; cancel: ctrl+c").Faint().String()
)

const (
HelpSubmit = "submit: tab/enter"
HelpBack = "go back: shift+tab"
HelpCancel = "cancel: ctrl+c"
HelpSelect = "navigate: up/down"
)

func Faint(s string) string {
return termenv.String(s).Faint().String()
}

func HelpBar(s ...string) string {
return Faint(fmt.Sprintf("\n%s", strings.Join(s, "; ")))
}

type Cfg struct {
CommitTypes []map[string]string `mapstructure:"commit_types"`
Scopes []map[string]string `mapstructure:"scopes"`
Expand Down
10 changes: 6 additions & 4 deletions pkg/description_editor/description_editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"github.com/skalt/git-cc/pkg/config"
)

var helpBar = config.HelpBar(config.HelpSubmit, config.HelpBack, config.HelpCancel)

const prePrompt = "A short description of the changes:\n\n"

type Model struct {
Expand All @@ -22,7 +24,7 @@ type Model struct {

func (m Model) SetPrefix(prefix string) Model {
m.prefixLen = len(prefix)
m.input.Prompt = termenv.String(prePrompt).Faint().String() + prefix
m.input.Prompt = config.Faint(prePrompt) + prefix
return m
}
func (m Model) SetErr(err error) Model {
Expand All @@ -45,7 +47,7 @@ func NewModel(lengthLimit int, value string, enforced bool) Model {
input.SetValue(value)
input.SetCursor(len(value))
// input.Cursor = len(value)
input.Prompt = termenv.String(prePrompt).Faint().String()
input.Prompt = config.Faint(prePrompt)
if enforced {
input.CharLimit = lengthLimit
}
Expand All @@ -62,7 +64,7 @@ func viewCounter(m Model) string {
paddedFormat := fmt.Sprintf("(%%%dd/%d)", len(fmt.Sprintf("%d", m.lengthLimit)), m.lengthLimit)
view := fmt.Sprintf(paddedFormat, current)
if current < m.lengthLimit {
return termenv.String(view).Faint().String()
return config.Faint(view)
} else if current == m.lengthLimit {
return view // render in a warning color termenv.String(view).
} else {
Expand All @@ -71,7 +73,7 @@ func viewCounter(m Model) string {
}

func viewHelpBar(m Model) string {
return fmt.Sprintf("\n%s %s", config.HelpBar, viewCounter(m))
return fmt.Sprintf("\n%s %s", helpBar, viewCounter(m))
}

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
Expand Down
55 changes: 55 additions & 0 deletions pkg/scope_selector/input.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package scope_selector

import (
tea "github.com/charmbracelet/bubbletea"
"github.com/skalt/git-cc/pkg/config"
"github.com/skalt/git-cc/pkg/parser"
"github.com/skalt/git-cc/pkg/single_select"
)

var helpBar = config.HelpBar(
config.HelpSubmit, config.HelpSelect, config.HelpBack, config.HelpCancel,
)

type Model struct {
input single_select.Model
}

func NewModel(cc *parser.CC, cfg config.Cfg) Model {
return Model{
single_select.NewModel(
config.Faint("select a scope:"),
cc.Scope,
append(
[]map[string]string{{"": "unscoped; affects the entire project"}},
cfg.Scopes...,
),
), // TODO: Option to add new scope?
}
}

func (m Model) Value() string {
return m.input.Value()
}

func (m Model) View() string {
return m.input.View() + helpBar
}

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
var cmd tea.Cmd
m.input, cmd = m.input.Update(msg)
return m, cmd
}

func (m Model) ShouldSkip(currentValue string) bool {
if len(m.input.Options) == 0 {
return true
}
for _, opt := range m.input.Options {
if currentValue == opt && opt != "" {
return true
}
}
return false
}
4 changes: 0 additions & 4 deletions pkg/single_select/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,5 @@ func (m Model) View() string {
s.WriteString("\n")
}

s.WriteString(
term.String("\n(tab/enter to select, up/down to navigate, Ctrl+C to quit)\n").Faint().String(),
)

return s.String()
}
47 changes: 47 additions & 0 deletions pkg/type_selector/input.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package type_selector

import (
tea "github.com/charmbracelet/bubbletea"
"github.com/skalt/git-cc/pkg/config"
"github.com/skalt/git-cc/pkg/parser"
"github.com/skalt/git-cc/pkg/single_select"
)

var helpBar = config.HelpBar(
config.HelpSubmit, config.HelpSelect, config.HelpCancel,
)

type Model struct {
input single_select.Model
}

func NewModel(cc *parser.CC, cfg config.Cfg) Model {
return Model{
single_select.NewModel(
config.Faint("select a commit type: "), cc.Type, cfg.CommitTypes,
),
}
}

func (m Model) Value() string {
return m.input.Value()
}

func (m Model) View() string {
return m.input.View() + helpBar
}

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
var cmd tea.Cmd
m.input, cmd = m.input.Update(msg)
return m, cmd
}

func (m Model) ShouldSkip(currentValue string) bool {
for _, opt := range m.input.Options {
if opt == currentValue {
return true
}
}
return false
}

0 comments on commit 3ec2b00

Please # to comment.