-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathabbreviations.go
More file actions
136 lines (123 loc) · 2.82 KB
/
abbreviations.go
File metadata and controls
136 lines (123 loc) · 2.82 KB
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package main
import (
"os"
"os/user"
"strings"
"github.com/fatih/color"
)
func getUserHome() []string {
home := os.Getenv("HOME")
if home != "" {
return strings.Split(home, "/")
}
usr, err := user.Current()
if err != nil {
return []string{"non-matching sentinel value", "&\\!`\\\\$'"}
} else {
return []string{"", "home", usr.Username}
}
}
func promptStartsWith(prompt Prompt, prefix []string) bool {
if len(prefix) > len(prompt) {
return false
}
for i, name := range prefix {
if name != prompt[i].Name {
return false
}
}
return true
}
func ShadowHome(prompt Prompt) {
home := getUserHome()
if promptStartsWith(prompt, home) {
for i := range home {
prompt[i].Shadowed = true
prompt[i].Abbreviation = ""
}
prompt[len(home)-1].Abbreviation = "~"
prompt[len(home)-1].NameStyle = []color.Attribute{color.FgYellow}
}
}
func GetCharsToCut(prompt Prompt, maxSize int) int {
totalChars := 0
for _, part := range prompt {
totalChars += len(part.Abbreviation)
if !part.Shadowed {
totalChars += 1
}
}
var charsToCut int
if totalChars > maxSize {
charsToCut = totalChars - maxSize
} else {
charsToCut = 0
}
return charsToCut
}
type TruncationTarget struct {
maxSize int
nMaxSize int
nOneLess int
}
func getSizeCounts(prompt Prompt) (map[int]int, int) {
sizeCounts := make(map[int]int)
maxSize := 0
for _, part := range prompt {
sizeCounts[len(part.Abbreviation)] += 1
if len(part.Abbreviation) > maxSize {
maxSize = len(part.Abbreviation)
}
}
return sizeCounts, maxSize
}
func getTruncationTarget(sizeCounts map[int]int, maxSize, charsToCut int) TruncationTarget {
ret := TruncationTarget{
maxSize,
sizeCounts[maxSize],
sizeCounts[maxSize-1],
}
for charsToCut > 0 && ret.maxSize > 1 {
if ret.nMaxSize == 0 {
ret.maxSize -= 1
ret.nMaxSize = ret.nOneLess
ret.nOneLess = sizeCounts[ret.maxSize-1]
} else {
ret.nMaxSize -= 1
ret.nOneLess += 1
charsToCut -= 1
}
}
return ret
}
func GetTruncationTarget(prompt Prompt, charsToCut int) TruncationTarget {
sizeCounts, maxSize := getSizeCounts(prompt)
return getTruncationTarget(sizeCounts, maxSize, charsToCut)
}
func (tt *TruncationTarget) Decrement() {
if tt.nOneLess > 0 {
tt.nOneLess -= 1
} else {
tt.nMaxSize -= 1
}
}
func (tt TruncationTarget) TargetSize() int {
if tt.nOneLess > 0 {
return tt.maxSize - 1
} else {
return tt.maxSize
}
}
func SetAbbreviations(prompt Prompt, tt TruncationTarget) {
for _, part := range prompt {
if tt.nMaxSize > 0 && len(part.Abbreviation) == tt.maxSize {
tt.nMaxSize -= 1
} else if tt.nOneLess > 0 && len(part.Abbreviation) == tt.maxSize-1 {
tt.nOneLess -= 1
} else if len(part.Abbreviation) > tt.TargetSize() {
part.Abbreviation = part.Abbreviation[:tt.TargetSize()]
part.SlashStyle = []color.Attribute{color.CrossedOut}
tt.Decrement()
}
}
}