github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/edit/instant.go (about)

     1  package edit
     2  
     3  import (
     4  	"github.com/markusbkk/elvish/pkg/cli"
     5  	"github.com/markusbkk/elvish/pkg/cli/modes"
     6  	"github.com/markusbkk/elvish/pkg/cli/tk"
     7  	"github.com/markusbkk/elvish/pkg/eval"
     8  	"github.com/markusbkk/elvish/pkg/parse"
     9  )
    10  
    11  //elvdoc:var -instant:binding
    12  //
    13  // Binding for the instant mode.
    14  
    15  //elvdoc:fn -instant:start
    16  //
    17  // Starts the instant mode. In instant mode, any text entered at the command
    18  // line is evaluated immediately, with the output displayed.
    19  //
    20  // **WARNING**: Beware of unintended consequences when using destructive
    21  // commands. For example, if you type `sudo rm -rf /tmp/*` in the instant mode,
    22  // Elvish will attempt to evaluate `sudo rm -rf /` when you typed that far.
    23  
    24  func initInstant(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
    25  	bindingVar := newBindingVar(emptyBindingsMap)
    26  	bindings := newMapBindings(ed, ev, bindingVar)
    27  	nb.AddNs("-instant",
    28  		eval.BuildNsNamed("edit:-instant").
    29  			AddVar("binding", bindingVar).
    30  			AddGoFns(map[string]interface{}{
    31  				"start": func() { instantStart(ed.app, ev, bindings) },
    32  			}))
    33  }
    34  
    35  func instantStart(app cli.App, ev *eval.Evaler, bindings tk.Bindings) {
    36  	execute := func(code string) ([]string, error) {
    37  		outPort, collect, err := eval.StringCapturePort()
    38  		if err != nil {
    39  			return nil, err
    40  		}
    41  		err = ev.Eval(
    42  			parse.Source{Name: "[instant]", Code: code},
    43  			eval.EvalCfg{
    44  				Ports:     []*eval.Port{nil, outPort},
    45  				Interrupt: eval.ListenInterrupts})
    46  		return collect(), err
    47  	}
    48  	w, err := modes.NewInstant(app,
    49  		modes.InstantSpec{Bindings: bindings, Execute: execute})
    50  	if w != nil {
    51  		app.PushAddon(w)
    52  		app.Redraw()
    53  	}
    54  	if err != nil {
    55  		app.Notify(modes.ErrorText(err))
    56  	}
    57  }