1package main
2
3import (
4	"log"
5	"os"
6	"path/filepath"
7	"strings"
8)
9
10type iconMap map[string]string
11
12func parseIcons() iconMap {
13	im := make(iconMap)
14
15	defaultIcons := []string{
16		"fi=��",
17		"di=��",
18		"ln=��",
19		"pi=��",
20		"so=��",
21		"bd=��",
22		"cd=��",
23		"or=��",
24		"su=��",
25		"sg=��",
26		"tw=��",
27		"ow=��",
28		"st=��",
29		"ex=��",
30	}
31
32	im.parseEnv(strings.Join(defaultIcons, ":"))
33
34	if env := os.Getenv("LF_ICONS"); env != "" {
35		im.parseEnv(env)
36	}
37
38	return im
39}
40
41func (im iconMap) parseEnv(env string) {
42	for _, entry := range strings.Split(env, ":") {
43		if entry == "" {
44			continue
45		}
46
47		pair := strings.Split(entry, "=")
48
49		if len(pair) != 2 {
50			log.Printf("invalid $LF_ICONS entry: %s", entry)
51			return
52		}
53
54		key, val := pair[0], pair[1]
55
56		key = replaceTilde(key)
57
58		if filepath.IsAbs(key) {
59			key = filepath.Clean(key)
60		}
61
62		im[key] = val
63	}
64}
65
66func (im iconMap) get(f *file) string {
67	if val, ok := im[f.path]; ok {
68		return val
69	}
70
71	if f.IsDir() {
72		if val, ok := im[f.Name()+"/"]; ok {
73			return val
74		}
75	}
76
77	var key string
78
79	switch {
80	case f.linkState == working:
81		key = "ln"
82	case f.linkState == broken:
83		key = "or"
84	case f.IsDir() && f.Mode()&os.ModeSticky != 0 && f.Mode()&0002 != 0:
85		key = "tw"
86	case f.IsDir() && f.Mode()&0002 != 0:
87		key = "ow"
88	case f.IsDir() && f.Mode()&os.ModeSticky != 0:
89		key = "st"
90	case f.IsDir():
91		key = "di"
92	case f.Mode()&os.ModeNamedPipe != 0:
93		key = "pi"
94	case f.Mode()&os.ModeSocket != 0:
95		key = "so"
96	case f.Mode()&os.ModeDevice != 0:
97		key = "bd"
98	case f.Mode()&os.ModeCharDevice != 0:
99		key = "cd"
100	case f.Mode()&os.ModeSetuid != 0:
101		key = "su"
102	case f.Mode()&os.ModeSetgid != 0:
103		key = "sg"
104	case f.Mode()&0111 != 0:
105		key = "ex"
106	}
107
108	if val, ok := im[key]; ok {
109		return val
110	}
111
112	if val, ok := im[f.Name()+"*"]; ok {
113		return val
114	}
115
116	if val, ok := im[filepath.Base(f.Name())+".*"]; ok {
117		return val
118	}
119
120	if val, ok := im["*"+f.ext]; ok {
121		return val
122	}
123
124	if val, ok := im["fi"]; ok {
125		return val
126	}
127
128	return " "
129}
130