与奶茶的互动
func main() { tmpl, err := template.New("").Funcs(interactiveFns()).Parse(os.Args[1]) if err != nil { log.Fatalf("parsing tempalte: %v", err) } var buf bytes.Buffer tmpl.Execute(&buf, nil) os.Stdout.Write(buf.Bytes()) } type interactiveCtx struct { values map[string]any } func interactiveFns() template.FuncMap { c := &interactiveCtx{ values: map[string]any{}, } return template.FuncMap{ "stringInput": stringInput(c), } } func stringInput(c *interactiveCtx) func(string) (any, error) { return func(inputPrompt string) (any, error) { if val, found := c.values[inputPrompt]; found { return val, nil } p := tea.NewProgram(initialModel(inputPrompt)) finalModel, err := p.Run() if err != nil { return nil, err } value := finalModel.(textInputModel).Value() c.values[inputPrompt] = value return value, nil } } type ( errMsg error ) type textInputModel struct { prompt string textInput textinput.Model err error } func initialModel(inputPrompt string) textInputModel { ti := textinput.New() ti.Focus() ti.CharLimit = 156 ti.Width = 20 return textInputModel{ prompt: inputPrompt, textInput: ti, err: nil, } } func (m textInputModel) Init() tea.Cmd { return textinput.Blink } func (m textInputModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd switch msg := msg.(type) { case tea.KeyMsg: switch msg.Type { case tea.KeyEnter, tea.KeyCtrlC, tea.KeyEsc: return m, tea.Quit } case errMsg: m.err = msg return m, nil } m.textInput, cmd = m.textInput.Update(msg) return m, cmd } func (m textInputModel) View() string { return fmt.Sprintf( "%s %s", m.prompt, m.textInput.View(), ) + "\n" } func (m textInputModel) Value() string { return m.textInput.Value() } }
内容来源: bitfield/script