all repos

viye @ 6c40e2014488fdd2786ef09056c129439fef701f

my shot at reimplementing xiki

viye/internal/plumbing/files/files.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
resturcture + tests + expand shell, 2 months ago
1
package files
2
3
import (
4
	"os"
5
	"path/filepath"
6
	"strings"
7
8
	"github.com/olexsmir/viye/internal/osutil"
9
	"github.com/olexsmir/viye/internal/viye"
10
)
11
12
type Tool struct{}
13
14
// TODO: add ./ paths support
15
16
func (Tool) Name() string { return "files(~/..., /...)" }
17
18
func (Tool) Match(ctx *viye.Context) bool {
19
	p := ctx.Path[0]
20
	if p == "~" || strings.HasPrefix(p, "/") {
21
		return true
22
	}
23
	_, err := os.Stat(filepath.Join(ctx.Dir, p))
24
	return err == nil
25
}
26
27
func (Tool) Execute(ctx *viye.Context) (string, error) {
28
	path := resolve(ctx.Path[0], ctx.Dir)
29
30
	info, err := os.Stat(path)
31
	if err != nil {
32
		return "", err
33
	}
34
35
	switch {
36
	case info.IsDir():
37
		if len(ctx.Path) == 1 {
38
			return listDir(path)
39
		}
40
		ctx.Dir = path
41
		ctx.Path = ctx.Path[1:]
42
		return ctx.Next()
43
44
	// case info.Mode()&0o111 != 0:
45
	// 	return runExec(path)
46
47
	default:
48
		return "", osutil.Open(path)
49
	}
50
}
51
52
func resolve(p, dir string) string {
53
	if p == "~" {
54
		home, _ := os.UserHomeDir()
55
		return home
56
	}
57
	if strings.HasPrefix(p, "~/") {
58
		home, _ := os.UserHomeDir()
59
		return filepath.Join(home, p[2:])
60
	}
61
	if filepath.IsAbs(p) {
62
		return filepath.Clean(p)
63
	}
64
	return filepath.Join(dir, p)
65
}
66
67
func listDir(dir string) (string, error) {
68
	entries, err := os.ReadDir(dir)
69
	if err != nil {
70
		return "", err
71
	}
72
	var b strings.Builder
73
	for _, e := range entries {
74
		name := e.Name()
75
		if e.IsDir() {
76
			name += "/"
77
		}
78
		b.WriteString(name)
79
		b.WriteByte('\n')
80
	}
81
	return b.String(), nil
82
}
83
84
// func runExec(path string) (string, error) {
85
// 	cmd := exec.Command(path)
86
// 	out, err := cmd.Output()
87
// 	if err != nil {
88
// 		return "", err
89
// 	}
90
// 	return string(out), nil
91
// }