textbringer 24 → 26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,180 @@
1
+ module Textbringer
2
+ class Theme
3
+ DEFAULT_THEME = "github"
4
+
5
+ class Palette
6
+ def initialize
7
+ @colors = {}
8
+ end
9
+
10
+ def color(name, hex: nil, ansi: nil)
11
+ @colors[name] = { hex: hex, ansi: ansi }
12
+ end
13
+
14
+ def resolve(name, tier)
15
+ c = @colors[name]
16
+ return nil unless c
17
+ tier == :ansi ? c[:ansi] : c[:hex]
18
+ end
19
+ end
20
+
21
+ @@themes = {}
22
+ @@current = nil
23
+ @@background_mode = nil
24
+
25
+ def self.define(name, &block)
26
+ theme = new(name)
27
+ block.call(theme)
28
+ @@themes[name] = theme
29
+ end
30
+
31
+ def self.[](name)
32
+ @@themes[name]
33
+ end
34
+
35
+ def self.current
36
+ @@current
37
+ end
38
+
39
+ def self.load(name)
40
+ user_path = File.expand_path("~/.textbringer/themes/#{name}.rb")
41
+ if File.exist?(user_path)
42
+ Kernel.load(user_path)
43
+ else
44
+ require "textbringer/themes/#{name}"
45
+ end
46
+ theme = @@themes[name]
47
+ raise EditorError, "Theme '#{name}' not found" unless theme
48
+ theme.activate
49
+ end
50
+
51
+ def self.load_default
52
+ return if @@current
53
+ load(DEFAULT_THEME)
54
+ end
55
+
56
+ def self.background_mode
57
+ mode = CONFIG[:background_mode]
58
+ return mode if mode == :dark || mode == :light
59
+ @@background_mode || :dark
60
+ end
61
+
62
+ def self.detect_background
63
+ @@background_mode = detect_background_via_osc11 ||
64
+ detect_background_via_colorfgbg ||
65
+ :dark
66
+ end
67
+
68
+ def self.color_tier
69
+ Window.colors >= 256 ? :hex : :ansi
70
+ end
71
+
72
+ def initialize(name)
73
+ @name = name
74
+ @palettes = {}
75
+ @face_definitions = []
76
+ @default_colors = nil
77
+ end
78
+
79
+ attr_reader :name
80
+
81
+ def palette(mode, &block)
82
+ p = Palette.new
83
+ block.call(p)
84
+ @palettes[mode] = p
85
+ end
86
+
87
+ def face(name, **attrs)
88
+ @face_definitions << [name, attrs]
89
+ end
90
+
91
+ def default_colors(foreground:, background:)
92
+ @default_colors = { foreground: foreground, background: background }
93
+ end
94
+
95
+ def activate
96
+ mode = self.class.background_mode
97
+ tier = self.class.color_tier
98
+ palette = @palettes[mode] || @palettes[:dark] || Palette.new
99
+ @face_definitions.each do |face_name, attrs|
100
+ resolved = {}
101
+ [:foreground, :background].each do |key|
102
+ val = attrs[key]
103
+ if val.is_a?(Symbol)
104
+ color = palette.resolve(val, tier)
105
+ if color
106
+ resolved[key] = color
107
+ else
108
+ raise EditorError,
109
+ "Unknown palette color :#{val} for #{key} in face #{face_name}"
110
+ end
111
+ elsif val.is_a?(String)
112
+ resolved[key] = val
113
+ end
114
+ end
115
+ [:bold, :underline, :reverse, :inherit].each do |key|
116
+ resolved[key] = attrs[key] if attrs.key?(key)
117
+ end
118
+ Face.define(face_name, **resolved)
119
+ end
120
+ @@current = self
121
+ apply_default_colors(palette, tier)
122
+ end
123
+
124
+ private
125
+
126
+ def apply_default_colors(palette, tier)
127
+ if @default_colors
128
+ fg = resolve_default_color(@default_colors[:foreground], palette, tier)
129
+ bg = resolve_default_color(@default_colors[:background], palette, tier)
130
+ else
131
+ fg = "default"
132
+ bg = "default"
133
+ end
134
+ Window.set_default_colors(fg, bg)
135
+ end
136
+
137
+ def resolve_default_color(val, palette, tier)
138
+ if val.is_a?(Symbol)
139
+ color = palette.resolve(val, tier)
140
+ unless color
141
+ raise EditorError,
142
+ "Unknown palette color :#{val} for default_colors"
143
+ end
144
+ color
145
+ else
146
+ val || "default"
147
+ end
148
+ end
149
+
150
+ private_class_method def self.detect_background_via_osc11
151
+ return nil unless $stdin.tty? && $stdout.tty?
152
+ require "io/console"
153
+ $stdin.raw(min: 0, time: 1) do |io|
154
+ $stdout.write("\e]11;?\e\\")
155
+ $stdout.flush
156
+ response = +""
157
+ while (c = io.getc)
158
+ response << c
159
+ break if response.include?("\e\\") || response.include?("\a")
160
+ end
161
+ if response =~ /\e\]11;rgb:([0-9a-f]+)\/([0-9a-f]+)\/([0-9a-f]+)/i
162
+ r = $1[0..1].to_i(16)
163
+ g = $2[0..1].to_i(16)
164
+ b = $3[0..1].to_i(16)
165
+ luminance = 0.299 * r + 0.587 * g + 0.114 * b
166
+ luminance < 128 ? :dark : :light
167
+ end
168
+ end
169
+ rescue
170
+ nil
171
+ end
172
+
173
+ private_class_method def self.detect_background_via_colorfgbg
174
+ colorfgbg = ENV["COLORFGBG"]
175
+ return nil unless colorfgbg
176
+ bg = colorfgbg.split(";").last.to_i
177
+ bg <= 6 || bg == 8 ? :dark : :light
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,106 @@
1
+ # Catppuccin theme for Textbringer
2
+ # Based on https://github.com/catppuccin/nvim
3
+ #
4
+ # Dark variant: Mocha Light variant: Latte
5
+ # GUI hex values from the official palette definitions.
6
+
7
+ Textbringer::Theme.define "catppuccin" do |t|
8
+ t.palette :dark do |p|
9
+ # Catppuccin Mocha base tones
10
+ p.color :text, hex: "#cdd6f4", ansi: "white"
11
+ p.color :subtext1, hex: "#bac2de", ansi: "white"
12
+ p.color :subtext0, hex: "#a6adc8", ansi: "white"
13
+ p.color :overlay2, hex: "#9399b2", ansi: "white"
14
+ p.color :overlay1, hex: "#7f849c", ansi: "brightblack"
15
+ p.color :overlay0, hex: "#6c7086", ansi: "brightblack"
16
+ p.color :surface2, hex: "#585b70", ansi: "brightblack"
17
+ p.color :surface1, hex: "#45475a", ansi: "brightblack"
18
+ p.color :surface0, hex: "#313244", ansi: "brightblack"
19
+ p.color :base, hex: "#1e1e2e", ansi: "black"
20
+ p.color :mantle, hex: "#181825", ansi: "black"
21
+ p.color :crust, hex: "#11111b", ansi: "black"
22
+
23
+ # Catppuccin Mocha accent colors
24
+ p.color :red, hex: "#f38ba8", ansi: "red"
25
+ p.color :maroon, hex: "#eba0ac", ansi: "red"
26
+ p.color :peach, hex: "#fab387", ansi: "yellow"
27
+ p.color :yellow, hex: "#f9e2af", ansi: "yellow"
28
+ p.color :green, hex: "#a6e3a1", ansi: "green"
29
+ p.color :teal, hex: "#94e2d5", ansi: "cyan"
30
+ p.color :sky, hex: "#89dceb", ansi: "cyan"
31
+ p.color :sapphire, hex: "#74c7ec", ansi: "cyan"
32
+ p.color :blue, hex: "#89b4fa", ansi: "blue"
33
+ p.color :lavender, hex: "#b4befe", ansi: "blue"
34
+ p.color :mauve, hex: "#cba6f7", ansi: "magenta"
35
+ p.color :pink, hex: "#f5c2e7", ansi: "magenta"
36
+ p.color :flamingo, hex: "#f2cdcd", ansi: "red"
37
+ p.color :rosewater, hex: "#f5e0dc", ansi: "red"
38
+ end
39
+
40
+ t.palette :light do |p|
41
+ # Catppuccin Latte base tones
42
+ p.color :text, hex: "#4c4f69", ansi: "black"
43
+ p.color :subtext1, hex: "#5c5f77", ansi: "black"
44
+ p.color :subtext0, hex: "#6c6f85", ansi: "brightblack"
45
+ p.color :overlay2, hex: "#7c7f93", ansi: "brightblack"
46
+ p.color :overlay1, hex: "#8c8fa1", ansi: "white"
47
+ p.color :overlay0, hex: "#9ca0b0", ansi: "white"
48
+ p.color :surface2, hex: "#acb0be", ansi: "white"
49
+ p.color :surface1, hex: "#bcc0cc", ansi: "white"
50
+ p.color :surface0, hex: "#ccd0da", ansi: "white"
51
+ p.color :base, hex: "#eff1f5", ansi: "white"
52
+ p.color :mantle, hex: "#e6e9ef", ansi: "white"
53
+ p.color :crust, hex: "#dce0e8", ansi: "white"
54
+
55
+ # Catppuccin Latte accent colors
56
+ p.color :red, hex: "#d20f39", ansi: "red"
57
+ p.color :maroon, hex: "#e64553", ansi: "red"
58
+ p.color :peach, hex: "#fe640b", ansi: "red"
59
+ p.color :yellow, hex: "#df8e1d", ansi: "yellow"
60
+ p.color :green, hex: "#40a02b", ansi: "green"
61
+ p.color :teal, hex: "#179299", ansi: "cyan"
62
+ p.color :sky, hex: "#04a5e5", ansi: "cyan"
63
+ p.color :sapphire, hex: "#209fb5", ansi: "cyan"
64
+ p.color :blue, hex: "#1e66f5", ansi: "blue"
65
+ p.color :lavender, hex: "#7287fd", ansi: "blue"
66
+ p.color :mauve, hex: "#8839ef", ansi: "magenta"
67
+ p.color :pink, hex: "#ea76cb", ansi: "magenta"
68
+ p.color :flamingo, hex: "#dd7878", ansi: "red"
69
+ p.color :rosewater, hex: "#dc8a78", ansi: "red"
70
+ end
71
+
72
+ t.default_colors foreground: :text, background: :base
73
+
74
+ # Programming faces (from catppuccin/nvim syntax.lua)
75
+ t.face :comment, foreground: :overlay2
76
+ t.face :preprocessing_directive, foreground: :pink
77
+ t.face :keyword, foreground: :mauve
78
+ t.face :string, foreground: :green
79
+ t.face :number, foreground: :peach
80
+ t.face :constant, foreground: :peach
81
+ t.face :function_name, foreground: :blue
82
+ t.face :type, foreground: :yellow
83
+ t.face :variable, foreground: :flamingo
84
+ t.face :operator, foreground: :sky
85
+ t.face :punctuation
86
+ t.face :builtin, foreground: :red
87
+ t.face :property, foreground: :lavender
88
+
89
+ # Basic faces (from catppuccin/nvim editor.lua)
90
+ t.face :mode_line, foreground: :text, background: :mantle
91
+ t.face :link, foreground: :blue, underline: true
92
+ t.face :control
93
+ t.face :region, background: :surface1
94
+ t.face :isearch, foreground: :mantle, background: :red
95
+ t.face :floating_window, foreground: :text, background: :mantle
96
+
97
+ # Completion faces
98
+ t.face :completion_popup, foreground: :overlay2, background: :mantle
99
+ t.face :completion_popup_selected, background: :surface0
100
+
101
+ # Dired faces
102
+ t.face :dired_directory, foreground: :blue
103
+ t.face :dired_symlink, foreground: :teal
104
+ t.face :dired_executable, foreground: :green
105
+ t.face :dired_flagged, foreground: :red
106
+ end
@@ -0,0 +1,86 @@
1
+ # GitHub theme for Textbringer
2
+ # Based on https://github.com/cormacrelf/vim-colors-github
3
+ # Inspired by GitHub's syntax highlighting as of 2018.
4
+ #
5
+ # GUI hex values from the source's guifg/guibg definitions.
6
+
7
+ Textbringer::Theme.define "github" do |t|
8
+ t.palette :light do |p|
9
+ # Backgrounds / foreground
10
+ p.color :bg, hex: "#ffffff", ansi: "white" # Normal guibg
11
+ p.color :bg1, hex: "#f6f8fa", ansi: "white" # overlay/gutter (grey2)
12
+ p.color :vis, hex: "#e4effb", ansi: "blue" # Visual guibg (blue2)
13
+ p.color :search, hex: "#ffffc5", ansi: "yellow" # Search guibg
14
+ p.color :fg, hex: "#24292e", ansi: "black" # Normal guifg (base0)
15
+ p.color :comment, hex: "#6a737d", ansi: "brightblack" # Comment guifg (base2)
16
+ p.color :line_nr, hex: "#babbbc", ansi: "white" # LineNr guifg (base4)
17
+
18
+ # Syntax colors
19
+ p.color :red, hex: "#d73a49", ansi: "red" # Statement guifg
20
+ p.color :darkred, hex: "#b31d28", ansi: "red" # darkred
21
+ p.color :purple, hex: "#6f42c1", ansi: "magenta" # Function guifg
22
+ p.color :green, hex: "#22863a", ansi: "green" # html/xml tags
23
+ p.color :orange, hex: "#e36209", ansi: "yellow" # orange
24
+ p.color :blue, hex: "#005cc5", ansi: "blue" # Identifier guifg
25
+ p.color :darkblue, hex: "#032f62", ansi: "blue" # String guifg
26
+ end
27
+
28
+ t.palette :dark do |p|
29
+ # Backgrounds / foreground (GUI hex from dark mode definitions)
30
+ p.color :bg, hex: "#24292e", ansi: "black" # base0 (Normal bg)
31
+ p.color :bg1, hex: "#353a3f", ansi: "brightblack" # dcolors.overlay (panels/popups)
32
+ p.color :vis, hex: "#354a60", ansi: "blue" # dcolors.blue2 / blues[4]
33
+ p.color :search, hex: "#595322", ansi: "yellow" # dcolors.yellow (Search bg)
34
+ p.color :fg, hex: "#fafbfc", ansi: "white" # fafbfc (Normal fg)
35
+ p.color :comment, hex: "#abaeb1", ansi: "brightblack" # darktext[2] (Comment)
36
+ p.color :line_nr, hex: "#76787b", ansi: "brightblack" # numDarkest (base4 in dark)
37
+
38
+ # Syntax colors (GUI hex)
39
+ p.color :red, hex: "#f16636", ansi: "red" # dcolors.red
40
+ p.color :darkred, hex: "#b31d28", ansi: "red" # s:colors.darkred (same both modes)
41
+ p.color :purple, hex: "#a887e6", ansi: "magenta" # dcolors.purple
42
+ p.color :green, hex: "#59b36f", ansi: "green" # dcolors.green
43
+ p.color :orange, hex: "#ffa657", ansi: "yellow" # s:colors.orange (same both modes)
44
+ p.color :blue, hex: "#4dacfd", ansi: "blue" # dcolors.blue
45
+ p.color :darkblue, hex: "#c1daec", ansi: "blue" # dcolors.darkblue = blue1
46
+ end
47
+
48
+ t.default_colors foreground: :fg, background: :bg
49
+
50
+ # Programming faces
51
+ t.face :comment, foreground: :comment # Comment = base2
52
+ t.face :preprocessing_directive, foreground: :red # PreProc = red
53
+ t.face :keyword, foreground: :red # Statement = red
54
+ t.face :string, foreground: :darkblue # String = darkblue
55
+ t.face :number, foreground: :blue # Number → Constant = blue
56
+ t.face :constant, foreground: :blue # Constant = blue
57
+ t.face :function_name, foreground: :purple # Function = purple
58
+ t.face :type, foreground: :orange # Type = orange (current GitHub style; vim source used red)
59
+ t.face :variable, foreground: :blue # Identifier = blue
60
+ t.face :operator # no explicit color in source
61
+ t.face :punctuation # Delimiter = fg (ghNormalNoBg)
62
+ t.face :builtin, foreground: :purple # Special = purple
63
+ t.face :property, foreground: :blue # Identifier = blue
64
+
65
+ # Basic faces
66
+ # StatusLine: fg=grey2 (~bg1), bg=base0 (~fg) — inverted from Normal in both modes
67
+ t.face :mode_line, foreground: :bg1, background: :fg
68
+ t.face :link, foreground: :blue, underline: true
69
+ t.face :control
70
+ t.face :region, background: :vis # Visual = visualblue
71
+ # Search has no explicit fg in source; fg inherits from Normal
72
+ t.face :isearch, foreground: :fg, background: :search
73
+ t.face :floating_window, foreground: :fg, background: :bg1
74
+
75
+ # Completion faces
76
+ # Pmenu: fg=base3 (≈ comment), bg=overlay (≈ bg1)
77
+ # PmenuSel: fg=overlay (≈ bg1), bg=blue; bold
78
+ t.face :completion_popup, foreground: :comment, background: :bg1
79
+ t.face :completion_popup_selected, foreground: :bg1, background: :blue, bold: true
80
+
81
+ # Dired faces
82
+ t.face :dired_directory, foreground: :blue # Directory → ghBlue
83
+ t.face :dired_symlink, foreground: :darkblue
84
+ t.face :dired_executable, foreground: :green
85
+ t.face :dired_flagged, foreground: :red
86
+ end
@@ -0,0 +1,85 @@
1
+ # Gruvbox theme for Textbringer
2
+ # Based on https://github.com/morhetz/gruvbox
3
+ #
4
+ # GUI hex values from the source's guifg/guibg definitions.
5
+ # Dark: bright accent colors on warm dark background
6
+ # Light: faded accent colors on warm light background
7
+
8
+ Textbringer::Theme.define "gruvbox" do |t|
9
+ t.palette :dark do |p|
10
+ # Base tones (dark background, light foreground)
11
+ p.color :bg0, hex: "#282828", ansi: "black" # dark0
12
+ p.color :bg1, hex: "#3c3836", ansi: "brightblack" # dark1
13
+ p.color :bg2, hex: "#504945", ansi: "brightblack" # dark2
14
+ p.color :bg3, hex: "#665c54", ansi: "brightblack" # dark3
15
+ p.color :bg4, hex: "#7c6f64", ansi: "white" # dark4
16
+ p.color :fg1, hex: "#ebdbb2", ansi: "white" # light1 (Normal guifg)
17
+ p.color :fg4, hex: "#a89984", ansi: "white" # light4
18
+ p.color :gray, hex: "#928374", ansi: "white" # gray_245
19
+
20
+ # Bright accent colors
21
+ p.color :red, hex: "#fb4934", ansi: "red" # bright_red
22
+ p.color :green, hex: "#b8bb26", ansi: "green" # bright_green
23
+ p.color :yellow, hex: "#fabd2f", ansi: "yellow" # bright_yellow
24
+ p.color :blue, hex: "#83a598", ansi: "blue" # bright_blue
25
+ p.color :purple, hex: "#d3869b", ansi: "magenta" # bright_purple
26
+ p.color :aqua, hex: "#8ec07c", ansi: "cyan" # bright_aqua
27
+ p.color :orange, hex: "#fe8019", ansi: "yellow" # bright_orange
28
+ end
29
+
30
+ t.palette :light do |p|
31
+ # Base tones (light background, dark foreground)
32
+ p.color :bg0, hex: "#fbf1c7", ansi: "white" # light0
33
+ p.color :bg1, hex: "#ebdbb2", ansi: "white" # light1
34
+ p.color :bg2, hex: "#d5c4a1", ansi: "white" # light2
35
+ p.color :bg3, hex: "#bdae93", ansi: "white" # light3
36
+ p.color :bg4, hex: "#a89984", ansi: "brightblack" # light4
37
+ p.color :fg1, hex: "#3c3836", ansi: "black" # dark1 (Normal guifg)
38
+ p.color :fg4, hex: "#7c6f64", ansi: "brightblack" # dark4
39
+ p.color :gray, hex: "#928374", ansi: "brightblack" # gray_244
40
+
41
+ # Faded accent colors
42
+ p.color :red, hex: "#9d0006", ansi: "red" # faded_red
43
+ p.color :green, hex: "#79740e", ansi: "green" # faded_green
44
+ p.color :yellow, hex: "#b57614", ansi: "yellow" # faded_yellow
45
+ p.color :blue, hex: "#076678", ansi: "blue" # faded_blue
46
+ p.color :purple, hex: "#8f3f71", ansi: "magenta" # faded_purple
47
+ p.color :aqua, hex: "#427b58", ansi: "cyan" # faded_aqua
48
+ p.color :orange, hex: "#af3a03", ansi: "red" # faded_orange
49
+ end
50
+
51
+ t.default_colors foreground: :fg1, background: :bg0
52
+
53
+ # Programming faces
54
+ t.face :comment, foreground: :gray
55
+ t.face :preprocessing_directive, foreground: :aqua
56
+ t.face :keyword, foreground: :red
57
+ t.face :string, foreground: :green
58
+ t.face :number, foreground: :purple
59
+ t.face :constant, foreground: :purple
60
+ t.face :function_name, foreground: :green, bold: true
61
+ t.face :type, foreground: :yellow
62
+ t.face :variable, foreground: :blue
63
+ t.face :operator
64
+ t.face :punctuation
65
+ t.face :builtin, foreground: :orange
66
+ t.face :property, foreground: :blue
67
+
68
+ # Basic faces
69
+ t.face :mode_line, foreground: :bg2, background: :fg1, reverse: true
70
+ t.face :link, foreground: :blue, underline: true
71
+ t.face :control
72
+ t.face :region, background: :bg3
73
+ t.face :isearch, foreground: :yellow, background: :bg0, reverse: true
74
+ t.face :floating_window, foreground: :fg1, background: :bg1
75
+
76
+ # Completion faces
77
+ t.face :completion_popup, foreground: :fg1, background: :bg2
78
+ t.face :completion_popup_selected, foreground: :bg2, background: :blue, bold: true
79
+
80
+ # Dired faces
81
+ t.face :dired_directory, foreground: :green, bold: true
82
+ t.face :dired_symlink, foreground: :aqua
83
+ t.face :dired_executable, foreground: :green
84
+ t.face :dired_flagged, foreground: :red
85
+ end
@@ -0,0 +1,65 @@
1
+ # Molokai theme for Textbringer
2
+ # Based on https://github.com/tomasr/molokai
3
+ # Original Monokai theme by Wimer Hazenberg; darker variant by Hamish Stuart Macpherson
4
+ #
5
+ # GUI hex values from the source's guifg/guibg definitions.
6
+ # Dark only (default darker variant, s:molokai_original = 0).
7
+
8
+ Textbringer::Theme.define "molokai" do |t|
9
+ t.palette :dark do |p|
10
+ # Background / foreground
11
+ p.color :bg, hex: "#1b1d1e", ansi: "black" # Normal guibg
12
+ p.color :bg1, hex: "#403d3d", ansi: "brightblack" # Visual guibg
13
+ p.color :bg2, hex: "#1b1d1e", ansi: "black" # floating window bg (same as bg)
14
+ p.color :fg, hex: "#f8f8f2", ansi: "white" # Normal guifg
15
+ p.color :comment, hex: "#7e8e91", ansi: "brightblack" # Comment guifg
16
+ p.color :gray, hex: "#455354", ansi: "brightblack" # StatusLine guifg
17
+ p.color :silver, hex: "#f8f8f2", ansi: "white" # StatusLine guibg = fg
18
+ p.color :mid_gray, hex: "#808080", ansi: "brightblack" # PmenuSel guibg
19
+ p.color :delim, hex: "#8f8f8f", ansi: "white" # Delimiter guifg
20
+
21
+ # Accent colors
22
+ p.color :pink, hex: "#f92672", ansi: "red" # Keyword guifg
23
+ p.color :green, hex: "#a6e22e", ansi: "green" # Function guifg
24
+ p.color :yellow, hex: "#e6db74", ansi: "yellow" # String guifg
25
+ p.color :purple, hex: "#ae81ff", ansi: "magenta" # Number guifg
26
+ p.color :orange, hex: "#fd971f", ansi: "yellow" # Identifier guifg
27
+ p.color :cyan, hex: "#66d9ef", ansi: "cyan" # Type guifg
28
+ p.color :search, hex: "#ffe792", ansi: "yellow" # Search guibg
29
+ end
30
+
31
+ t.default_colors foreground: :fg, background: :bg
32
+
33
+ # Programming faces
34
+ t.face :comment, foreground: :comment
35
+ t.face :preprocessing_directive, foreground: :green
36
+ t.face :keyword, foreground: :pink, bold: true
37
+ t.face :string, foreground: :yellow
38
+ t.face :number, foreground: :purple
39
+ t.face :constant, foreground: :purple, bold: true
40
+ t.face :function_name, foreground: :green
41
+ t.face :type, foreground: :cyan
42
+ t.face :variable, foreground: :orange
43
+ t.face :operator, foreground: :pink
44
+ t.face :punctuation, foreground: :delim
45
+ t.face :builtin, foreground: :cyan
46
+ t.face :property, foreground: :orange
47
+
48
+ # Basic faces
49
+ t.face :mode_line, foreground: :gray, background: :silver
50
+ t.face :link, foreground: :cyan, underline: true
51
+ t.face :control
52
+ t.face :region, background: :bg1
53
+ t.face :isearch, foreground: :bg, background: :search
54
+ t.face :floating_window, foreground: :fg, background: :bg2
55
+
56
+ # Completion faces
57
+ t.face :completion_popup, foreground: :cyan, background: :bg
58
+ t.face :completion_popup_selected, foreground: :fg, background: :mid_gray
59
+
60
+ # Dired faces
61
+ t.face :dired_directory, foreground: :green, bold: true
62
+ t.face :dired_symlink, foreground: :cyan
63
+ t.face :dired_executable, foreground: :green
64
+ t.face :dired_flagged, foreground: :pink
65
+ end
@@ -0,0 +1,67 @@
1
+ # Sonokai theme for Textbringer (default style)
2
+ # Based on https://github.com/sainnhe/sonokai
3
+ #
4
+ # GUI hex values from the source's default style palette.
5
+ # A dark theme only. Falls back to dark palette on light terminals.
6
+
7
+ Textbringer::Theme.define "sonokai" do |t|
8
+ t.palette :dark do |p|
9
+ # Base tones
10
+ p.color :black, hex: "#181819", ansi: "black"
11
+ p.color :bg_dim, hex: "#222327", ansi: "black"
12
+ p.color :bg0, hex: "#2c2e34", ansi: "black"
13
+ p.color :bg1, hex: "#33353f", ansi: "brightblack"
14
+ p.color :bg2, hex: "#363944", ansi: "brightblack"
15
+ p.color :bg3, hex: "#3b3e48", ansi: "brightblack"
16
+ p.color :bg4, hex: "#414550", ansi: "brightblack"
17
+ p.color :fg, hex: "#e2e2e3", ansi: "white"
18
+ p.color :grey, hex: "#7f8490", ansi: "white"
19
+ p.color :grey_dim, hex: "#595f6f", ansi: "brightblack"
20
+
21
+ # Accent colors
22
+ p.color :red, hex: "#fc5d7c", ansi: "red"
23
+ p.color :orange, hex: "#f39660", ansi: "yellow"
24
+ p.color :yellow, hex: "#e7c664", ansi: "yellow"
25
+ p.color :green, hex: "#9ed072", ansi: "green"
26
+ p.color :blue, hex: "#76cce0", ansi: "cyan"
27
+ p.color :purple, hex: "#b39df3", ansi: "magenta"
28
+
29
+ # Filled colors for UI
30
+ p.color :filled_blue, hex: "#85d3f2", ansi: "cyan"
31
+ end
32
+
33
+ t.default_colors foreground: :fg, background: :bg0
34
+
35
+ # Programming faces (from sonokai highlight groups)
36
+ t.face :comment, foreground: :grey
37
+ t.face :preprocessing_directive, foreground: :red
38
+ t.face :keyword, foreground: :red
39
+ t.face :string, foreground: :yellow
40
+ t.face :number, foreground: :purple
41
+ t.face :constant, foreground: :orange
42
+ t.face :function_name, foreground: :green
43
+ t.face :type, foreground: :blue
44
+ t.face :variable, foreground: :orange
45
+ t.face :operator, foreground: :red
46
+ t.face :punctuation
47
+ t.face :builtin, foreground: :green
48
+ t.face :property, foreground: :blue
49
+
50
+ # Basic faces
51
+ t.face :mode_line, foreground: :fg, background: :bg3
52
+ t.face :link, foreground: :blue, underline: true
53
+ t.face :control
54
+ t.face :region, background: :bg4
55
+ t.face :isearch, foreground: :green, background: :bg0, reverse: true
56
+ t.face :floating_window, foreground: :fg, background: :bg_dim
57
+
58
+ # Completion faces
59
+ t.face :completion_popup, foreground: :fg, background: :bg2
60
+ t.face :completion_popup_selected, foreground: :bg0, background: :filled_blue
61
+
62
+ # Dired faces
63
+ t.face :dired_directory, foreground: :green
64
+ t.face :dired_symlink, foreground: :blue
65
+ t.face :dired_executable, foreground: :green
66
+ t.face :dired_flagged, foreground: :red
67
+ end
@@ -0,0 +1,70 @@
1
+ # Tokyo Night theme for Textbringer
2
+ # Based on https://github.com/folke/tokyonight.nvim
3
+ # Night variant (dark only).
4
+ # GUI hex values from the source palette definitions.
5
+
6
+ Textbringer::Theme.define "tokyonight" do |t|
7
+ t.palette :dark do |p|
8
+ # Background / foreground (night variant)
9
+ p.color :bg, hex: "#1a1b26", ansi: "black" # bg
10
+ p.color :bg_dark, hex: "#16161e", ansi: "black" # bg_dark → popups, statusline
11
+ p.color :bg_hl, hex: "#292e42", ansi: "brightblack" # bg_highlight → floating windows
12
+ p.color :bg_vis, hex: "#283357", ansi: "brightblack" # bg_visual = blend(blue0, 0.4, bg)
13
+ p.color :sel_bg, hex: "#343a55", ansi: "brightblack" # PmenuSel bg = blend(fg_gutter, 0.8, bg)
14
+ p.color :search, hex: "#3d59a1", ansi: "blue" # bg_search = blue0
15
+ p.color :fg, hex: "#c0caf5", ansi: "white" # fg
16
+ p.color :fg_dark, hex: "#a9b1d6", ansi: "white" # fg_dark → statusline fg
17
+ p.color :comment, hex: "#565f89", ansi: "brightblack" # comment
18
+
19
+ # Accent colors
20
+ p.color :blue, hex: "#7aa2f7", ansi: "blue" # Function, Directory, link
21
+ p.color :cyan, hex: "#7dcfff", ansi: "cyan" # PreProc, Keyword (base groups)
22
+ p.color :purple, hex: "#9d7cd8", ansi: "magenta" # @keyword (treesitter default)
23
+ p.color :magenta, hex: "#bb9af7", ansi: "magenta" # Identifier, Statement
24
+ p.color :green, hex: "#9ece6a", ansi: "green" # String
25
+ p.color :teal, hex: "#73daca", ansi: "cyan" # @property, @variable.member
26
+ p.color :orange, hex: "#ff9e64", ansi: "yellow" # Constant
27
+ p.color :red, hex: "#f7768e", ansi: "red" # @variable.builtin, flagged files
28
+ p.color :blue1, hex: "#2ac3de", ansi: "cyan" # Type, Special
29
+ p.color :blue5, hex: "#89ddff", ansi: "cyan" # Operator, punctuation delimiters
30
+ end
31
+
32
+ t.default_colors foreground: :fg, background: :bg
33
+
34
+ # Programming faces
35
+ t.face :comment, foreground: :comment
36
+ t.face :preprocessing_directive, foreground: :cyan # PreProc = c.cyan
37
+ t.face :keyword, foreground: :purple # @keyword = c.purple (treesitter)
38
+ t.face :string, foreground: :green # String = c.green
39
+ t.face :number, foreground: :orange # Number → Constant = c.orange
40
+ t.face :constant, foreground: :orange # Constant = c.orange
41
+ t.face :function_name, foreground: :blue # Function = c.blue
42
+ t.face :type, foreground: :blue1 # Type = c.blue1
43
+ t.face :variable, foreground: :magenta # Identifier = c.magenta
44
+ t.face :operator, foreground: :blue5 # Operator = c.blue5
45
+ t.face :punctuation, foreground: :blue5 # @punctuation.delimiter = c.blue5
46
+ t.face :builtin, foreground: :blue1 # Special = c.blue1
47
+ t.face :property, foreground: :teal # @property = c.green1 (teal)
48
+
49
+ # Basic faces
50
+ # StatusLine: fg = fg_dark, bg = bg_dark
51
+ t.face :mode_line, foreground: :fg_dark, background: :bg_dark
52
+ t.face :link, foreground: :blue, underline: true
53
+ t.face :control
54
+ t.face :region, background: :bg_vis # Visual = bg_visual
55
+ # Search: bg = bg_search (blue0 = #3d59a1), fg = fg
56
+ t.face :isearch, foreground: :fg, background: :search
57
+ t.face :floating_window, foreground: :fg, background: :bg_hl
58
+
59
+ # Completion faces
60
+ # Pmenu: bg = bg_dark, fg = fg
61
+ # PmenuSel: bg = blend(fg_gutter, 0.8, bg) ≈ #343a55
62
+ t.face :completion_popup, foreground: :fg, background: :bg_dark
63
+ t.face :completion_popup_selected, foreground: :fg, background: :sel_bg
64
+
65
+ # Dired faces
66
+ t.face :dired_directory, foreground: :blue, bold: true # Directory = c.blue
67
+ t.face :dired_symlink, foreground: :teal
68
+ t.face :dired_executable, foreground: :green
69
+ t.face :dired_flagged, foreground: :red
70
+ end