github.com/aretext/aretext@v1.3.0/display/palette.go (about) 1 package display 2 3 import ( 4 "log" 5 6 "github.com/gdamore/tcell/v2" 7 8 "github.com/aretext/aretext/config" 9 "github.com/aretext/aretext/state" 10 "github.com/aretext/aretext/syntax/parser" 11 ) 12 13 // Palette controls the style of displayed text. 14 type Palette struct { 15 lineNumStyle tcell.Style 16 selectionStyle tcell.Style 17 searchMatchStyle tcell.Style 18 searchCursorStyle tcell.Style 19 statusMsgSuccessStyle tcell.Style 20 statusMsgErrorStyle tcell.Style 21 statusInputModeStyle tcell.Style 22 statusInputBufferStyle tcell.Style 23 statusRecordingMacroStyle tcell.Style 24 statusFilePathStyle tcell.Style 25 menuBorderStyle tcell.Style 26 menuIconStyle tcell.Style 27 menuPromptStyle tcell.Style 28 menuQueryStyle tcell.Style 29 menuCursorStyle tcell.Style 30 menuItemSelectedStyle tcell.Style 31 menuItemUnselectedStyle tcell.Style 32 textFieldPromptStyle tcell.Style 33 textFieldInputTextStyle tcell.Style 34 textFieldBorderStyle tcell.Style 35 searchPrefixStyle tcell.Style 36 searchQueryStyle tcell.Style 37 tokenRoleStyle map[parser.TokenRole]tcell.Style 38 } 39 40 func NewPalette() *Palette { 41 s := tcell.StyleDefault 42 return &Palette{ 43 lineNumStyle: s.Foreground(tcell.ColorOlive), 44 selectionStyle: s.Reverse(true).Dim(true), 45 searchMatchStyle: s.Reverse(true), 46 searchCursorStyle: s.Reverse(true).Dim(true), 47 statusMsgSuccessStyle: s.Foreground(tcell.ColorGreen).Bold(true), 48 statusMsgErrorStyle: s.Background(tcell.ColorMaroon).Foreground(tcell.ColorWhite).Bold(true), 49 statusInputModeStyle: s.Bold(true), 50 statusInputBufferStyle: s.Bold(true), 51 statusRecordingMacroStyle: s.Bold(true), 52 statusFilePathStyle: s.Bold(true), 53 menuBorderStyle: s.Dim(true), 54 menuIconStyle: s, 55 menuPromptStyle: s.Dim(true), 56 menuQueryStyle: s, 57 menuCursorStyle: s.Bold(true), 58 menuItemSelectedStyle: s.Underline(true), 59 menuItemUnselectedStyle: s, 60 textFieldPromptStyle: s.Dim(true), 61 textFieldInputTextStyle: s, 62 textFieldBorderStyle: s, 63 searchPrefixStyle: s, 64 searchQueryStyle: s, 65 tokenRoleStyle: map[parser.TokenRole]tcell.Style{ 66 parser.TokenRoleOperator: s.Foreground(tcell.ColorPurple), 67 parser.TokenRoleKeyword: s.Foreground(tcell.ColorOlive), 68 parser.TokenRoleNumber: s.Foreground(tcell.ColorGreen), 69 parser.TokenRoleString: s.Foreground(tcell.ColorMaroon), 70 parser.TokenRoleComment: s.Foreground(tcell.ColorNavy), 71 parser.TokenRoleCustom1: s.Foreground(tcell.ColorTeal), 72 parser.TokenRoleCustom2: s.Foreground(tcell.ColorDarkBlue), 73 parser.TokenRoleCustom3: s.Foreground(tcell.ColorRed), 74 parser.TokenRoleCustom4: s.Foreground(tcell.ColorLime), 75 parser.TokenRoleCustom5: s.Foreground(tcell.ColorFuchsia), 76 parser.TokenRoleCustom6: s.Foreground(tcell.ColorAqua), 77 parser.TokenRoleCustom7: s.Foreground(tcell.ColorDarkGreen), 78 parser.TokenRoleCustom8: s.Foreground(tcell.ColorDarkCyan), 79 parser.TokenRoleCustom9: s.Foreground(tcell.ColorTeal), 80 parser.TokenRoleCustom10: s.Foreground(tcell.ColorDarkBlue), 81 parser.TokenRoleCustom11: s.Foreground(tcell.ColorRed), 82 parser.TokenRoleCustom12: s.Foreground(tcell.ColorLime), 83 parser.TokenRoleCustom13: s.Foreground(tcell.ColorFuchsia), 84 parser.TokenRoleCustom14: s.Foreground(tcell.ColorAqua), 85 parser.TokenRoleCustom15: s.Foreground(tcell.ColorDarkGreen), 86 parser.TokenRoleCustom16: s.Foreground(tcell.ColorDarkCyan), 87 }, 88 } 89 } 90 91 func NewPaletteFromConfigStyles(styles map[string]config.StyleConfig) *Palette { 92 p := NewPalette() 93 for k, v := range styles { 94 s := styleFromConfig(v) 95 switch k { 96 case config.StyleLineNum: 97 p.lineNumStyle = s 98 case config.StyleTokenOperator: 99 p.tokenRoleStyle[parser.TokenRoleOperator] = s 100 case config.StyleTokenKeyword: 101 p.tokenRoleStyle[parser.TokenRoleKeyword] = s 102 case config.StyleTokenNumber: 103 p.tokenRoleStyle[parser.TokenRoleNumber] = s 104 case config.StyleTokenString: 105 p.tokenRoleStyle[parser.TokenRoleString] = s 106 case config.StyleTokenComment: 107 p.tokenRoleStyle[parser.TokenRoleComment] = s 108 case config.StyleTokenCustom1: 109 p.tokenRoleStyle[parser.TokenRoleCustom1] = s 110 case config.StyleTokenCustom2: 111 p.tokenRoleStyle[parser.TokenRoleCustom2] = s 112 case config.StyleTokenCustom3: 113 p.tokenRoleStyle[parser.TokenRoleCustom3] = s 114 case config.StyleTokenCustom4: 115 p.tokenRoleStyle[parser.TokenRoleCustom4] = s 116 case config.StyleTokenCustom5: 117 p.tokenRoleStyle[parser.TokenRoleCustom5] = s 118 case config.StyleTokenCustom6: 119 p.tokenRoleStyle[parser.TokenRoleCustom6] = s 120 case config.StyleTokenCustom7: 121 p.tokenRoleStyle[parser.TokenRoleCustom7] = s 122 case config.StyleTokenCustom8: 123 p.tokenRoleStyle[parser.TokenRoleCustom8] = s 124 case config.StyleTokenCustom9: 125 p.tokenRoleStyle[parser.TokenRoleCustom9] = s 126 case config.StyleTokenCustom10: 127 p.tokenRoleStyle[parser.TokenRoleCustom10] = s 128 case config.StyleTokenCustom11: 129 p.tokenRoleStyle[parser.TokenRoleCustom11] = s 130 case config.StyleTokenCustom12: 131 p.tokenRoleStyle[parser.TokenRoleCustom12] = s 132 case config.StyleTokenCustom13: 133 p.tokenRoleStyle[parser.TokenRoleCustom13] = s 134 case config.StyleTokenCustom14: 135 p.tokenRoleStyle[parser.TokenRoleCustom14] = s 136 case config.StyleTokenCustom15: 137 p.tokenRoleStyle[parser.TokenRoleCustom15] = s 138 case config.StyleTokenCustom16: 139 p.tokenRoleStyle[parser.TokenRoleCustom16] = s 140 default: 141 log.Printf("Unrecognized style key: %s\n", k) 142 } 143 } 144 return p 145 } 146 147 func (p *Palette) StyleForLineNum() tcell.Style { 148 return p.lineNumStyle 149 } 150 151 func (p *Palette) StyleForSelection() tcell.Style { 152 return p.selectionStyle 153 } 154 155 func (p *Palette) StyleForSearchMatch() tcell.Style { 156 return p.searchMatchStyle 157 } 158 159 func (p *Palette) StyleForSearchCursor() tcell.Style { 160 return p.searchCursorStyle 161 } 162 163 func (p *Palette) StyleForStatusInputMode() tcell.Style { 164 return p.statusInputModeStyle 165 } 166 167 func (p *Palette) StyleForStatusInputBuffer() tcell.Style { 168 return p.statusInputBufferStyle 169 } 170 171 func (p *Palette) StyleForStatusRecordingMacro() tcell.Style { 172 return p.statusRecordingMacroStyle 173 } 174 175 func (p *Palette) StyleForStatusFilePath() tcell.Style { 176 return p.statusFilePathStyle 177 } 178 179 func (p *Palette) StyleForStatusMsg(statusMsgStyle state.StatusMsgStyle) tcell.Style { 180 switch statusMsgStyle { 181 case state.StatusMsgStyleSuccess: 182 return p.statusMsgSuccessStyle 183 case state.StatusMsgStyleError: 184 return p.statusMsgErrorStyle 185 default: 186 return tcell.StyleDefault 187 } 188 } 189 190 func (p *Palette) StyleForMenuBorder() tcell.Style { 191 return p.menuBorderStyle 192 } 193 194 func (p *Palette) StyleForMenuIcon() tcell.Style { 195 return p.menuIconStyle 196 } 197 198 func (p *Palette) StyleForMenuPrompt() tcell.Style { 199 return p.menuPromptStyle 200 } 201 202 func (p *Palette) StyleForMenuQuery() tcell.Style { 203 return p.menuQueryStyle 204 } 205 206 func (p *Palette) StyleForMenuCursor() tcell.Style { 207 return p.menuCursorStyle 208 } 209 210 func (p *Palette) StyleForMenuItem(selected bool) tcell.Style { 211 if selected { 212 return p.menuItemSelectedStyle 213 } else { 214 return p.menuItemUnselectedStyle 215 } 216 } 217 218 func (p *Palette) StyleForTextFieldPrompt() tcell.Style { 219 return p.textFieldPromptStyle 220 } 221 222 func (p *Palette) StyleForTextFieldInputText() tcell.Style { 223 return p.textFieldInputTextStyle 224 } 225 226 func (p *Palette) StyleForTextFieldBorder() tcell.Style { 227 return p.textFieldBorderStyle 228 } 229 230 func (p *Palette) StyleForSearchPrefix() tcell.Style { 231 return p.searchPrefixStyle 232 } 233 234 func (p *Palette) StyleForSearchQuery() tcell.Style { 235 return p.searchQueryStyle 236 } 237 238 func (p *Palette) StyleForTokenRole(tokenRole parser.TokenRole) tcell.Style { 239 // If key is not set, returns tcell.StyleDefault (the zero value). 240 return p.tokenRoleStyle[tokenRole] 241 } 242 243 func styleFromConfig(s config.StyleConfig) tcell.Style { 244 c := tcell.GetColor(s.Color) 245 style := tcell.StyleDefault.Foreground(c) 246 247 if s.BackgroundColor != "" { 248 bg := tcell.GetColor(s.BackgroundColor) 249 style = style.Background(bg) 250 } 251 252 if s.Bold { 253 style = style.Bold(true) 254 } 255 256 if s.Italic { 257 style = style.Italic(true) 258 } 259 260 if s.Underline { 261 style = style.Underline(true) 262 } 263 264 if s.StrikeThrough { 265 style = style.StrikeThrough(true) 266 } 267 268 return style 269 }