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

     1  package edit
     2  
     3  // This file encapsulates functionality related to a complete REPL cycle. Such as capturing
     4  // information about the most recently executed interactive command.
     5  
     6  import (
     7  	"github.com/markusbkk/elvish/pkg/eval"
     8  	"github.com/markusbkk/elvish/pkg/eval/vals"
     9  	"github.com/markusbkk/elvish/pkg/eval/vars"
    10  	"github.com/markusbkk/elvish/pkg/parse"
    11  )
    12  
    13  //elvdoc:var after-command
    14  //
    15  // A list of functions to call after each interactive command completes. There is one pre-defined
    16  // function used to populate the [`$edit:command-duration`](./edit.html#edit:command-duration)
    17  // variable. Each function is called with a single [map](https://elv.sh/ref/language.html#map)
    18  // argument containing the following keys:
    19  //
    20  // * `src`: Information about the source that was executed, same as what
    21  //   [`src`](builtin.html#src) would output inside the code.
    22  //
    23  // * `duration`: A [floating-point number](https://elv.sh/ref/language.html#number) representing the
    24  // command execution duration in seconds.
    25  //
    26  // * `error`: An [exception](../ref/language.html#exception) object if the command terminated with
    27  // an exception, else [`$nil`](../ref/language.html#nil).
    28  //
    29  // @cf edit:command-duration
    30  
    31  //elvdoc:var command-duration
    32  //
    33  // Duration, in seconds, of the most recent interactive command. This can be useful in your prompt
    34  // to provide feedback on how long a command took to run. The initial value of this variable is the
    35  // time to evaluate your [`rc.elv`](command.html#rc-file) before printing the first prompt.
    36  //
    37  // @cf edit:after-command
    38  
    39  func initRepl(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
    40  	var commandDuration float64
    41  	// TODO: Ensure that this variable can only be written from the Elvish code
    42  	// in elv_init.go.
    43  	nb.AddVar("command-duration", vars.FromPtr(&commandDuration))
    44  
    45  	afterCommandHook := newListVar(vals.EmptyList)
    46  	nb.AddVar("after-command", afterCommandHook)
    47  	ed.AfterCommand = append(ed.AfterCommand,
    48  		func(src parse.Source, duration float64, err error) {
    49  			m := vals.MakeMap("src", src, "duration", duration, "error", err)
    50  			callHooks(ev, "$<edit>:after-command", afterCommandHook.Get().(vals.List), m)
    51  		})
    52  }