package main import ( // "os/exec" "fmt" "log" "os" "strings" "io" "bufio" // "path/filepath" "text/template" "cdhist/dir" ) func histAdd(histFile string, newPath string) (error) { paths, err := ReadLines(histFile) if err != nil { if os.IsNotExist(err) != true { log.Printf("Error reading cd history file: %v", err) } } file, err := os.OpenFile(histFile, os.O_RDWR|os.O_CREATE, 0660) if err != nil { return err } defer file.Close() if err := file.Truncate(0); err != nil { return err } if len(paths) == 0 { path, _ := os.Getwd() if err == nil { paths = append(paths, path) } } for _, path := range paths { if strings.Compare(path, newPath) != 0 { _, err := file.Write([]byte(fmt.Sprintf("%s\n", path))) if err != nil { log.Printf("Error writing cd history file: %v", err) return err } } } _, err = file.Write([]byte(fmt.Sprintf("%s\n", newPath))) if err != nil { log.Printf("Error writing cd history file: %v", err) return err } return nil } func histList(histFile string) error { paths, err := ReadLines(histFile) if err != nil { return err } m := len(paths) - 1 for i := 0; i < m; i++ { s := fmt.Sprintf("%d: %s\n",m - i, paths[i]) os.Stderr.WriteString(s) } var in int os.Stderr.WriteString("> ") fmt.Scanln(&in) if in >= 1 && in <= m { path := paths[m - in] cd(histFile, aliasFile, "", path) } return nil } func histListNoPrompt(histFile string) error { paths, err := ReadLines(histFile) if err != nil { return err } for _, p := range(paths) { os.Stdout.WriteString(p) os.Stdout.WriteString("\n") } return nil } func DirAliases(aliasFile string) map[string]string { d, err := ReadLines(aliasFile) if err != nil { log.Printf("Error reading cd alias file: %s", err) } aliases := make(map[string]string) for _, line := range d { l := strings.Split(line, "=") if len(l) == 2 { aliases[strings.TrimSpace(l[0])] = strings.TrimSpace(l[1]) } } return aliases } func cd(histFile, aliasFile, outString, path string) { cleanPath, err := dir.Sanitize(path) if ! dir.Exist(cleanPath) { a := DirAliases(aliasFile) p, prs := a[path] if prs { cleanPath, err = dir.Sanitize(p) } } if err != nil { log.Printf("%s: %s", path, err) os.Exit(3) } histAdd(histFile, cleanPath) fmt.Printf("%s %s", outString, cleanPath) os.Exit(0) } func ReadLines(fileName string) ([]string, error) { file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0660) if err != nil { // log.Print(err) return nil, err } defer file.Close() reader := bufio.NewReader(file) lines := make([]string,0) for { line, _, err := reader.ReadLine() if err != nil { if err == io.EOF { err = nil } break } lines = append(lines, string(line)) } return lines, err } // makeBashFunc prints the wrapper function to be sourced by bash // Copied from https://github.com/bulletmark/cdhist/blob/master/cdhist/cdhist.py func printBashFunc(opts BashFuncOpts) { f := `{{.FuncName}}() { local d local r d=$({{.Command}} "$@") r=$? if [[ $r == 0 ]]; then builtin cd $d elif [[ $r == 2 ]]; then echo -e "$d" fi }` t, err := template.New("t").Parse(f) if err != nil { log.Printf("Error parsing template, %s", err) os.Exit(3) } err = t.Execute(os.Stdout, opts) if err != nil { log.Printf("Error executing template, %s", err) os.Exit(3) } return } /* func sanitizePath(path string) string { switch path { case "-": path = os.Getenv("OLDPWD") case "": var err error // need to do this because the next line won't work using := path, err = os.UserHomeDir() if err != nil { log.Printf("No home directory: %s", err) } } path = strings.TrimSpace(path) path, err := filepath.Abs(path) if err != nil { log.Printf("Invalid path:, %s", err) os.Exit(2) } if _, err := os.Stat(path); os.IsNotExist(err) { log.Printf("%s: No such directory.", path) log.Printf("%v", DirAliases(aliasFile)) os.Exit(2) } return path }*/ // func cdableVars() bool { // v := exec.Command("bash", "-i", "-c", "echo $var") // o, _ := v.Output() // os.Stderr.WriteString(string(o)) // // c := exec.Command("bash", "-i", "-c", "shopt cdable_vars") // out, _ := c.Output() // os.Stderr.WriteString(string(out)) // // return strings.Contains(string(out), "on") // }