working version, maybe add some features

master
Bryan 2023-09-15 06:18:09 -06:00
parent 3704ed9985
commit 82dfdf8df8
2 changed files with 115 additions and 34 deletions

103
cdhist.go
View File

@ -4,42 +4,107 @@ import (
"fmt" "fmt"
"log" "log"
"os" "os"
"strings"
"io" "io"
"bufio" "bufio"
"path/filepath"
) )
func histAdd(histFile string, path string) (error) { func histAdd(histFile string, newPath string) (error) {
data, err := ReadLines(histFile) paths, err := ReadLines(histFile)
if err != nil { if err != nil {
if os.IsNotExist(err) != true { if os.IsNotExist(err) != true {
log.Printf("Error reading cd history file: %v", err) log.Printf("Error reading cd history file: %v", err)
} }
} }
data = append(data, path)
file, err := os.OpenFile(histFile, os.O_RDWR|os.O_CREATE, 0660) file, err := os.OpenFile(histFile, os.O_RDWR|os.O_CREATE, 0660)
if err != nil { if err != nil {
return err return err
} }
defer file.Close() defer file.Close()
for _, line := range data { if err := file.Truncate(0); err != nil {
_, err := file.Write([]byte(fmt.Sprintf("%s\n", line))) return err
if err != nil { }
log.Printf("Error writing cd history file: %v", err) if len(paths) == 0 {
return err 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
}
} }
} }
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) { func histList(histFile string) error {
fmt.Println("List") 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)
}
return var in int
os.Stderr.WriteString("> ")
fmt.Scanln(&in)
if in >= 1 && in <= m {
path := paths[m - in]
cd(histFile, "", path)
}
return nil
} }
func ReadLines(fileName string) (data []string, err error) { 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 s, err := os.Stat(path); os.IsNotExist(err) {
log.Printf("%s: No such directory. %v", path, s)
os.Exit(2)
}
return path
}
func cd(histFile, outString, path string) {
path = sanitizePath(path)
histAdd(histFile, path)
fmt.Printf("%s %s", outString, path)
os.Exit(0)
}
func ReadLines(fileName string) ([]string, error) {
file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0660) file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0660)
if err != nil { if err != nil {
// log.Print(err) // log.Print(err)
@ -48,7 +113,7 @@ func ReadLines(fileName string) (data []string, err error) {
defer file.Close() defer file.Close()
reader := bufio.NewReader(file) reader := bufio.NewReader(file)
var paths []string paths := make([]string,0)
for { for {
line, _, err := reader.ReadLine() line, _, err := reader.ReadLine()
if err != nil { if err != nil {
@ -63,14 +128,14 @@ func ReadLines(fileName string) (data []string, err error) {
} }
// makeBashFunc prints the wrapper function to be sourced by bash // makeBashFunc prints the wrapper function to be sourced by bash
// Copied from https://github.com/bulletmark/cdhist/blob/master/cdhist/cdhist.py
func makeBashFunc() { func makeBashFunc() {
// fmt.Printf("cdh() { local d; d=$(cdhist-v2 \"$@\"); if [ $? -ne 0 ]; then return 0; fi; builtin cd -- \"$d\"; }") fmt.Printf(`cd() {
fmt.Printf(`cdh() {
local d local d
d=$(cdhist-v2 "$@") d=$(cdhist "$@")
if [ $? -ne 0 ]; then return 0 if [ $? -eq 0 ]; then
builtin cd $d
fi fi
builtin cd -- "$d"
}`) }`)
return return
} }

46
main.go
View File

@ -2,42 +2,58 @@ package main
import ( import (
"os" "os"
// "os/exec" "flag"
"log" "log"
"path" "path"
// "syscall"
"fmt" "fmt"
) )
// must run the following to source the cd bash function
// if type cdhist &>/dev/null; then . <(cdhist -i); fi
var ( var (
histFile string = ".cd_history" histFile string = ".cd_history"
outString string = ""
) )
func main() { func main() {
histFileDir, err := os.UserHomeDir() histFileDir, err := os.UserHomeDir()
if err != nil { if err != nil {
log.Fatal(err, "Can't find home directory.") log.Printf("Error reading cd history file: %v", err)
} }
histFile := path.Join(histFileDir, histFile) histFile := path.Join(histFileDir, histFile)
if len(os.Args) > 1 && os.Args[1] == "--" { if len(os.Args) == 2 && os.Args[1] == "--" {
histList(histFile) if err := histList(histFile); err != nil {
os.Exit(1) log.Printf("Error reading cd history file: %s", err)
} }
if len(os.Args) > 1 && os.Args[1] == "-i" {
makeBashFunc()
os.Exit(1) os.Exit(1)
} }
if len(os.Args) > 1 { flagInit := flag.Bool("i", false, "Creates function to be sourced by bash")
path := os.Args[1] flagL := flag.Bool("L", false, "Passed to cd")
histAdd(histFile, path) flagP := flag.Bool("P", false, "Passed to cd")
fmt.Printf("%s", path) flage := flag.Bool("e", false, "Passed to cd")
os.Exit(0) flagAt := flag.Bool("@", false, "Passed to cd")
flag.Parse()
switch {
case *flagInit:
makeBashFunc()
os.Exit(1)
case *flagL:
outString = fmt.Sprintf("%s -L", outString)
case *flagP:
outString = fmt.Sprintf("%s -P", outString)
case *flage:
outString = fmt.Sprintf("%s -e", outString)
case *flagAt:
outString = fmt.Sprintf("%s -@", outString)
} }
path := flag.Arg(0)
cd(histFile, outString, path)
return return
} }