styles.go

  1// Package styles define styling and theming for the project.
  2package styles
  3
  4import (
  5	"fmt"
  6	"image/color"
  7	"strings"
  8
  9	"charm.land/bubbles/v2/filepicker"
 10	"charm.land/bubbles/v2/help"
 11	"charm.land/bubbles/v2/textarea"
 12	"charm.land/bubbles/v2/textinput"
 13	"charm.land/glamour/v2/ansi"
 14	"charm.land/lipgloss/v2"
 15	"github.com/alecthomas/chroma/v2"
 16	"github.com/charmbracelet/crush/internal/ui/diffview"
 17)
 18
 19const (
 20	CheckIcon       string = "βœ“"
 21	SpinnerIcon     string = "β‹―"
 22	LoadingIcon     string = "⟳"
 23	ModelIcon       string = "β—‡"
 24	HypercreditIcon string = "β—†"
 25
 26	ArrowRightIcon string = "β†’"
 27
 28	ToolPending string = "●"
 29	ToolSuccess string = "βœ“"
 30	ToolError   string = "Γ—"
 31
 32	RadioOn  string = "β—‰"
 33	RadioOff string = "β—‹"
 34
 35	BorderThin  string = "β”‚"
 36	BorderThick string = "β–Œ"
 37
 38	SectionSeparator string = "─"
 39
 40	TodoCompletedIcon  string = "βœ“"
 41	TodoPendingIcon    string = "β€’"
 42	TodoInProgressIcon string = "β†’"
 43
 44	ImageIcon string = "β– "
 45	TextIcon  string = "≑"
 46	SkillIcon string = "β–²"
 47
 48	ScrollbarThumb string = "┃"
 49	ScrollbarTrack string = "β”‚"
 50
 51	LSPErrorIcon   string = "E"
 52	LSPWarningIcon string = "W"
 53	LSPInfoIcon    string = "I"
 54	LSPHintIcon    string = "H"
 55)
 56
 57const (
 58	defaultMargin     = 2
 59	defaultListIndent = 2
 60)
 61
 62type Styles struct {
 63	// Header
 64	Header struct {
 65		Charm             lipgloss.Style // Style for "Charmβ„’" label
 66		Diagonals         lipgloss.Style // Style for diagonal separators (β•±)
 67		Percentage        lipgloss.Style // Style for context percentage
 68		Hypercredit       lipgloss.Style // Style for Hypercredit count (β—† N)
 69		Keystroke         lipgloss.Style // Style for keystroke hints (e.g., "ctrl+d")
 70		KeystrokeTip      lipgloss.Style // Style for keystroke action text (e.g., "open", "close")
 71		WorkingDir        lipgloss.Style // Style for current working directory
 72		Separator         lipgloss.Style // Style for separator dots (β€’)
 73		Wrapper           lipgloss.Style // Outer container for the entire header row
 74		LogoGradCanvas    lipgloss.Style // Canvas for the compact "CRUSH" gradient
 75		LogoGradFromColor color.Color    // "CRUSH" wordmark gradient start
 76		LogoGradToColor   color.Color    // "CRUSH" wordmark gradient end
 77	}
 78
 79	CompactDetails struct {
 80		View    lipgloss.Style
 81		Version lipgloss.Style
 82		Title   lipgloss.Style
 83	}
 84
 85	// Tool calls
 86	ToolCallSuccess lipgloss.Style
 87
 88	// Text selection
 89	TextSelection lipgloss.Style
 90
 91	// Markdown & Chroma
 92	Markdown      ansi.StyleConfig
 93	QuietMarkdown ansi.StyleConfig
 94
 95	// Inputs
 96	TextInput textinput.Styles
 97
 98	// Help
 99	Help help.Styles
100
101	// Diff
102	Diff diffview.Style
103
104	// FilePicker
105	FilePicker filepicker.Styles
106
107	// Buttons
108	Button struct {
109		Focused lipgloss.Style
110		Blurred lipgloss.Style
111	}
112
113	// Editor
114	Editor struct {
115		Textarea textarea.Styles
116
117		// Normal mode prompt (default "::: ").
118		PromptNormalFocused lipgloss.Style
119		PromptNormalBlurred lipgloss.Style
120
121		// YOLO mode prompt (" ! " icon + ":::" dots).
122		PromptYoloIconFocused lipgloss.Style
123		PromptYoloIconBlurred lipgloss.Style
124		PromptYoloDotsFocused lipgloss.Style
125		PromptYoloDotsBlurred lipgloss.Style
126	}
127
128	// Radio
129	Radio struct {
130		On    lipgloss.Style
131		Off   lipgloss.Style
132		Label lipgloss.Style // Text next to a radio button
133	}
134
135	// Background
136	Background color.Color
137
138	// Logo
139	Logo struct {
140		FieldColor         color.Color
141		TitleColorA        color.Color
142		TitleColorB        color.Color
143		CharmColor         color.Color
144		VersionColor       color.Color
145		SmallCharm         lipgloss.Style // "Charmβ„’" label in SmallRender
146		SmallDiagonals     lipgloss.Style // Diagonal line fill in SmallRender
147		GradCanvas         lipgloss.Style // Blank canvas for gradient painting
148		SmallGradFromColor color.Color    // Small "Crush" wordmark gradient start
149		SmallGradToColor   color.Color    // Small "Crush" wordmark gradient end
150	}
151
152	// Working indicator gradient (spinners/shimmers on assistant "thinking",
153	// tool-call pending, CLI generating, startup).
154	WorkingGradFromColor color.Color
155	WorkingGradToColor   color.Color
156	WorkingLabelColor    color.Color // Label text color next to the indicator
157
158	// Section Title
159	Section struct {
160		Title lipgloss.Style
161		Line  lipgloss.Style
162	}
163
164	// Initialize
165	Initialize struct {
166		Header  lipgloss.Style
167		Content lipgloss.Style
168		Accent  lipgloss.Style
169	}
170
171	// LSP
172	LSP struct {
173		ErrorDiagnostic   lipgloss.Style
174		WarningDiagnostic lipgloss.Style
175		HintDiagnostic    lipgloss.Style
176		InfoDiagnostic    lipgloss.Style
177	}
178
179	// Sidebar
180	Sidebar struct {
181		SessionTitle lipgloss.Style // Current session title at top of sidebar
182		WorkingDir   lipgloss.Style // Working directory path (PrettyPath)
183	}
184
185	// ModelInfo (model name, provider, reasoning, token/cost summary)
186	ModelInfo struct {
187		Icon                 lipgloss.Style // Model icon (β—‡)
188		Name                 lipgloss.Style // Model name text
189		Provider             lipgloss.Style // "via <provider>" text
190		ProviderFallback     lipgloss.Style // Provider on its own second line
191		Reasoning            lipgloss.Style // Reasoning effort text
192		TokenCount           lipgloss.Style // "(42K)" token count
193		TokenPercentage      lipgloss.Style // "42%" percent of context window
194		EstimatedUsagePrefix lipgloss.Style // "~" prefix for estimated usage
195		Cost                 lipgloss.Style // "$0.42" cost readout
196		HypercreditIcon      lipgloss.Style // Hypercredit icon (β—†)
197		HypercreditText      lipgloss.Style // Remaining Hypercredits text
198	}
199
200	// Resource styles the LSP/MCP/skills sidebar lists: their heading,
201	// each row's status icon, name, status text, and truncation hints.
202	Resource struct {
203		Heading         lipgloss.Style // Section header ("LSPs", "MCPs", "Skills")
204		Name            lipgloss.Style // Resource name (e.g. "gopls")
205		StatusText      lipgloss.Style // Row status description (e.g. "starting...")
206		OfflineIcon     lipgloss.Style // Offline/unstarted/stopped status icon
207		DisabledIcon    lipgloss.Style // Disabled status icon
208		BusyIcon        lipgloss.Style // Busy/starting status icon
209		ErrorIcon       lipgloss.Style // Error status icon
210		OnlineIcon      lipgloss.Style // Online/ready status icon
211		AdditionalText  lipgloss.Style // "None" and "…and N more" text
212		CapabilityCount lipgloss.Style // "N tools" / "N prompts" / "N resources"
213		RowTitleBase    lipgloss.Style // Base style applied over row titles in common.Status
214		RowDescBase     lipgloss.Style // Base style applied over row descriptions in common.Status
215		DefaultTitleFg  color.Color    // Default title color when opt is zero
216		DefaultDescFg   color.Color    // Default description color when opt is zero
217	}
218
219	// Files
220	Files struct {
221		Path           lipgloss.Style
222		Additions      lipgloss.Style
223		Deletions      lipgloss.Style
224		SectionTitle   lipgloss.Style // "Modified Files" heading
225		EmptyMessage   lipgloss.Style // "None" placeholder when no files
226		TruncationHint lipgloss.Style // "…and N more" message
227	}
228
229	// Chat
230	// Messages - chat message item styles
231	Messages struct {
232		UserBlurred      lipgloss.Style
233		UserFocused      lipgloss.Style
234		AssistantBlurred lipgloss.Style
235		AssistantFocused lipgloss.Style
236		NoContent        lipgloss.Style
237		Thinking         lipgloss.Style
238		ErrorTag         lipgloss.Style
239		ErrorTitle       lipgloss.Style
240		ErrorDetails     lipgloss.Style
241		ToolCallFocused  lipgloss.Style
242		ToolCallCompact  lipgloss.Style
243		ToolCallBlurred  lipgloss.Style
244		SectionHeader    lipgloss.Style
245
246		// Thinking section styles
247		ThinkingBox            lipgloss.Style // Background for thinking content
248		ThinkingTruncationHint lipgloss.Style // "… (N lines hidden)" hint
249		ThinkingFooterTitle    lipgloss.Style // "Thought for" text
250		ThinkingFooterDuration lipgloss.Style // Duration value
251		AssistantInfoIcon      lipgloss.Style
252		AssistantInfoModel     lipgloss.Style
253		AssistantInfoProvider  lipgloss.Style
254		AssistantInfoDuration  lipgloss.Style
255		AssistantCanceled      lipgloss.Style // Italic "Canceled" footer
256	}
257
258	// Tool - styles for tool call rendering
259	Tool struct {
260		// Icon styles with tool status
261		IconPending   lipgloss.Style
262		IconSuccess   lipgloss.Style
263		IconError     lipgloss.Style
264		IconCancelled lipgloss.Style
265
266		// Tool name styles
267		NameNormal lipgloss.Style // Top-level tool name
268		NameNested lipgloss.Style // Nested child tool name (inside Agent/Agentic Fetch)
269
270		// Parameter list styles
271		ParamMain lipgloss.Style
272		ParamKey  lipgloss.Style
273
274		// Content rendering styles
275		ContentLine           lipgloss.Style // Individual content line with background and width
276		ContentTruncation     lipgloss.Style // Truncation message "… (N lines)"
277		ContentCodeLine       lipgloss.Style // Code line with background and width
278		ContentCodeTruncation lipgloss.Style // Code truncation message with bgBase
279		ContentCodeBg         color.Color    // Background color for syntax highlighting
280		Body                  lipgloss.Style // Body content padding (PaddingLeft(2))
281
282		// Deprecated - kept for backward compatibility
283		ContentBg         lipgloss.Style // Content background
284		ContentText       lipgloss.Style // Content text
285		ContentLineNumber lipgloss.Style // Line numbers in code
286
287		// State message styles
288		StateWaiting   lipgloss.Style // "Waiting for tool response..."
289		StateCancelled lipgloss.Style // "Canceled."
290
291		// Error styles
292		ErrorTag     lipgloss.Style // ERROR tag
293		ErrorMessage lipgloss.Style // Error message text
294
295		// Diff styles
296		DiffTruncation lipgloss.Style // Diff truncation message with padding
297
298		// Multi-edit note styles
299		NoteTag     lipgloss.Style // NOTE tag (yellow background)
300		NoteMessage lipgloss.Style // Note message text
301
302		// Job header styles (for bash jobs)
303		JobIconPending lipgloss.Style // Pending job icon (green dark)
304		JobIconError   lipgloss.Style // Error job icon (red dark)
305		JobIconSuccess lipgloss.Style // Success job icon (green)
306		JobToolName    lipgloss.Style // Job tool name "Bash" (blue)
307		JobAction      lipgloss.Style // Action text (Start, Output, Kill)
308		JobPID         lipgloss.Style // PID text
309		JobDescription lipgloss.Style // Description text
310
311		// Agent task styles
312		AgentTaskTag lipgloss.Style // Agent task tag (blue background, bold)
313		AgentPrompt  lipgloss.Style // Agent prompt text
314
315		// Agentic fetch styles
316		AgenticFetchPromptTag lipgloss.Style // Agentic fetch prompt tag (green background, bold)
317
318		// Todo styles
319		TodoRatio          lipgloss.Style // Todo ratio (e.g., "2/5")
320		TodoCompletedIcon  lipgloss.Style // Completed todo icon
321		TodoInProgressIcon lipgloss.Style // In-progress todo icon
322		TodoPendingIcon    lipgloss.Style // Pending todo icon
323		TodoStatusNote     lipgloss.Style // " Β· completed N" / " Β· starting task" trailing note
324		TodoItem           lipgloss.Style // Default body text for todo list items
325		TodoJustStarted    lipgloss.Style // Text of the just-started todo in tool-call bodies
326
327		// MCP tools
328		MCPName     lipgloss.Style // The mcp name
329		MCPToolName lipgloss.Style // The mcp tool name
330		MCPArrow    lipgloss.Style // The mcp arrow icon
331
332		// Images and external resources
333		ResourceLoadedText      lipgloss.Style
334		ResourceLoadedIndicator lipgloss.Style
335		ResourceName            lipgloss.Style
336		ResourceSize            lipgloss.Style
337		MediaType               lipgloss.Style
338
339		// Hooks
340		HookLabel        lipgloss.Style // "Hook" label
341		HookName         lipgloss.Style // Hook command name
342		HookMatcher      lipgloss.Style // Matcher regex pattern
343		HookArrow        lipgloss.Style // Arrow indicator
344		HookDetail       lipgloss.Style // Decision detail text
345		HookOK           lipgloss.Style // "OK" status
346		HookDenied       lipgloss.Style // "Denied" status
347		HookDeniedLabel  lipgloss.Style // "Hook" label when denied
348		HookDeniedReason lipgloss.Style // Denied reason text
349		HookRewrote      lipgloss.Style // "Rewrote Input" indicator
350
351		// Action verb colors for tool-call headers.
352		ActionCreate  lipgloss.Style // Constructive actions (e.g. "Add", "Create")
353		ActionDestroy lipgloss.Style // Destructive actions (e.g. "Remove", "Delete")
354
355		// Tool result helpers.
356		ResultEmpty      lipgloss.Style // "No results" placeholder
357		ResultTruncation lipgloss.Style // "… and N more" truncation line
358		ResultItemName   lipgloss.Style // Item name (left column in result lists)
359		ResultItemDesc   lipgloss.Style // Item description (right column)
360	}
361
362	// Dialog styles
363	Dialog struct {
364		Title              lipgloss.Style
365		TitleText          lipgloss.Style
366		TitleError         lipgloss.Style
367		TitleAccent        lipgloss.Style
368		TitleLineBase      lipgloss.Style // Base for the gradient β•±β•±β•± next to dialog titles
369		TitleGradFromColor color.Color    // Default dialog title β•±β•±β•± gradient start
370		TitleGradToColor   color.Color    // Default dialog title β•±β•±β•± gradient end
371		// View is the main content area style.
372		View          lipgloss.Style
373		PrimaryText   lipgloss.Style
374		SecondaryText lipgloss.Style
375		// HelpView is the line that contains the help.
376		HelpView lipgloss.Style
377		Help     struct {
378			Ellipsis       lipgloss.Style
379			ShortKey       lipgloss.Style
380			ShortDesc      lipgloss.Style
381			ShortSeparator lipgloss.Style
382			FullKey        lipgloss.Style
383			FullDesc       lipgloss.Style
384			FullSeparator  lipgloss.Style
385		}
386
387		NormalItem   lipgloss.Style
388		SelectedItem lipgloss.Style
389		InputPrompt  lipgloss.Style
390
391		List lipgloss.Style
392
393		Spinner lipgloss.Style
394
395		// ContentPanel is used for content blocks with subtle background.
396		ContentPanel lipgloss.Style
397
398		// Scrollbar styles for scrollable content.
399		ScrollbarThumb lipgloss.Style
400		ScrollbarTrack lipgloss.Style
401
402		// Arguments
403		Arguments struct {
404			Content                  lipgloss.Style
405			Description              lipgloss.Style
406			InputLabelBlurred        lipgloss.Style
407			InputLabelFocused        lipgloss.Style
408			InputRequiredMarkBlurred lipgloss.Style
409			InputRequiredMarkFocused lipgloss.Style
410		}
411
412		// ListItem styles the info-text rendered alongside list items (commands,
413		// models, reasoning options). Sessions have their own overrides below.
414		ListItem struct {
415			InfoBlurred lipgloss.Style
416			InfoFocused lipgloss.Style
417		}
418
419		Models struct {
420			ConfiguredText lipgloss.Style // "Configured" badge shown on the ModelGroup header
421		}
422
423		Permissions struct {
424			KeyText   lipgloss.Style // Left key cell of a key/value row
425			ValueText lipgloss.Style // Right value cell of a key/value row
426			ParamsBg  color.Color    // Background color behind highlighted JSON parameters
427		}
428
429		Quit struct {
430			Content lipgloss.Style // Wrapper for the quit dialog's inner content
431			Frame   lipgloss.Style // Outer rounded border framing the quit dialog
432		}
433
434		APIKey struct {
435			Spinner lipgloss.Style // Loading spinner while validating the key
436		}
437
438		OAuth struct {
439			Spinner      lipgloss.Style // Loading spinner
440			Instructions lipgloss.Style // Emphasized instruction text
441			UserCode     lipgloss.Style // Prominent user code display
442			Success      lipgloss.Style // Positive status text (e.g. "Authentication successful!")
443			Link         lipgloss.Style // Underlined verification URL
444			Enter        lipgloss.Style // "enter" keyword highlight in instructions
445			ErrorText    lipgloss.Style // Error message when authentication fails
446			StatusText   lipgloss.Style // Narrative status text ("Initializing...", "Verifying...", etc.)
447			UserCodeBg   color.Color    // Background color of the centered user-code box
448		}
449
450		ImagePreview lipgloss.Style
451
452		Sessions struct {
453			// styles for when we are in delete mode
454			DeletingView                   lipgloss.Style
455			DeletingItemFocused            lipgloss.Style
456			DeletingItemBlurred            lipgloss.Style
457			DeletingTitle                  lipgloss.Style
458			DeletingMessage                lipgloss.Style
459			DeletingTitleGradientFromColor color.Color
460			DeletingTitleGradientToColor   color.Color
461
462			// styles for when we are in update mode
463			RenamingView                   lipgloss.Style
464			RenamingingItemFocused         lipgloss.Style
465			RenamingItemBlurred            lipgloss.Style
466			RenamingingTitle               lipgloss.Style
467			RenamingingMessage             lipgloss.Style
468			RenamingTitleGradientFromColor color.Color
469			RenamingTitleGradientToColor   color.Color
470			RenamingPlaceholder            lipgloss.Style
471
472			InfoBlurred lipgloss.Style // Timestamp text on unfocused session items
473			InfoFocused lipgloss.Style // Timestamp text on the focused session item
474		}
475	}
476
477	// Status bar and help
478	Status struct {
479		Help lipgloss.Style
480
481		ErrorIndicator   lipgloss.Style
482		WarnIndicator    lipgloss.Style
483		InfoIndicator    lipgloss.Style
484		UpdateIndicator  lipgloss.Style
485		SuccessIndicator lipgloss.Style
486
487		ErrorMessage   lipgloss.Style
488		WarnMessage    lipgloss.Style
489		InfoMessage    lipgloss.Style
490		UpdateMessage  lipgloss.Style
491		SuccessMessage lipgloss.Style
492	}
493
494	// Completions popup styles
495	Completions struct {
496		Normal  lipgloss.Style
497		Focused lipgloss.Style
498		Match   lipgloss.Style
499	}
500
501	// Attachments styles
502	Attachments struct {
503		Normal   lipgloss.Style
504		Image    lipgloss.Style
505		Text     lipgloss.Style
506		Skill    lipgloss.Style
507		Deleting lipgloss.Style
508	}
509
510	// Pills styles for todo/queue pills
511	Pills struct {
512		Base               lipgloss.Style // Base pill style with padding
513		Focused            lipgloss.Style // Focused pill with visible border
514		Blurred            lipgloss.Style // Blurred pill with hidden border
515		QueueItemPrefix    lipgloss.Style // Prefix for queue list items
516		QueueItemText      lipgloss.Style // Queue list item body text
517		QueueLabel         lipgloss.Style // "N Queued" label text
518		QueueIconBase      lipgloss.Style // Base style for queue gradient triangles
519		QueueGradFromColor color.Color    // Start color for queue indicator gradient
520		QueueGradToColor   color.Color    // End color for queue indicator gradient
521		TodoLabel          lipgloss.Style // "To-Do" label
522		TodoProgress       lipgloss.Style // Todo ratio (e.g. "2/5")
523		TodoCurrentTask    lipgloss.Style // Current in-progress task name
524		TodoSpinner        lipgloss.Style // Todo spinner style
525		HelpKey            lipgloss.Style // Keystroke hint style
526		HelpText           lipgloss.Style // Help action text style
527		Area               lipgloss.Style // Pills area container
528	}
529}
530
531// ChromaTheme converts the current markdown chroma styles to a chroma
532// StyleEntries map.
533func (s *Styles) ChromaTheme() chroma.StyleEntries {
534	rules := s.Markdown.CodeBlock
535
536	return chroma.StyleEntries{
537		chroma.Text:                chromaStyle(rules.Chroma.Text),
538		chroma.Error:               chromaStyle(rules.Chroma.Error),
539		chroma.Comment:             chromaStyle(rules.Chroma.Comment),
540		chroma.CommentPreproc:      chromaStyle(rules.Chroma.CommentPreproc),
541		chroma.Keyword:             chromaStyle(rules.Chroma.Keyword),
542		chroma.KeywordReserved:     chromaStyle(rules.Chroma.KeywordReserved),
543		chroma.KeywordNamespace:    chromaStyle(rules.Chroma.KeywordNamespace),
544		chroma.KeywordType:         chromaStyle(rules.Chroma.KeywordType),
545		chroma.Operator:            chromaStyle(rules.Chroma.Operator),
546		chroma.Punctuation:         chromaStyle(rules.Chroma.Punctuation),
547		chroma.Name:                chromaStyle(rules.Chroma.Name),
548		chroma.NameBuiltin:         chromaStyle(rules.Chroma.NameBuiltin),
549		chroma.NameTag:             chromaStyle(rules.Chroma.NameTag),
550		chroma.NameAttribute:       chromaStyle(rules.Chroma.NameAttribute),
551		chroma.NameClass:           chromaStyle(rules.Chroma.NameClass),
552		chroma.NameConstant:        chromaStyle(rules.Chroma.NameConstant),
553		chroma.NameDecorator:       chromaStyle(rules.Chroma.NameDecorator),
554		chroma.NameException:       chromaStyle(rules.Chroma.NameException),
555		chroma.NameFunction:        chromaStyle(rules.Chroma.NameFunction),
556		chroma.NameOther:           chromaStyle(rules.Chroma.NameOther),
557		chroma.Literal:             chromaStyle(rules.Chroma.Literal),
558		chroma.LiteralNumber:       chromaStyle(rules.Chroma.LiteralNumber),
559		chroma.LiteralDate:         chromaStyle(rules.Chroma.LiteralDate),
560		chroma.LiteralString:       chromaStyle(rules.Chroma.LiteralString),
561		chroma.LiteralStringEscape: chromaStyle(rules.Chroma.LiteralStringEscape),
562		chroma.GenericDeleted:      chromaStyle(rules.Chroma.GenericDeleted),
563		chroma.GenericEmph:         chromaStyle(rules.Chroma.GenericEmph),
564		chroma.GenericInserted:     chromaStyle(rules.Chroma.GenericInserted),
565		chroma.GenericStrong:       chromaStyle(rules.Chroma.GenericStrong),
566		chroma.GenericSubheading:   chromaStyle(rules.Chroma.GenericSubheading),
567		chroma.Background:          chromaStyle(rules.Chroma.Background),
568	}
569}
570
571// DialogHelpStyles returns the styles for dialog help.
572func (s *Styles) DialogHelpStyles() help.Styles {
573	return help.Styles(s.Dialog.Help)
574}
575
576// hex returns a pointer to the "#rrggbb" representation of c. It's used to
577// satisfy glamour's string-pointer API when configuring markdown colors
578// from the theme palette.
579func hex(c color.Color) *string {
580	r, g, b, _ := c.RGBA()
581	s := fmt.Sprintf("#%02x%02x%02x", r>>8, g>>8, b>>8)
582	return &s
583}
584
585func chromaStyle(style ansi.StylePrimitive) string {
586	var s strings.Builder
587
588	if style.Color != nil {
589		s.WriteString(*style.Color)
590	}
591	if style.BackgroundColor != nil {
592		if s.Len() > 0 {
593			s.WriteString(" ")
594		}
595		s.WriteString("bg:")
596		s.WriteString(*style.BackgroundColor)
597	}
598	if style.Italic != nil && *style.Italic {
599		if s.Len() > 0 {
600			s.WriteString(" ")
601		}
602		s.WriteString("italic")
603	}
604	if style.Bold != nil && *style.Bold {
605		if s.Len() > 0 {
606			s.WriteString(" ")
607		}
608		s.WriteString("bold")
609	}
610	if style.Underline != nil && *style.Underline {
611		if s.Len() > 0 {
612			s.WriteString(" ")
613		}
614		s.WriteString("underline")
615	}
616
617	return s.String()
618}