197 lines
4.0 KiB
Go
197 lines
4.0 KiB
Go
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 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(2)
|
|
}
|
|
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
|
|
d=$({{.Command}} "$@")
|
|
if [ $? -eq 0 ]; then
|
|
builtin cd $d
|
|
fi
|
|
}`
|
|
t, err := template.New("t").Parse(f)
|
|
if err != nil {
|
|
log.Printf("Error parsing template, %s", err)
|
|
os.Exit(2)
|
|
}
|
|
err = t.Execute(os.Stderr, opts)
|
|
if err != nil {
|
|
log.Printf("Error executing template, %s", err)
|
|
os.Exit(2)
|
|
}
|
|
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")
|
|
// }
|