github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+incompatible/cmds/core/elvish/edit/ui/styled.go (about) 1 package ui 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/u-root/u-root/cmds/core/elvish/eval/vals" 8 "github.com/u-root/u-root/cmds/core/elvish/hash" 9 "github.com/u-root/u-root/cmds/core/elvish/parse" 10 "github.com/u-root/u-root/cmds/core/elvish/vector" 11 ) 12 13 // Styled is a piece of text with style. 14 type Styled struct { 15 Text string 16 Styles Styles 17 } 18 19 var styleTranslationTable = map[string]string{ 20 "bold": "1", 21 "dim": "2", 22 "italic": "3", 23 "underlined": "4", 24 "blink": "5", 25 "inverse": "7", 26 27 "black": "30", 28 "red": "31", 29 "green": "32", 30 "yellow": "33", 31 "blue": "34", 32 "magenta": "35", 33 "cyan": "36", 34 "lightgray": "37", 35 "gray": "90", 36 "lightred": "91", 37 "lightgreen": "92", 38 "lightyellow": "93", 39 "lightblue": "94", 40 "lightmagenta": "95", 41 "lightcyan": "96", 42 "white": "97", 43 44 "bg-default": "49", 45 "bg-black": "40", 46 "bg-red": "41", 47 "bg-green": "42", 48 "bg-yellow": "43", 49 "bg-blue": "44", 50 "bg-magenta": "45", 51 "bg-cyan": "46", 52 "bg-lightgray": "47", 53 "bg-gray": "100", 54 "bg-lightred": "101", 55 "bg-lightgreen": "102", 56 "bg-lightyellow": "103", 57 "bg-lightblue": "104", 58 "bg-lightmagenta": "105", 59 "bg-lightcyan": "106", 60 "bg-white": "107", 61 } 62 63 func Unstyled(s string) Styled { 64 return Styled{s, Styles{}} 65 } 66 67 func (s *Styled) Kind() string { 68 return "styled" 69 } 70 71 func (s *Styled) Equal(a interface{}) bool { 72 rhs, ok := a.(*Styled) 73 if !ok { 74 return false 75 } 76 return s.Text == rhs.Text && s.Styles.Eq(rhs.Styles) 77 } 78 79 func (s *Styled) Hash() uint32 { 80 h := hash.DJBInit 81 h = hash.DJBCombine(h, hash.Hash(s.Text)) 82 h = hash.DJBCombine(h, s.Styles.Hash()) 83 return h 84 } 85 86 func (s *Styled) String() string { 87 return "\033[" + s.Styles.String() + "m" + s.Text + "\033[m" 88 } 89 90 func (s *Styled) Repr(indent int) string { 91 quotedStyles := make([]string, len(s.Styles)) 92 for i, st := range s.Styles { 93 quotedStyles[i] = parse.Quote(st) 94 } 95 return fmt.Sprintf("(edit:styled %s [%s]", 96 parse.Quote(s.Text), strings.Join(quotedStyles, " ")) 97 } 98 99 func (s *Styled) Index(k interface{}) (interface{}, bool) { 100 switch k { 101 case "text": 102 return s.Text, true 103 case "styles": 104 li := vector.Empty 105 for _, st := range s.Styles { 106 li = li.Cons(st) 107 } 108 return li, true 109 default: 110 return nil, false 111 } 112 } 113 114 func (s *Styled) IterateKeys(f func(interface{}) bool) { 115 vals.Feed(f, "text", "styles") 116 } 117 118 type Styles []string 119 120 func (ss Styles) Eq(rhs Styles) bool { 121 if len(ss) != len(rhs) { 122 return false 123 } 124 for i, s := range ss { 125 if s != rhs[i] { 126 return false 127 } 128 } 129 return true 130 } 131 132 func (ss Styles) Hash() uint32 { 133 h := hash.DJBInit 134 for _, s := range ss { 135 h = hash.DJBCombine(h, hash.Hash(s)) 136 } 137 return h 138 } 139 140 func JoinStyles(so Styles, st ...Styles) Styles { 141 for _, v := range st { 142 so = append(so, v...) 143 } 144 145 return so 146 } 147 148 func TranslateStyle(s string) string { 149 v, ok := styleTranslationTable[s] 150 if ok { 151 return v 152 } 153 return s 154 } 155 156 func StylesFromString(s string) Styles { 157 var st Styles 158 for _, v := range strings.Split(s, ";") { 159 st = append(st, v) 160 } 161 162 return st 163 } 164 165 func (s Styles) String() string { 166 var o string 167 for i, v := range s { 168 if len(v) > 0 { 169 if i > 0 { 170 o += ";" 171 } 172 o += TranslateStyle(v) 173 } 174 } 175 176 return o 177 }