summaryrefslogtreecommitdiff
path: root/internal/xdg/xdg.go
blob: be1365099306a890739bbf244f6865ae34a7b0e2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// SPDX-License-Identifier: GPL-3.0-or-later

// Package xdg resolves the XDG base directories and expands ~ in paths.
package xdg

import (
	"os"
	"path/filepath"
	"strings"
)

// ConfigHome is $XDG_CONFIG_HOME, or ~/.config.
func ConfigHome() string { return base("XDG_CONFIG_HOME", ".config") }

// StateHome is $XDG_STATE_HOME, or ~/.local/state.
func StateHome() string { return base("XDG_STATE_HOME", filepath.Join(".local", "state")) }

// DataHome is $XDG_DATA_HOME, or ~/.local/share.
func DataHome() string { return base("XDG_DATA_HOME", filepath.Join(".local", "share")) }

// CacheHome is $XDG_CACHE_HOME, or ~/.cache.
func CacheHome() string { return base("XDG_CACHE_HOME", ".cache") }

// base follows the XDG rule that a relative value is invalid and ignored.
func base(env, fallback string) string {
	if v := os.Getenv(env); filepath.IsAbs(v) {
		return filepath.Clean(v)
	}
	return filepath.Join(Home(), fallback)
}

// Home is the user's home directory, or "/" when it is unknown.
func Home() string {
	if h, err := os.UserHomeDir(); err == nil && h != "" {
		return filepath.Clean(h)
	}
	return "/"
}

// Expand replaces a leading "~" or "~/" with the home directory.
// "~user" is left alone.
func Expand(p string) string {
	if p == "~" {
		return Home()
	}
	if strings.HasPrefix(p, "~/") {
		return filepath.Join(Home(), p[2:])
	}
	return p
}

// Abbrev replaces a leading home directory with "~", for display and for
// paths written into config files.
func Abbrev(p string) string {
	h := Home()
	if p == h {
		return "~"
	}
	if h != "/" && strings.HasPrefix(p, h+"/") {
		return "~/" + p[len(h)+1:]
	}
	return p
}