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