okami.mom/albedo

git clone https://git.nkp.pet/okami.mom/albedo

dawntui: show remote paths relative to the host's home, as scp reads themd7df0e6

main
2.2 KiB73 linesraw
1package tui
2
3import (
4	"cmp"
5	"path"
6	"strings"
7
8	"albedo/cli/internal/daemon"
9)
10
11// sessionHost is how a session's host reads: the daemon's label, which
12// leaves out a user ssh would pick anyway, else the host as stored. Local
13// sessions have none.
14func sessionHost(s daemon.Session) string {
15	if s.Location != nil && s.Location.Label != nil {
16		return *s.Location.Label
17	}
18	host, _ := daemon.SplitLocation(s.Workspace)
19	return host
20}
21
22// placeText is a workspace as one line of text: a local path under your
23// home starts with ~, and a remote one leads with its host (label, else as
24// stored), relative to that host's home as scp reads it. home is the path ~
25// names where the workspace is; empty, a local path folds under your own
26// home and a remote one stays whole.
27func placeText(workspace, label, home string) string {
28	host, p := daemon.SplitLocation(workspace)
29	switch {
30	case host != "":
31		return cmp.Or(label, host) + ":" + scpRelative(underHome(p, home))
32	case home == "":
33		return homePath(workspace)
34	}
35	return underHome(workspace, home)
36}
37
38// sessionPlace is where a session works, as placeText shows it.
39func sessionPlace(s daemon.Session) string {
40	return placeText(s.Workspace, sessionHost(s), "")
41}
42
43// splitHost reads typed text as a location still being written: the host
44// before the first colon and whatever follows it, which may be empty, ~ or
45// relative to the remote home as well as absolute. Like the daemon's rule,
46// text starting with / or ~, or with a slash before the colon, is local.
47func splitHost(text string) (host, rest string, ok bool) {
48	if text == "" || text[0] == '/' || text[0] == '~' {
49		return "", text, false
50	}
51	if i := strings.Index(text, "]:"); text[0] == '[' && i > 0 {
52		return text[:i+1], text[i+2:], true
53	}
54	host, rest, ok = strings.Cut(text, ":")
55	if !ok || host == "" || strings.Contains(host, "/") {
56		return "", text, false
57	}
58	return host, rest, true
59}
60
61// joinPlace is the folder name inside the location dir.
62func joinPlace(dir, name string) string {
63	host, p := daemon.SplitLocation(dir)
64	if host == "" {
65		return path.Join(dir, name)
66	}
67	return host + ":" + path.Join(p, name)
68}
69
70// parentPlace is the folder above the location dir, on the same host.
71func parentPlace(dir string) string {
72	return joinPlace(dir, "..")
73}