cdhist/cdhist.go

186 lines
3.6 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, err := 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 {
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 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")
// }