Refactor, add alias file support
parent
82dfdf8df8
commit
bbafd7788f
149
cdhist.go
149
cdhist.go
|
|
@ -1,13 +1,16 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
// "os/exec"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"io"
|
"io"
|
||||||
"bufio"
|
"bufio"
|
||||||
"path/filepath"
|
// "path/filepath"
|
||||||
|
"text/template"
|
||||||
|
"cdhist/dir"
|
||||||
)
|
)
|
||||||
|
|
||||||
func histAdd(histFile string, newPath string) (error) {
|
func histAdd(histFile string, newPath string) (error) {
|
||||||
|
|
@ -66,11 +69,93 @@ func histList(histFile string) error {
|
||||||
fmt.Scanln(&in)
|
fmt.Scanln(&in)
|
||||||
if in >= 1 && in <= m {
|
if in >= 1 && in <= m {
|
||||||
path := paths[m - in]
|
path := paths[m - in]
|
||||||
cd(histFile, "", path)
|
cd(histFile, aliasFile, "", path)
|
||||||
}
|
}
|
||||||
return nil
|
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 {
|
func sanitizePath(path string) string {
|
||||||
switch path {
|
switch path {
|
||||||
case "-":
|
case "-":
|
||||||
|
|
@ -89,53 +174,23 @@ func sanitizePath(path string) string {
|
||||||
log.Printf("Invalid path:, %s", err)
|
log.Printf("Invalid path:, %s", err)
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
if s, err := os.Stat(path); os.IsNotExist(err) {
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||||
log.Printf("%s: No such directory. %v", path, s)
|
log.Printf("%s: No such directory.", path)
|
||||||
|
log.Printf("%v", DirAliases(aliasFile))
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
return path
|
return path
|
||||||
}
|
}*/
|
||||||
|
|
||||||
func cd(histFile, outString, path string) {
|
// func cdableVars() bool {
|
||||||
path = sanitizePath(path)
|
// v := exec.Command("bash", "-i", "-c", "echo $var")
|
||||||
histAdd(histFile, path)
|
// o, _ := v.Output()
|
||||||
fmt.Printf("%s %s", outString, path)
|
// os.Stderr.WriteString(string(o))
|
||||||
os.Exit(0)
|
//
|
||||||
}
|
// c := exec.Command("bash", "-i", "-c", "shopt cdable_vars")
|
||||||
|
// out, _ := c.Output()
|
||||||
func ReadLines(fileName string) ([]string, error) {
|
// os.Stderr.WriteString(string(out))
|
||||||
file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0660)
|
//
|
||||||
if err != nil {
|
// return strings.Contains(string(out), "on")
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
module projects/cdhist
|
||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
|
replace cdhist/dir => ./dir
|
||||||
|
|
||||||
|
require cdhist/dir v0.0.0-00010101000000-000000000000
|
||||||
|
|
|
||||||
23
main.go
23
main.go
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"path"
|
"path"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
// "cdhist/dir"
|
||||||
)
|
)
|
||||||
|
|
||||||
// must run the following to source the cd bash function
|
// must run the following to source the cd bash function
|
||||||
|
|
@ -13,16 +14,24 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
histFile string = ".cd_history"
|
histFile string = ".cd_history"
|
||||||
|
aliasFile string = ".cd_aliases"
|
||||||
outString string = ""
|
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 {
|
if err != nil {
|
||||||
log.Printf("Error reading cd history file: %v", err)
|
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 len(os.Args) == 2 && os.Args[1] == "--" {
|
||||||
if err := histList(histFile); err != nil {
|
if err := histList(histFile); err != nil {
|
||||||
|
|
@ -40,7 +49,11 @@ func main() {
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case *flagInit:
|
case *flagInit:
|
||||||
makeBashFunc()
|
name := "cd"
|
||||||
|
if flag.Arg(0) != "" {
|
||||||
|
name = flag.Arg(0)
|
||||||
|
}
|
||||||
|
printBashFunc(BashFuncOpts{FuncName: name, Command: os.Args[0]})
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
case *flagL:
|
case *flagL:
|
||||||
outString = fmt.Sprintf("%s -L", outString)
|
outString = fmt.Sprintf("%s -L", outString)
|
||||||
|
|
@ -53,7 +66,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
path := flag.Arg(0)
|
path := flag.Arg(0)
|
||||||
cd(histFile, outString, path)
|
cd(histFile, aliasFile, outString, path)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue