Refactor, add alias file support
parent
82dfdf8df8
commit
bbafd7788f
149
cdhist.go
149
cdhist.go
|
|
@ -1,13 +1,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
// "os/exec"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"io"
|
||||
"bufio"
|
||||
"path/filepath"
|
||||
// "path/filepath"
|
||||
"text/template"
|
||||
"cdhist/dir"
|
||||
)
|
||||
|
||||
func histAdd(histFile string, newPath string) (error) {
|
||||
|
|
@ -66,11 +69,93 @@ func histList(histFile string) error {
|
|||
fmt.Scanln(&in)
|
||||
if in >= 1 && in <= m {
|
||||
path := paths[m - in]
|
||||
cd(histFile, "", path)
|
||||
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 "-":
|
||||
|
|
@ -89,53 +174,23 @@ func sanitizePath(path string) string {
|
|||
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)
|
||||
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 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)
|
||||
if err != nil {
|
||||
// log.Print(err)
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
reader := bufio.NewReader(file)
|
||||
paths := make([]string,0)
|
||||
for {
|
||||
line, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
err = nil
|
||||
}
|
||||
break
|
||||
}
|
||||
paths = append(paths, string(line))
|
||||
}
|
||||
return paths, err
|
||||
}
|
||||
|
||||
// makeBashFunc prints the wrapper function to be sourced by bash
|
||||
// Copied from https://github.com/bulletmark/cdhist/blob/master/cdhist/cdhist.py
|
||||
func makeBashFunc() {
|
||||
fmt.Printf(`cd() {
|
||||
local d
|
||||
d=$(cdhist "$@")
|
||||
if [ $? -eq 0 ]; then
|
||||
builtin cd $d
|
||||
fi
|
||||
}`)
|
||||
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")
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
package dir
|
||||
|
||||
import (
|
||||
"os"
|
||||
// "errors"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Exist(path string) bool {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func Sanitize(path string) (string, error) {
|
||||
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 {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
path = strings.TrimSpace(path)
|
||||
path, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return path, nil
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module cdhist/dir
|
||||
|
||||
go 1.20
|
||||
4
go.mod
4
go.mod
|
|
@ -1,3 +1,7 @@
|
|||
module projects/cdhist
|
||||
|
||||
go 1.20
|
||||
|
||||
replace cdhist/dir => ./dir
|
||||
|
||||
require cdhist/dir v0.0.0-00010101000000-000000000000
|
||||
|
|
|
|||
27
main.go
27
main.go
|
|
@ -6,23 +6,32 @@ import (
|
|||
"log"
|
||||
"path"
|
||||
"fmt"
|
||||
// "cdhist/dir"
|
||||
)
|
||||
|
||||
// must run the following to source the cd bash function
|
||||
// if type cdhist &>/dev/null; then . <(cdhist -i); fi
|
||||
|
||||
var (
|
||||
histFile string = ".cd_history"
|
||||
outString string = ""
|
||||
histFile string = ".cd_history"
|
||||
aliasFile string = ".cd_aliases"
|
||||
outString string = ""
|
||||
)
|
||||
|
||||
func main() {
|
||||
type BashFuncOpts struct {
|
||||
Command string
|
||||
FuncName string
|
||||
}
|
||||
|
||||
histFileDir, err := os.UserHomeDir()
|
||||
func main() {
|
||||
// cdableVars()
|
||||
|
||||
dir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
log.Printf("Error reading cd history file: %v", err)
|
||||
}
|
||||
histFile := path.Join(histFileDir, histFile)
|
||||
histFile = path.Join(dir, histFile)
|
||||
aliasFile = path.Join(dir, aliasFile)
|
||||
|
||||
if len(os.Args) == 2 && os.Args[1] == "--" {
|
||||
if err := histList(histFile); err != nil {
|
||||
|
|
@ -40,7 +49,11 @@ func main() {
|
|||
|
||||
switch {
|
||||
case *flagInit:
|
||||
makeBashFunc()
|
||||
name := "cd"
|
||||
if flag.Arg(0) != "" {
|
||||
name = flag.Arg(0)
|
||||
}
|
||||
printBashFunc(BashFuncOpts{FuncName: name, Command: os.Args[0]})
|
||||
os.Exit(1)
|
||||
case *flagL:
|
||||
outString = fmt.Sprintf("%s -L", outString)
|
||||
|
|
@ -53,7 +66,7 @@ func main() {
|
|||
}
|
||||
|
||||
path := flag.Arg(0)
|
||||
cd(histFile, outString, path)
|
||||
cd(histFile, aliasFile, outString, path)
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue