2018-02-03 14:12:13 +08:00
|
|
|
package eval
|
|
|
|
|
|
|
|
import (
|
|
|
|
"runtime"
|
|
|
|
|
2020-04-26 01:26:17 +08:00
|
|
|
"github.com/elves/elvish/pkg/parse"
|
2019-12-24 04:00:59 +08:00
|
|
|
"github.com/elves/elvish/pkg/util"
|
2018-02-03 14:12:13 +08:00
|
|
|
)
|
|
|
|
|
2020-01-18 21:12:50 +08:00
|
|
|
//elvdoc:fn src
|
|
|
|
//
|
|
|
|
// ```elvish
|
|
|
|
// src
|
|
|
|
// ```
|
|
|
|
//
|
|
|
|
// Output a map-like value describing the current source being evaluated. The value
|
|
|
|
// contains the following fields:
|
|
|
|
//
|
2020-04-25 19:50:07 +08:00
|
|
|
// - `name`, a unique name of the current source. If the source originates from a
|
|
|
|
// file, it is the full path of the file.
|
2020-01-18 21:12:50 +08:00
|
|
|
//
|
2020-04-25 19:50:07 +08:00
|
|
|
// - `code`, the full body of the current source.
|
2020-01-18 21:12:50 +08:00
|
|
|
//
|
2020-04-25 19:50:07 +08:00
|
|
|
// - `is-file`, whether the source originates from a file.
|
2020-01-18 21:12:50 +08:00
|
|
|
//
|
|
|
|
// Examples:
|
|
|
|
//
|
|
|
|
// ```elvish-transcript
|
2020-04-25 19:50:07 +08:00
|
|
|
// ~> put (src)[name code is-file]
|
|
|
|
// ▶ '[tty]'
|
|
|
|
// ▶ 'put (src)[name code is-file]'
|
|
|
|
// ▶ $false
|
|
|
|
// ~> echo 'put (src)[name code is-file]' > show-src.elv
|
|
|
|
// ~> elvish show-src.elv
|
|
|
|
// ▶ /home/elf/show-src.elv
|
|
|
|
// ▶ "put (src)[name code is-file]\n"
|
|
|
|
// ▶ $true
|
|
|
|
//
|
|
|
|
// Note: this builtin always returns information of the source of the function
|
|
|
|
// calling `src`. Consider the following example:
|
2020-01-18 21:12:50 +08:00
|
|
|
//
|
|
|
|
// ```elvish-transcript
|
2020-04-25 19:50:07 +08:00
|
|
|
// ~> echo 'fn show { put (src)[name] }' > ~/.elvish/lib/src-util.elv
|
|
|
|
// ~> use src-util
|
|
|
|
// ~> src-util:show
|
|
|
|
// ▶ /home/elf/.elvish/lib/src-util.elv
|
2020-01-18 21:12:50 +08:00
|
|
|
// ```
|
|
|
|
|
|
|
|
//elvdoc:fn -gc
|
|
|
|
//
|
|
|
|
// ```elvish
|
|
|
|
// -gc
|
|
|
|
// ```
|
|
|
|
//
|
|
|
|
// Force the Go garbage collector to run.
|
|
|
|
//
|
|
|
|
// This is only useful for debug purposes.
|
|
|
|
|
|
|
|
//elvdoc:fn -stack
|
|
|
|
//
|
|
|
|
// ```elvish
|
|
|
|
// -stack
|
|
|
|
// ```
|
|
|
|
//
|
|
|
|
// Print a stack trace.
|
|
|
|
//
|
|
|
|
// This is only useful for debug purposes.
|
|
|
|
|
|
|
|
//elvdoc:fn -log
|
|
|
|
//
|
|
|
|
// ```elvish
|
|
|
|
// -log $filename
|
|
|
|
// ```
|
|
|
|
//
|
|
|
|
// Direct internal debug logs to the named file.
|
|
|
|
//
|
|
|
|
// This is only useful for debug purposes.
|
|
|
|
|
2018-02-03 14:12:13 +08:00
|
|
|
func init() {
|
2018-02-07 03:39:40 +08:00
|
|
|
addBuiltinFns(map[string]interface{}{
|
2018-02-04 14:30:36 +08:00
|
|
|
"src": src,
|
|
|
|
"-gc": _gc,
|
|
|
|
"-stack": _stack,
|
|
|
|
"-log": _log,
|
2018-02-03 14:12:13 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-04-26 02:22:38 +08:00
|
|
|
func src(fm *Frame) parse.Source {
|
2018-03-01 10:17:56 +08:00
|
|
|
return fm.srcMeta
|
2018-02-03 14:12:13 +08:00
|
|
|
}
|
|
|
|
|
2018-02-04 14:30:36 +08:00
|
|
|
func _gc() {
|
2018-02-03 14:12:13 +08:00
|
|
|
runtime.GC()
|
|
|
|
}
|
|
|
|
|
2018-03-01 10:17:56 +08:00
|
|
|
func _stack(fm *Frame) {
|
|
|
|
out := fm.ports[1].File
|
2020-08-09 11:42:32 +08:00
|
|
|
// TODO(xiaq): Dup with main.go.
|
2018-02-03 14:12:13 +08:00
|
|
|
buf := make([]byte, 1024)
|
|
|
|
for runtime.Stack(buf, true) == cap(buf) {
|
|
|
|
buf = make([]byte, cap(buf)*2)
|
|
|
|
}
|
|
|
|
out.Write(buf)
|
|
|
|
}
|
|
|
|
|
2018-02-04 14:30:36 +08:00
|
|
|
func _log(fname string) error {
|
|
|
|
return util.SetOutputFile(fname)
|
2018-02-03 14:12:13 +08:00
|
|
|
}
|