Open rickywei opened 1 month ago
also, it needs an extra key press after exec run exit to input
Hey there! What are you trying to do in the above code? Typically you're going to want to use tea.ExecProcess
as tea.Exec
is for lower level work (like working with SSH).
Here's a diff that fixes the above code:
diff --git a/main.go b/main.go
index 5b6b2f5..1e4a82f 100644
--- a/main.go
+++ b/main.go
@@ -2,7 +2,6 @@ package main
import (
"fmt"
- "io"
"os"
"os/exec"
@@ -12,8 +11,6 @@ import (
type editorFinishedMsg struct{ err error }
func openEditor() tea.Cmd {
- return tea.Exec(&echo{}, func(err error) tea.Msg { return err })
-
editor := os.Getenv("EDITOR")
if editor == "" {
editor = "vim"
@@ -73,30 +70,3 @@ func main() {
os.Exit(1)
}
}
-
-type echo struct {
- stdin io.Reader
- stdout, stderr io.Writer
-}
-
-func (e *echo) Run() error {
- fmt.Println(io.Copy(e.stdout, e.stdin))
- return nil
-}
-func (e *echo) SetStdin(r io.Reader) {
- if e.stdin == nil {
- e.stdin = r
- }
-}
-func (e *echo) SetStdout(w io.Writer) {
- if e.stdin == nil {
-
- e.stdout = w
- }
-}
-func (e *echo) SetStderr(w io.Writer) {
- if e.stdin == nil {
- e.stdout = w
- }
-
-}
@meowgorithm Thanks for your reply. And as you guessed, I am going to interactive with SSH. Since my code is a little long, so I post the code with some modification of example code. (The echo is replaced with SSH in my code). Let me simplify the code here. this example code can reproduce the problem too.
package main
import (
"fmt"
"io"
"os"
tea "github.com/charmbracelet/bubbletea"
)
type editorFinishedMsg struct{ err error }
type model struct {
err error
}
func (m model) Init() tea.Cmd {
return nil
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "e":
// return m, tea.Exec(&echo{}, func(err error) tea.Msg { return err })
return m, tea.Exec(&echo{}, func(err error) tea.Msg { return err })
case "ctrl+c", "q":
return m, tea.Quit
}
case editorFinishedMsg:
if msg.err != nil {
m.err = msg.err
return m, tea.Quit
}
}
return m, nil
}
func (m model) View() string {
if m.err != nil {
return "Error: " + m.err.Error() + "\n"
}
return "Press 'e' to echo"
}
func main() {
m := model{}
if _, err := tea.NewProgram(m).Run(); err != nil {
fmt.Println("Error running program:", err)
os.Exit(1)
}
}
type echo struct {
stdin io.Reader
stdout, stderr io.Writer
}
func (e *echo) Run() error {
fmt.Println(io.Copy(e.stdout, e.stdin))
return nil
}
func (e *echo) SetStdin(r io.Reader) {
e.stdin = r
}
func (e *echo) SetStdout(w io.Writer) {
e.stdout = w
}
func (e *echo) SetStderr(w io.Writer) {
e.stdout = w
}
When you run it and press "e", your input should be echoed on screen. But The thing is, the first key you input is not echoed. For example, you only get bc when you input abc.
Hi! On Windows I noticed a similar behaviour for reading user input after a tea.Program was run: The first key input is somehow ignored.
package main
import (
"bufio"
"fmt"
tea "github.com/charmbracelet/bubbletea"
"log"
"os"
)
func main() {
p := tea.NewProgram(model{})
if _, err := p.Run(); err != nil {
log.Fatal(err)
}
fmt.Println("input something")
if _, err := bufio.NewReader(os.Stdin).ReadString('\n'); err != nil {
log.Fatal(err)
}
}
type model struct{}
func (m model) Init() tea.Cmd {
return nil
}
func (m model) 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
}
}
return m, cmd
}
func (m model) View() string {
return fmt.Sprint("hi, press enter to quit")
}