2019-12-18 18:38:21 +08:00
|
|
|
package edit
|
2019-12-08 08:29:19 +08:00
|
|
|
|
|
|
|
import (
|
2021-01-27 09:28:38 +08:00
|
|
|
"src.elv.sh/pkg/cli"
|
2021-09-04 03:44:04 +08:00
|
|
|
"src.elv.sh/pkg/cli/modes"
|
2021-02-12 02:49:00 +08:00
|
|
|
"src.elv.sh/pkg/cli/tk"
|
2021-01-27 09:28:38 +08:00
|
|
|
"src.elv.sh/pkg/eval"
|
|
|
|
"src.elv.sh/pkg/parse"
|
2019-12-08 08:29:19 +08:00
|
|
|
)
|
|
|
|
|
2019-12-27 00:31:24 +08:00
|
|
|
//elvdoc:var -instant:binding
|
|
|
|
//
|
|
|
|
// Binding for the instant mode.
|
|
|
|
|
|
|
|
//elvdoc:fn -instant:start
|
|
|
|
//
|
|
|
|
// Starts the instant mode. In instant mode, any text entered at the command
|
|
|
|
// line is evaluated immediately, with the output displayed.
|
|
|
|
//
|
|
|
|
// **WARNING**: Beware of unintended consequences when using destructive
|
|
|
|
// commands. For example, if you type `sudo rm -rf /tmp/*` in the instant mode,
|
|
|
|
// Elvish will attempt to evaluate `sudo rm -rf /` when you typed that far.
|
|
|
|
|
2020-12-25 01:39:51 +08:00
|
|
|
func initInstant(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
|
2021-02-13 05:34:47 +08:00
|
|
|
bindingVar := newBindingVar(emptyBindingsMap)
|
|
|
|
bindings := newMapBindings(ed, ev, bindingVar)
|
2020-12-25 01:39:51 +08:00
|
|
|
nb.AddNs("-instant",
|
2021-10-24 04:44:11 +08:00
|
|
|
eval.BuildNsNamed("edit:-instant").
|
|
|
|
AddVar("binding", bindingVar).
|
|
|
|
AddGoFns(map[string]interface{}{
|
|
|
|
"start": func() { instantStart(ed.app, ev, bindings) },
|
|
|
|
}))
|
2019-12-08 08:29:19 +08:00
|
|
|
}
|
|
|
|
|
2021-02-13 05:34:47 +08:00
|
|
|
func instantStart(app cli.App, ev *eval.Evaler, bindings tk.Bindings) {
|
2019-12-08 08:29:19 +08:00
|
|
|
execute := func(code string) ([]string, error) {
|
2021-01-05 12:07:35 +08:00
|
|
|
outPort, collect, err := eval.StringCapturePort()
|
2019-12-08 08:29:19 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-01-02 10:24:12 +08:00
|
|
|
err = ev.Eval(
|
|
|
|
parse.Source{Name: "[instant]", Code: code},
|
|
|
|
eval.EvalCfg{
|
|
|
|
Ports: []*eval.Port{nil, outPort},
|
|
|
|
Interrupt: eval.ListenInterrupts})
|
|
|
|
return collect(), err
|
|
|
|
}
|
2021-09-04 03:44:04 +08:00
|
|
|
w, err := modes.NewInstant(app,
|
|
|
|
modes.InstantSpec{Bindings: bindings, Execute: execute})
|
2021-02-14 05:13:12 +08:00
|
|
|
if w != nil {
|
2021-08-30 07:55:09 +08:00
|
|
|
app.PushAddon(w)
|
2021-02-14 05:13:12 +08:00
|
|
|
app.Redraw()
|
|
|
|
}
|
|
|
|
if err != nil {
|
2021-12-08 08:26:17 +08:00
|
|
|
app.Notify(modes.ErrorText(err))
|
2021-02-14 05:13:12 +08:00
|
|
|
}
|
2021-01-02 10:24:12 +08:00
|
|
|
}
|