pkg: Move edit.capturePort to eval.CaptureStringPort.

This commit is contained in:
Qi Xiao 2021-01-02 02:39:03 +00:00
parent f92ae06a04
commit e43492ba17
2 changed files with 40 additions and 46 deletions

View File

@ -1,17 +1,10 @@
package edit
import (
"bufio"
"io"
"os"
"sync"
"github.com/elves/elvish/pkg/cli"
"github.com/elves/elvish/pkg/cli/addons/instant"
"github.com/elves/elvish/pkg/eval"
"github.com/elves/elvish/pkg/eval/vals"
"github.com/elves/elvish/pkg/parse"
"github.com/elves/elvish/pkg/strutil"
)
//elvdoc:var -instant:binding
@ -40,7 +33,7 @@ func initInstant(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
func instantStart(app cli.App, ev *eval.Evaler, binding cli.Handler) {
execute := func(code string) ([]string, error) {
outPort, collect, err := capturePort()
outPort, collect, err := eval.CaptureStringPort()
if err != nil {
return nil, err
}
@ -53,41 +46,3 @@ func instantStart(app cli.App, ev *eval.Evaler, binding cli.Handler) {
}
instant.Start(app, instant.Config{Binding: binding, Execute: execute})
}
// Like eval.CapturePort, but collects output into strings, with value outputs
// stringified and prepended a marker.
func capturePort() (*eval.Port, func() []string, error) {
var lines []string
var mu sync.Mutex
addLine := func(line string) {
mu.Lock()
defer mu.Unlock()
lines = append(lines, line)
}
port, done, err := eval.PipePort(
func(ch <-chan interface{}) {
for v := range ch {
addLine("▶ " + vals.ToString(v))
}
},
func(r *os.File) {
bufr := bufio.NewReader(r)
for {
line, err := bufr.ReadString('\n')
if err != nil {
if err != io.EOF {
addLine("i/o error: " + err.Error())
}
break
}
addLine(strutil.ChopLineEnding(line))
}
})
if err != nil {
return nil, nil, err
}
return port, func() []string {
done()
return lines
}, nil
}

View File

@ -7,6 +7,7 @@ import (
"os"
"sync"
"github.com/elves/elvish/pkg/eval/vals"
"github.com/elves/elvish/pkg/strutil"
)
@ -149,3 +150,41 @@ func CapturePort() (*Port, func() []interface{}, error) {
return vs
}, nil
}
// CaptureStringPort is like CapturePort, but processes value outputs by
// stringifying them and prepending an output marker.
func CaptureStringPort() (*Port, func() []string, error) {
var lines []string
var mu sync.Mutex
addLine := func(line string) {
mu.Lock()
defer mu.Unlock()
lines = append(lines, line)
}
port, done, err := PipePort(
func(ch <-chan interface{}) {
for v := range ch {
addLine("▶ " + vals.ToString(v))
}
},
func(r *os.File) {
bufr := bufio.NewReader(r)
for {
line, err := bufr.ReadString('\n')
if err != nil {
if err != io.EOF {
addLine("i/o error: " + err.Error())
}
break
}
addLine(strutil.ChopLineEnding(line))
}
})
if err != nil {
return nil, nil, err
}
return port, func() []string {
done()
return lines
}, nil
}