func complFormHeadInner(head string, ed *Editor) ([]*candidate, error) { if util.DontSearch(head) { return complFilenameInner(head, true) } var commands []string got := func(s string) { if strings.HasPrefix(s, head) { commands = append(commands, s) } } for special := range isBuiltinSpecial { got(special) } splice, ns, _ := eval.ParseVariable(head) iterateVariables(ed.evaler, ns, func(varname string) { if strings.HasPrefix(varname, eval.FnPrefix) { got(eval.MakeVariableName(splice, ns, varname[len(eval.FnPrefix):])) } }) for command := range ed.isExternal { got(command) } sort.Strings(commands) cands := []*candidate{} for _, cmd := range commands { cands = append(cands, &candidate{text: cmd}) } return cands, nil }
func goodFormHead(head string, ed *Editor) bool { if isBuiltinSpecial[head] { return true } else if util.DontSearch(head) { // XXX don't stat twice return util.IsExecutable(head) || isDir(head) } else { explode, ns, name := eval.ParseVariable(head) if !explode { switch ns { case "": if eval.Builtin()[eval.FnPrefix+name] != nil || ed.evaler.Global[eval.FnPrefix+name] != nil { return true } case "e": if ed.isExternal[name] { return true } default: if ed.evaler.Modules[ns] != nil && ed.evaler.Modules[ns][eval.FnPrefix+name] != nil { return true } } } return ed.isExternal[head] } }
// Call calls an external command. func (e ExternalCmd) Call(ec *EvalCtx, argVals []Value, opts map[string]Value) { if len(opts) > 0 { throw(ErrExternalCmdOpts) } if util.DontSearch(e.Name) { stat, err := os.Stat(e.Name) if err == nil && stat.IsDir() { // implicit cd if len(argVals) > 0 { throw(ErrCdNoArg) } cdInner(e.Name, ec) return } } files := make([]uintptr, len(ec.ports)) for i, port := range ec.ports { if port == nil || port.File == nil { files[i] = fdNil } else { files[i] = port.File.Fd() } } args := make([]string, len(argVals)+1) for i, a := range argVals { // NOTE Maybe we should enfore string arguments instead of coercing all // args into string args[i+1] = ToString(a) } sys := syscall.SysProcAttr{Setpgid: ec.background} attr := syscall.ProcAttr{Env: os.Environ(), Files: files[:], Sys: &sys} path, err := ec.Search(e.Name) if err != nil { throw(err) } args[0] = path pid, err := syscall.ForkExec(path, args, &attr) if err != nil { throw(errors.New("forkExec: " + err.Error())) } var ws syscall.WaitStatus _, err = syscall.Wait4(pid, &ws, syscall.WUNTRACED, nil) if err != nil { throw(fmt.Errorf("wait: %s", err.Error())) } else { maybeThrow(NewExternalCmdExit(e.Name, ws, pid)) } }
func goodFormHead(head string, ed *Editor) bool { if isBuiltinSpecial[head] { return true } else if util.DontSearch(head) { // XXX don't stat twice return util.IsExecutable(head) || isDir(head) } else { _, ns, head := eval.ParseVariable(head) if ns == "" { return ed.isExternal[head] || eval.Builtin()[eval.FnPrefix+head] != nil || ed.evaler.Global[eval.FnPrefix+head] != nil } else { return ed.evaler.Modules[ns] != nil && ed.evaler.Modules[ns][eval.FnPrefix+head] != nil } } }
func complFormHeadInner(head string, ed *Editor) ([]*candidate, error) { if util.DontSearch(head) { return complFilenameInner(head, true) } var commands []string got := func(s string) { if strings.HasPrefix(s, head) { commands = append(commands, s) } } for special := range isBuiltinSpecial { got(special) } explode, ns, _ := eval.ParseVariable(head) if !explode { iterateVariables(ed.evaler, ns, func(varname string) { if strings.HasPrefix(varname, eval.FnPrefix) { got(eval.MakeVariableName(false, ns, varname[len(eval.FnPrefix):])) } else { got(eval.MakeVariableName(false, ns, varname) + "=") } }) } for command := range ed.isExternal { got(command) if strings.HasPrefix(head, "e:") { got("e:" + command) } } // TODO Support non-module namespaces. for ns := range ed.evaler.Modules { if head != ns+":" { got(ns + ":") } } sort.Strings(commands) cands := []*candidate{} for _, cmd := range commands { cands = append(cands, &candidate{text: cmd}) } return cands, nil }