/* SHS: Syntactically Homogeneous Shell * Copyright (C) 2019 Aidan Hahn * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package util import ( "fmt" "strings" "io/ioutil" "gitlab.com/whom/shs/log" "gitlab.com/whom/shs/ast" ) // wrap this in a lambda that passes in the vt and ft // I suppose it could be more optimal. Fix if it bothers you func ShellCompleter(line string, vt ast.VarTable, ft ast.FuncTable) []string { var head, tail string idx := strings.LastIndex(line, " ") if idx > 0 { head = line[:idx+1] tail = line[idx+1:] } else { head = "" tail = line } dir, path, tok := getPathBase(tail) compSource := []string{} if !path { dir = "." } else { line = tok } fobjs, err := ioutil.ReadDir(dir) if err != nil { log.Log(log.DEBUG, "couldnt read dir " + dir + ": " + err.Error(), "complete") if path { return nil } } else { for _, f := range fobjs { compSource = append(compSource, dir + "/" + f.Name()) } } if !path { compSource = append(compSource, ast.ListVars(vt)...) compSource = append(compSource, ast.ListFuncs(ft)...) } completions := []string{} for _, i := range compSource { if strings.HasPrefix(i, tail) { completions = append(completions, head + i) } } return completions } // returns everything up to the last '/' // as well as whether or not a / was found // and finally the token after the last / func getPathBase(in string) (string, bool, string) { if in == "" { return "", false, "" } isPath := false i := len(in) - 1 for i > 0 { if in[i] == '/' { isPath = true break } i -= 1 } return in[:i], isPath, in[i+1:] }