-
Notifications
You must be signed in to change notification settings - Fork 23
/
style.go
129 lines (113 loc) · 2.67 KB
/
style.go
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
package commands
import (
"fmt"
"sort"
"github.com/ambientsound/pms/api"
"github.com/ambientsound/pms/input/lexer"
"github.com/gdamore/tcell/v2"
)
// Style manipulates the style table, allowing to set colors and attributes for UI elements.
type Style struct {
newcommand
api api.API
styleKey string
styleValue tcell.Style
background bool
foreground bool
}
// NewStyle returns Style.
func NewStyle(api api.API) Command {
return &Style{
api: api,
}
}
// Parse implements Command.
func (cmd *Style) Parse() error {
// Scan the style key. All names are accepted, even names that are not
// implemented anywhere.
tok, lit := cmd.ScanIgnoreWhitespace()
cmd.setTabCompleteNames(lit)
if tok != lexer.TokenIdentifier {
return fmt.Errorf("Unexpected '%v', expected identifier", lit)
}
cmd.styleKey = lit
// Scan each style attribute.
for {
tok, lit := cmd.Scan()
switch tok {
case lexer.TokenWhitespace:
cmd.setTabCompleteStyles("")
continue
case lexer.TokenIdentifier:
break
case lexer.TokenEnd:
return nil
default:
return fmt.Errorf("Unexpected '%v', expected identifier", lit)
}
cmd.setTabCompleteStyles(lit)
err := cmd.mergeStyle(lit)
if err != nil {
return err
}
}
}
// Exec implements Command.
func (cmd *Style) Exec() error {
styleMap := cmd.api.Styles()
styleMap[cmd.styleKey] = cmd.styleValue
return nil
}
// setTabCompleteNames sets the tab complete list to the list of available style keys.
func (cmd *Style) setTabCompleteNames(lit string) {
styleMap := cmd.api.Styles()
list := make(sort.StringSlice, len(styleMap))
i := 0
for key := range styleMap {
list[i] = key
i++
}
list.Sort()
cmd.setTabComplete(lit, list)
}
// setTabCompleteStyles sets the tab complete list to available styles.
func (cmd *Style) setTabCompleteStyles(lit string) {
list := []string{
"blink",
"bold",
"dim",
"reverse",
"underline",
}
cmd.setTabComplete(lit, list)
}
func (cmd *Style) mergeStyle(lit string) error {
switch lit {
case "blink":
cmd.styleValue = cmd.styleValue.Blink(true)
case "bold":
cmd.styleValue = cmd.styleValue.Bold(true)
case "dim":
cmd.styleValue = cmd.styleValue.Dim(true)
case "reverse":
cmd.styleValue = cmd.styleValue.Reverse(true)
case "underline":
cmd.styleValue = cmd.styleValue.Underline(true)
default:
if lit[0] == '@' {
lit = "#" + lit[1:]
}
color := tcell.GetColor(lit)
switch {
case !cmd.foreground:
cmd.styleValue = cmd.styleValue.Foreground(color)
cmd.foreground = true
case !cmd.background:
cmd.styleValue = cmd.styleValue.Background(color)
cmd.background = true
default:
return fmt.Errorf("Only two color values are allowed per style.")
}
}
return nil
}