github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/eval/builtin_fn_cmd.go (about) 1 package eval 2 3 import ( 4 "os" 5 "os/exec" 6 7 "github.com/markusbkk/elvish/pkg/eval/errs" 8 ) 9 10 // Command and process control. 11 12 // TODO(xiaq): Document "fg". 13 14 func init() { 15 addBuiltinFns(map[string]interface{}{ 16 // Command resolution 17 "external": external, 18 "has-external": hasExternal, 19 "search-external": searchExternal, 20 21 // Process control 22 "fg": fg, 23 "exec": execFn, 24 "exit": exit, 25 }) 26 } 27 28 //elvdoc:fn external 29 // 30 // ```elvish 31 // external $program 32 // ``` 33 // 34 // Construct a callable value for the external program `$program`. Example: 35 // 36 // ```elvish-transcript 37 // ~> var x = (external man) 38 // ~> $x ls # opens the manpage for ls 39 // ``` 40 // 41 // @cf has-external search-external 42 43 func external(cmd string) Callable { 44 return NewExternalCmd(cmd) 45 } 46 47 //elvdoc:fn has-external 48 // 49 // ```elvish 50 // has-external $command 51 // ``` 52 // 53 // Test whether `$command` names a valid external command. Examples (your output 54 // might differ): 55 // 56 // ```elvish-transcript 57 // ~> has-external cat 58 // ▶ $true 59 // ~> has-external lalala 60 // ▶ $false 61 // ``` 62 // 63 // @cf external search-external 64 65 func hasExternal(cmd string) bool { 66 _, err := exec.LookPath(cmd) 67 return err == nil 68 } 69 70 //elvdoc:fn search-external 71 // 72 // ```elvish 73 // search-external $command 74 // ``` 75 // 76 // Output the full path of the external `$command`. Throws an exception when not 77 // found. Example (your output might vary): 78 // 79 // ```elvish-transcript 80 // ~> search-external cat 81 // ▶ /bin/cat 82 // ``` 83 // 84 // @cf external has-external 85 86 func searchExternal(cmd string) (string, error) { 87 return exec.LookPath(cmd) 88 } 89 90 //elvdoc:fn exit 91 // 92 // ```elvish 93 // exit $status? 94 // ``` 95 // 96 // Exit the Elvish process with `$status` (defaulting to 0). 97 98 func exit(fm *Frame, codes ...int) error { 99 code := 0 100 switch len(codes) { 101 case 0: 102 case 1: 103 code = codes[0] 104 default: 105 return errs.ArityMismatch{What: "arguments", ValidLow: 0, ValidHigh: 1, Actual: len(codes)} 106 } 107 108 preExit(fm) 109 os.Exit(code) 110 // Does not return 111 panic("os.Exit returned") 112 } 113 114 func preExit(fm *Frame) { 115 for _, hook := range fm.Evaler.BeforeExit { 116 hook() 117 } 118 }