Skip to content

Commit

Permalink
feat: prompt function
Browse files Browse the repository at this point in the history
  • Loading branch information
wobsoriano committed Jul 24, 2022
1 parent 4a27669 commit d21994b
Show file tree
Hide file tree
Showing 7 changed files with 295 additions and 127 deletions.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ require (
)

require (
github.com/atotto/clipboard v0.1.2 // indirect
github.com/charmbracelet/bubbles v0.8.0 // indirect
github.com/charmbracelet/lipgloss v0.1.2 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
Expand Down
28 changes: 28 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
github.com/atotto/clipboard v0.1.2 h1:YZCtFu5Ie8qX2VmVTBnrqLSiU9XOWwqNRmdT3gIQzbY=
github.com/atotto/clipboard v0.1.2/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/charmbracelet/bubbles v0.8.0 h1:+l2op90Ag37Vn+30O1hbg/0wBl+e+sxHhgY1F/rvdHs=
github.com/charmbracelet/bubbles v0.8.0/go.mod h1:5WX1sSSjNCgCrzvRMN/z23HxvWaa+AI16Ch0KPZPeDs=
github.com/charmbracelet/bubbletea v0.13.1/go.mod h1:tp9tr9Dadh0PLhgiwchE5zZJXm5543JYjHG9oY+5qSg=
github.com/charmbracelet/bubbletea v0.22.0 h1:E1BTNSE3iIrq0G0X6TjGAmrQ32cGCbFDPcIuImikrUc=
github.com/charmbracelet/bubbletea v0.22.0/go.mod h1:aoVIwlNlr5wbCB26KhxfrqAn0bMp4YpJcoOelbxApjs=
github.com/charmbracelet/lipgloss v0.1.2 h1:D+LUMg34W7n2pkuMrevKVxT7HXqnoRHm7IoomkX3/ZU=
github.com/charmbracelet/lipgloss v0.1.2/go.mod h1:5D8zradw52m7QmxRF6QgwbwJi9je84g8MkWiGN07uKg=
github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
Expand All @@ -15,13 +28,27 @@ github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTd
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
github.com/muesli/cancelreader v0.2.1 h1:Xzd1B4U5bWQOuSKuN398MyynIGTNT89dxzpEDsalXZs=
github.com/muesli/cancelreader v0.2.1/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/muesli/termenv v0.7.2/go.mod h1:ct2L5N2lmix82RaY3bMWwVu/jUFc9Ule0KGDCiKYPh8=
github.com/muesli/termenv v0.8.1/go.mod h1:kzt/D/4a88RoheZmwfqorY3A+tnsSMA9HJC/fQSFKo0=
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 h1:QANkGiGr39l1EESqrE0gZw0/AJNYzIvoGLhIoVYtluI=
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand All @@ -30,3 +57,4 @@ golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIj
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
122 changes: 10 additions & 112 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,10 @@ package main
import "C"

import (
"encoding/json"
"fmt"
"strconv"
"unsafe"

"github.com/mritd/bubbles/common"

"github.com/mritd/bubbles/selector"

tea "github.com/charmbracelet/bubbletea"
"github.com/wobsoriano/promptx/prompt"
"github.com/wobsoriano/promptx/selection"
)

func ch(str string) *C.char {
Expand All @@ -27,117 +21,21 @@ func str(ch *C.char) string {
return C.GoString(ch)
}

func sf(err error) string {
if err == nil {
return ""
}

return fmt.Sprintf("%s", err)
}
func main() {}

//export FreeString
func FreeString(str *C.char) {
C.free(unsafe.Pointer(str))
}

type model struct {
sl selector.Model
}

func (m model) Init() tea.Cmd {
return nil
}
func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// By default, the prompt component will not return a "tea.Quit"
// message unless Ctrl+C is pressed.
//
// If there is no error in the input, the prompt component returns
// a "common.DONE" message when the Enter key is pressed.
switch msg {
case common.DONE:
return m, tea.Quit
}

_, cmd := m.sl.Update(msg)
return m, cmd
}

func (m model) View() string {
return m.sl.View()
}

type ListItem struct {
Text string `json:"text"`
Description string `json:"description"`
}

func main() {}

type Result struct {
SelectedIndex string `json:"selectedIndex"`
Error string `json:"error"`
}

//export CreateSelection
func CreateSelection(jsonData, headerText, footerText *C.char, perPage int) *C.char {
var item []ListItem
json.Unmarshal([]byte(str(jsonData)), &item)
data := []interface{}{}
for _, val := range item {
data = append(data, ListItem{Text: val.Text, Description: val.Description})
}
m := &model{
sl: selector.Model{
Data: data,
PerPage: perPage,
// Use the arrow keys to navigate: ↓ ↑ → ←
// Select Commit Type:
HeaderFunc: selector.DefaultHeaderFuncWithAppend(str(headerText)),
// [1] feat (Introducing new features)
SelectedFunc: func(m selector.Model, obj interface{}, gdIndex int) string {
t := obj.(ListItem)
if t.Description != "" {
return common.FontColor(fmt.Sprintf("[%d] %s (%s)", gdIndex+1, t.Text, t.Description), selector.ColorSelected)
}
return common.FontColor(fmt.Sprintf("[%d] %s", gdIndex+1, t.Text), selector.ColorSelected)
},
// 2. fix (Bug fix)
UnSelectedFunc: func(m selector.Model, obj interface{}, gdIndex int) string {
t := obj.(ListItem)
if t.Description != "" {
return common.FontColor(fmt.Sprintf(" %d. %s (%s)", gdIndex+1, t.Text, t.Description), selector.ColorUnSelected)
}
return common.FontColor(fmt.Sprintf(" %d. %s", gdIndex+1, t.Text), selector.ColorUnSelected)
},
FooterFunc: func(m selector.Model, obj interface{}, gdIndex int) string {
return common.FontColor(str(footerText), selector.ColorFooter)
},
FinishedFunc: func(s interface{}) string {
return ""
},
},
}
result := selection.Selection(str(jsonData), str(headerText), str(footerText), perPage)
return ch(result)
}

p := tea.NewProgram(m)
err := p.Start()
if err != nil {
result, _ := json.Marshal(&Result{
SelectedIndex: "",
Error: sf(err),
})
return ch(string(result))
}
if !m.sl.Canceled() {
result, _ := json.Marshal(&Result{
SelectedIndex: strconv.Itoa(m.sl.Index()),
Error: "",
})
return ch(string(result))
} else {
result, _ := json.Marshal(&Result{
SelectedIndex: "",
Error: "Cancelled",
})
return ch(string(result))
}
//export CreatePrompt
func CreatePrompt(prompText, echoMode *C.char, required bool, charLimit int) *C.char {
result := prompt.Prompt(str(prompText), str(echoMode), required, charLimit)
return ch(result)
}
39 changes: 24 additions & 15 deletions playground.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import { createSelection } from './src'
import { createSelection, createPrompt } from './src'

const result = createSelection([
{ text: 'feat', description: 'Introducing new features' },
{ text: 'fix', description: 'Bug fix' },
{ text: 'docs', description: 'Writing docs' },
{ text: 'style', description: 'Improving structure/format of the code' },
{ text: 'refactor', description: 'Refactoring code' },
{ text: 'test', description: 'Refactoring code' },
{ text: 'chore', description: 'When adding missing tests' },
{ text: 'perf', description: 'Improving performance' }
], {
headerText: 'Select Commit Type: ',
perPage: 5,
footerText: 'Footer here'
})
// const result = createSelection([
// { text: 'feat', description: 'Introducing new features' },
// { text: 'fix', description: 'Bug fix' },
// { text: 'docs', description: 'Writing docs' },
// { text: 'style', description: 'Improving structure/format of the code' },
// { text: 'refactor', description: 'Refactoring code' },
// { text: 'test', description: 'Refactoring code' },
// { text: 'chore', description: 'When adding missing tests' },
// { text: 'perf', description: 'Improving performance' }
// ], {
// headerText: 'Select Commit Type: ',
// perPage: 5,
// footerText: 'Footer here'
// })

// console.log(result)
const result = createPrompt("Enter anything: ")

console.log(result)

const result2 = createPrompt("Enter password: ", {
echoMode: 'none'
})

console.log(result2)
85 changes: 85 additions & 0 deletions prompt/prompt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package prompt

import (
"encoding/json"
"fmt"

"github.com/mritd/bubbles/common"

tea "github.com/charmbracelet/bubbletea"
"github.com/mritd/bubbles/prompt"
)

type model struct {
input *prompt.Model
}

func (m model) Init() tea.Cmd {
return nil
}

func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// By default, the prompt component will not return a "tea.Quit"
// message unless Ctrl+C is pressed.
//
// If there is no error in the input, the prompt component returns
// a "common.DONE" message when the Enter key is pressed.
switch msg {
case common.DONE:
return m, tea.Quit
}

_, cmd := m.input.Update(msg)
return m, cmd
}

func (m model) View() string {
return m.input.View()
}

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

type Result struct {
Value string `json:"value"`
Error string `json:"error"`
}

func Prompt(promptText, echoMode string, required bool, charLimit int) string {
m := model{input: &prompt.Model{
ValidateFunc: prompt.VFNotBlank,
Prompt: promptText,
CharLimit: charLimit,
EchoMode: prompt.EchoNormal,
}}

if echoMode == "none" {
m.input.EchoMode = prompt.EchoNone
} else if echoMode == "password" {
m.input.EchoMode = prompt.EchoPassword
} else {
m.input.EchoMode = prompt.EchoNormal
}

if required {
m.input.ValidateFunc = prompt.VFNotBlank
} else {
m.input.ValidateFunc = prompt.VFDoNothing
}

p := tea.NewProgram(&m)
err := p.Start()
if err != nil {
result, _ := json.Marshal(&Result{
Value: m.Value(),
Error: fmt.Sprintf("%s", err),
})
return string(result)
}
result, _ := json.Marshal(&Result{
Value: m.Value(),
Error: "",
})
return string(result)
}
Loading

0 comments on commit d21994b

Please sign in to comment.