textbringer 24 → 25
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.
- checksums.yaml +4 -4
- data/exe/txtb +1 -0
- data/lib/textbringer/buffer.rb +19 -11
- data/lib/textbringer/commands/misc.rb +19 -0
- data/lib/textbringer/commands/windows.rb +14 -0
- data/lib/textbringer/config.rb +2 -1
- data/lib/textbringer/face.rb +71 -15
- data/lib/textbringer/gamegrid.rb +2 -6
- data/lib/textbringer/highlight_context.rb +21 -0
- data/lib/textbringer/mode.rb +25 -0
- data/lib/textbringer/modes/gamegrid_mode.rb +6 -1
- data/lib/textbringer/modes/ruby_mode.rb +298 -181
- data/lib/textbringer/theme.rb +180 -0
- data/lib/textbringer/themes/catppuccin.rb +105 -0
- data/lib/textbringer/themes/github.rb +89 -0
- data/lib/textbringer/themes/gruvbox.rb +84 -0
- data/lib/textbringer/themes/molokai.rb +67 -0
- data/lib/textbringer/themes/sonokai.rb +63 -0
- data/lib/textbringer/themes/tokyonight.rb +70 -0
- data/lib/textbringer/version.rb +1 -1
- data/lib/textbringer/window.rb +28 -41
- data/lib/textbringer.rb +2 -0
- data/textbringer.gemspec +1 -0
- metadata +23 -5
- data/lib/textbringer/faces/basic.rb +0 -8
- data/lib/textbringer/faces/completion.rb +0 -4
- data/lib/textbringer/faces/dired.rb +0 -6
- data/lib/textbringer/faces/programming.rb +0 -6
|
@@ -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,105 @@
|
|
|
1
|
+
# Catppuccin theme for Textbringer
|
|
2
|
+
# Based on https://github.com/catppuccin/nvim
|
|
3
|
+
#
|
|
4
|
+
# Dark variant: Mocha Light variant: Latte
|
|
5
|
+
|
|
6
|
+
Textbringer::Theme.define "catppuccin" do |t|
|
|
7
|
+
t.palette :dark do |p|
|
|
8
|
+
# Catppuccin Mocha base tones
|
|
9
|
+
p.color :text, hex: "#d7d7ff", ansi: "white"
|
|
10
|
+
p.color :subtext1, hex: "#afafd7", ansi: "white"
|
|
11
|
+
p.color :subtext0, hex: "#afafd7", ansi: "white"
|
|
12
|
+
p.color :overlay2, hex: "#8787af", ansi: "white"
|
|
13
|
+
p.color :overlay1, hex: "#8787af", ansi: "white"
|
|
14
|
+
p.color :overlay0, hex: "#767676", ansi: "brightblack"
|
|
15
|
+
p.color :surface2, hex: "#626262", ansi: "brightblack"
|
|
16
|
+
p.color :surface1, hex: "#4e4e4e", ansi: "brightblack"
|
|
17
|
+
p.color :surface0, hex: "#3a3a3a", ansi: "brightblack"
|
|
18
|
+
p.color :base, hex: "#262626", ansi: "black"
|
|
19
|
+
p.color :mantle, hex: "#1c1c1c", ansi: "black"
|
|
20
|
+
p.color :crust, hex: "#121212", ansi: "black"
|
|
21
|
+
|
|
22
|
+
# Catppuccin Mocha accent colors
|
|
23
|
+
p.color :red, hex: "#ff87af", ansi: "red"
|
|
24
|
+
p.color :maroon, hex: "#d7afaf", ansi: "red"
|
|
25
|
+
p.color :peach, hex: "#ffaf87", ansi: "yellow"
|
|
26
|
+
p.color :yellow, hex: "#ffd7af", ansi: "yellow"
|
|
27
|
+
p.color :green, hex: "#afd7af", ansi: "green"
|
|
28
|
+
p.color :teal, hex: "#87d7d7", ansi: "cyan"
|
|
29
|
+
p.color :sky, hex: "#87d7d7", ansi: "cyan"
|
|
30
|
+
p.color :sapphire, hex: "#87d7ff", ansi: "cyan"
|
|
31
|
+
p.color :blue, hex: "#87afff", ansi: "blue"
|
|
32
|
+
p.color :lavender, hex: "#afafff", ansi: "blue"
|
|
33
|
+
p.color :mauve, hex: "#d7afff", ansi: "magenta"
|
|
34
|
+
p.color :pink, hex: "#ffafd7", ansi: "magenta"
|
|
35
|
+
p.color :flamingo, hex: "#ffd7d7", ansi: "red"
|
|
36
|
+
p.color :rosewater, hex: "#ffd7d7", ansi: "red"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
t.palette :light do |p|
|
|
40
|
+
# Catppuccin Latte base tones
|
|
41
|
+
p.color :text, hex: "#585858", ansi: "black"
|
|
42
|
+
p.color :subtext1, hex: "#5f5f87", ansi: "black"
|
|
43
|
+
p.color :subtext0, hex: "#767676", ansi: "brightblack"
|
|
44
|
+
p.color :overlay2, hex: "#878787", ansi: "brightblack"
|
|
45
|
+
p.color :overlay1, hex: "#949494", ansi: "white"
|
|
46
|
+
p.color :overlay0, hex: "#a8a8a8", ansi: "white"
|
|
47
|
+
p.color :surface2, hex: "#b2b2b2", ansi: "white"
|
|
48
|
+
p.color :surface1, hex: "#c6c6c6", ansi: "white"
|
|
49
|
+
p.color :surface0, hex: "#d0d0d0", ansi: "white"
|
|
50
|
+
p.color :base, hex: "#eeeeee", ansi: "white"
|
|
51
|
+
p.color :mantle, hex: "#eeeeee", ansi: "white"
|
|
52
|
+
p.color :crust, hex: "#e4e4e4", ansi: "white"
|
|
53
|
+
|
|
54
|
+
# Catppuccin Latte accent colors
|
|
55
|
+
p.color :red, hex: "#d7005f", ansi: "red"
|
|
56
|
+
p.color :maroon, hex: "#d75f5f", ansi: "red"
|
|
57
|
+
p.color :peach, hex: "#ff5f00", ansi: "red"
|
|
58
|
+
p.color :yellow, hex: "#d78700", ansi: "yellow"
|
|
59
|
+
p.color :green, hex: "#5faf00", ansi: "green"
|
|
60
|
+
p.color :teal, hex: "#008787", ansi: "cyan"
|
|
61
|
+
p.color :sky, hex: "#00afd7", ansi: "cyan"
|
|
62
|
+
p.color :sapphire, hex: "#00afaf", ansi: "cyan"
|
|
63
|
+
p.color :blue, hex: "#005fff", ansi: "blue"
|
|
64
|
+
p.color :lavender, hex: "#5f87ff", ansi: "blue"
|
|
65
|
+
p.color :mauve, hex: "#875fff", ansi: "magenta"
|
|
66
|
+
p.color :pink, hex: "#d787d7", ansi: "magenta"
|
|
67
|
+
p.color :flamingo, hex: "#d78787", ansi: "red"
|
|
68
|
+
p.color :rosewater, hex: "#d78787", ansi: "red"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
t.default_colors foreground: :text, background: :base
|
|
72
|
+
|
|
73
|
+
# Programming faces (from catppuccin/nvim syntax.lua)
|
|
74
|
+
t.face :comment, foreground: :overlay2
|
|
75
|
+
t.face :preprocessing_directive, foreground: :pink
|
|
76
|
+
t.face :keyword, foreground: :mauve
|
|
77
|
+
t.face :string, foreground: :green
|
|
78
|
+
t.face :number, foreground: :peach
|
|
79
|
+
t.face :constant, foreground: :peach
|
|
80
|
+
t.face :function_name, foreground: :blue
|
|
81
|
+
t.face :type, foreground: :yellow
|
|
82
|
+
t.face :variable, foreground: :flamingo
|
|
83
|
+
t.face :operator, foreground: :sky
|
|
84
|
+
t.face :punctuation
|
|
85
|
+
t.face :builtin, foreground: :red
|
|
86
|
+
t.face :property, foreground: :lavender
|
|
87
|
+
|
|
88
|
+
# Basic faces (from catppuccin/nvim editor.lua)
|
|
89
|
+
t.face :mode_line, foreground: :text, background: :mantle
|
|
90
|
+
t.face :link, foreground: :blue, underline: true
|
|
91
|
+
t.face :control
|
|
92
|
+
t.face :region, background: :surface1
|
|
93
|
+
t.face :isearch, foreground: :mantle, background: :red
|
|
94
|
+
t.face :floating_window, foreground: :text, background: :mantle
|
|
95
|
+
|
|
96
|
+
# Completion faces
|
|
97
|
+
t.face :completion_popup, foreground: :overlay2, background: :mantle
|
|
98
|
+
t.face :completion_popup_selected, background: :surface0
|
|
99
|
+
|
|
100
|
+
# Dired faces
|
|
101
|
+
t.face :dired_directory, foreground: :blue
|
|
102
|
+
t.face :dired_symlink, foreground: :teal
|
|
103
|
+
t.face :dired_executable, foreground: :green
|
|
104
|
+
t.face :dired_flagged, foreground: :red
|
|
105
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
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
|
+
# Light palette: cterm values from source (accurate).
|
|
6
|
+
# Dark palette: GUI hex values — dark-mode cterm values in source are unreliable
|
|
7
|
+
# (e.g. dcolors.blue has cterm=167 which maps to red, overlay has cterm=123
|
|
8
|
+
# which maps to bright cyan).
|
|
9
|
+
|
|
10
|
+
Textbringer::Theme.define "github" do |t|
|
|
11
|
+
t.palette :light do |p|
|
|
12
|
+
# Backgrounds / foreground
|
|
13
|
+
p.color :bg, hex: "#ffffff", ansi: "white" # 231 Normal bg
|
|
14
|
+
p.color :bg1, hex: "#eeeeee", ansi: "white" # 255 overlay/gutter/panels
|
|
15
|
+
p.color :vis, hex: "#afd7ff", ansi: "blue" # 153 Visual selection bg (blue2)
|
|
16
|
+
p.color :search, hex: "#ffffd7", ansi: "yellow" # 230 Search bg (yellow)
|
|
17
|
+
p.color :fg, hex: "#262626", ansi: "black" # 235 Normal fg (base0)
|
|
18
|
+
p.color :comment, hex: "#767676", ansi: "brightblack" # 243 Comment (base2)
|
|
19
|
+
p.color :line_nr, hex: "#bcbcbc", ansi: "white" # 250 LineNr fg (base4)
|
|
20
|
+
|
|
21
|
+
# Syntax colors
|
|
22
|
+
p.color :red, hex: "#d75f5f", ansi: "red" # 167 Statement, Type, PreProc
|
|
23
|
+
p.color :darkred, hex: "#af0000", ansi: "red" # 124 darkred
|
|
24
|
+
p.color :purple, hex: "#8700af", ansi: "magenta" # 91 Function, Define, Special
|
|
25
|
+
p.color :green, hex: "#00875f", ansi: "green" # 29 html/xml tags
|
|
26
|
+
p.color :orange, hex: "#d75f00", ansi: "yellow" # 166 orange
|
|
27
|
+
p.color :blue, hex: "#005fd7", ansi: "blue" # 26 Identifier, Constant, Macro
|
|
28
|
+
p.color :darkblue, hex: "#00005f", ansi: "blue" # 17 String
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
t.palette :dark do |p|
|
|
32
|
+
# Backgrounds / foreground (GUI hex — cterm values are unreliable in source)
|
|
33
|
+
p.color :bg, hex: "#24292e", ansi: "black" # base0 (Normal bg)
|
|
34
|
+
p.color :bg1, hex: "#353a3f", ansi: "brightblack" # dcolors.overlay (panels/popups)
|
|
35
|
+
p.color :vis, hex: "#354a60", ansi: "blue" # dcolors.blue2 / blues[4]
|
|
36
|
+
p.color :search, hex: "#595322", ansi: "yellow" # dcolors.yellow (Search bg)
|
|
37
|
+
p.color :fg, hex: "#fafbfc", ansi: "white" # fafbfc (Normal fg)
|
|
38
|
+
p.color :comment, hex: "#abaeb1", ansi: "brightblack" # darktext[2] (Comment)
|
|
39
|
+
p.color :line_nr, hex: "#76787b", ansi: "brightblack" # numDarkest (base4 in dark)
|
|
40
|
+
|
|
41
|
+
# Syntax colors (GUI hex)
|
|
42
|
+
p.color :red, hex: "#f16636", ansi: "red" # dcolors.red
|
|
43
|
+
p.color :darkred, hex: "#b31d28", ansi: "red" # s:colors.darkred (same both modes)
|
|
44
|
+
p.color :purple, hex: "#a887e6", ansi: "magenta" # dcolors.purple
|
|
45
|
+
p.color :green, hex: "#59b36f", ansi: "green" # dcolors.green
|
|
46
|
+
p.color :orange, hex: "#ffa657", ansi: "yellow" # s:colors.orange (same both modes)
|
|
47
|
+
p.color :blue, hex: "#4dacfd", ansi: "blue" # dcolors.blue
|
|
48
|
+
p.color :darkblue, hex: "#c1daec", ansi: "blue" # dcolors.darkblue = blue1
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
t.default_colors foreground: :fg, background: :bg
|
|
52
|
+
|
|
53
|
+
# Programming faces
|
|
54
|
+
t.face :comment, foreground: :comment # Comment = base2
|
|
55
|
+
t.face :preprocessing_directive, foreground: :red # PreProc = red
|
|
56
|
+
t.face :keyword, foreground: :red # Statement = red
|
|
57
|
+
t.face :string, foreground: :darkblue # String = darkblue
|
|
58
|
+
t.face :number, foreground: :blue # Number → Constant = blue
|
|
59
|
+
t.face :constant, foreground: :blue # Constant = blue
|
|
60
|
+
t.face :function_name, foreground: :purple # Function = purple
|
|
61
|
+
t.face :type, foreground: :orange # Type = orange
|
|
62
|
+
t.face :variable, foreground: :blue # Identifier = blue
|
|
63
|
+
t.face :operator # no explicit color in source
|
|
64
|
+
t.face :punctuation # Delimiter = fg (ghNormalNoBg)
|
|
65
|
+
t.face :builtin, foreground: :purple # Special = purple
|
|
66
|
+
t.face :property, foreground: :blue # Identifier = blue
|
|
67
|
+
|
|
68
|
+
# Basic faces
|
|
69
|
+
# StatusLine: fg=grey2 (~bg1), bg=base0 (~fg) — inverted from Normal in both modes
|
|
70
|
+
t.face :mode_line, foreground: :bg1, background: :fg
|
|
71
|
+
t.face :link, foreground: :blue, underline: true
|
|
72
|
+
t.face :control
|
|
73
|
+
t.face :region, background: :vis # Visual = visualblue
|
|
74
|
+
# Search has no explicit fg in source; fg inherits from Normal
|
|
75
|
+
t.face :isearch, foreground: :fg, background: :search
|
|
76
|
+
t.face :floating_window, foreground: :fg, background: :bg1
|
|
77
|
+
|
|
78
|
+
# Completion faces
|
|
79
|
+
# Pmenu: fg=base3 (≈ comment), bg=overlay (≈ bg1)
|
|
80
|
+
# PmenuSel: fg=overlay (≈ bg1), bg=blue; bold
|
|
81
|
+
t.face :completion_popup, foreground: :comment, background: :bg1
|
|
82
|
+
t.face :completion_popup_selected, foreground: :bg1, background: :blue, bold: true
|
|
83
|
+
|
|
84
|
+
# Dired faces
|
|
85
|
+
t.face :dired_directory, foreground: :blue # Directory → ghBlue
|
|
86
|
+
t.face :dired_symlink, foreground: :darkblue
|
|
87
|
+
t.face :dired_executable, foreground: :green
|
|
88
|
+
t.face :dired_flagged, foreground: :red
|
|
89
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Gruvbox theme for Textbringer
|
|
2
|
+
# Based on https://github.com/morhetz/gruvbox
|
|
3
|
+
#
|
|
4
|
+
# Dark: bright accent colors on warm dark background
|
|
5
|
+
# Light: neutral accent colors on warm light background
|
|
6
|
+
|
|
7
|
+
Textbringer::Theme.define "gruvbox" do |t|
|
|
8
|
+
t.palette :dark do |p|
|
|
9
|
+
# Base tones (dark background, light foreground)
|
|
10
|
+
p.color :bg0, hex: "#262626", ansi: "black"
|
|
11
|
+
p.color :bg1, hex: "#3a3a3a", ansi: "brightblack"
|
|
12
|
+
p.color :bg2, hex: "#4e4e4e", ansi: "brightblack"
|
|
13
|
+
p.color :bg3, hex: "#626262", ansi: "brightblack"
|
|
14
|
+
p.color :bg4, hex: "#767676", ansi: "white"
|
|
15
|
+
p.color :fg1, hex: "#ffd7af", ansi: "white"
|
|
16
|
+
p.color :fg4, hex: "#949494", ansi: "white"
|
|
17
|
+
p.color :gray, hex: "#8a8a8a", ansi: "white"
|
|
18
|
+
|
|
19
|
+
# Bright accent colors
|
|
20
|
+
p.color :red, hex: "#d75f5f", ansi: "red"
|
|
21
|
+
p.color :green, hex: "#afaf00", ansi: "green"
|
|
22
|
+
p.color :yellow, hex: "#ffaf00", ansi: "yellow"
|
|
23
|
+
p.color :blue, hex: "#87afaf", ansi: "blue"
|
|
24
|
+
p.color :purple, hex: "#d787af", ansi: "magenta"
|
|
25
|
+
p.color :aqua, hex: "#87af87", ansi: "cyan"
|
|
26
|
+
p.color :orange, hex: "#ff8700", ansi: "yellow"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
t.palette :light do |p|
|
|
30
|
+
# Base tones (light background, dark foreground)
|
|
31
|
+
p.color :bg0, hex: "#ffffaf", ansi: "white"
|
|
32
|
+
p.color :bg1, hex: "#ffd7af", ansi: "white"
|
|
33
|
+
p.color :bg2, hex: "#bcbcbc", ansi: "white"
|
|
34
|
+
p.color :bg3, hex: "#a8a8a8", ansi: "white"
|
|
35
|
+
p.color :bg4, hex: "#949494", ansi: "brightblack"
|
|
36
|
+
p.color :fg1, hex: "#3a3a3a", ansi: "black"
|
|
37
|
+
p.color :fg4, hex: "#767676", ansi: "brightblack"
|
|
38
|
+
p.color :gray, hex: "#8a8a8a", ansi: "brightblack"
|
|
39
|
+
|
|
40
|
+
# Neutral accent colors
|
|
41
|
+
p.color :red, hex: "#af0000", ansi: "red"
|
|
42
|
+
p.color :green, hex: "#87af00", ansi: "green"
|
|
43
|
+
p.color :yellow, hex: "#d78700", ansi: "yellow"
|
|
44
|
+
p.color :blue, hex: "#5f8787", ansi: "blue"
|
|
45
|
+
p.color :purple, hex: "#af5f87", ansi: "magenta"
|
|
46
|
+
p.color :aqua, hex: "#5faf87", ansi: "cyan"
|
|
47
|
+
p.color :orange, hex: "#d75f00", ansi: "red"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
t.default_colors foreground: :fg1, background: :bg0
|
|
51
|
+
|
|
52
|
+
# Programming faces
|
|
53
|
+
t.face :comment, foreground: :gray
|
|
54
|
+
t.face :preprocessing_directive, foreground: :aqua
|
|
55
|
+
t.face :keyword, foreground: :red
|
|
56
|
+
t.face :string, foreground: :green
|
|
57
|
+
t.face :number, foreground: :purple
|
|
58
|
+
t.face :constant, foreground: :purple
|
|
59
|
+
t.face :function_name, foreground: :green
|
|
60
|
+
t.face :type, foreground: :yellow
|
|
61
|
+
t.face :variable, foreground: :blue
|
|
62
|
+
t.face :operator
|
|
63
|
+
t.face :punctuation
|
|
64
|
+
t.face :builtin, foreground: :orange
|
|
65
|
+
t.face :property, foreground: :blue
|
|
66
|
+
|
|
67
|
+
# Basic faces
|
|
68
|
+
t.face :mode_line, foreground: :bg2, background: :fg1, reverse: true
|
|
69
|
+
t.face :link, foreground: :blue, underline: true
|
|
70
|
+
t.face :control
|
|
71
|
+
t.face :region, background: :bg3
|
|
72
|
+
t.face :isearch, foreground: :yellow, background: :bg0, reverse: true
|
|
73
|
+
t.face :floating_window, foreground: :fg1, background: :bg1
|
|
74
|
+
|
|
75
|
+
# Completion faces
|
|
76
|
+
t.face :completion_popup, foreground: :fg1, background: :bg2
|
|
77
|
+
t.face :completion_popup_selected, foreground: :bg2, background: :blue, bold: true
|
|
78
|
+
|
|
79
|
+
# Dired faces
|
|
80
|
+
t.face :dired_directory, foreground: :green, bold: true
|
|
81
|
+
t.face :dired_symlink, foreground: :aqua
|
|
82
|
+
t.face :dired_executable, foreground: :green
|
|
83
|
+
t.face :dired_flagged, foreground: :red
|
|
84
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
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
|
+
# Colors derived from molokai's 256-color (cterm) values.
|
|
6
|
+
# Dark only.
|
|
7
|
+
|
|
8
|
+
Textbringer::Theme.define "molokai" do |t|
|
|
9
|
+
t.palette :dark do |p|
|
|
10
|
+
# Background / foreground (cterm numbers in comments)
|
|
11
|
+
p.color :bg, hex: "#121212", ansi: "black" # 233 Normal bg
|
|
12
|
+
p.color :bg1, hex: "#262626", ansi: "brightblack" # 235 Visual, region
|
|
13
|
+
p.color :bg2, hex: "#303030", ansi: "brightblack" # 236 LineNr bg, floating windows
|
|
14
|
+
p.color :fg, hex: "#d0d0d0", ansi: "white" # 252 Normal fg
|
|
15
|
+
p.color :comment, hex: "#5f5f5f", ansi: "brightblack" # 59 Comment
|
|
16
|
+
p.color :gray, hex: "#444444", ansi: "brightblack" # 238 StatusLine fg
|
|
17
|
+
p.color :silver, hex: "#dadada", ansi: "white" # 253 StatusLine bg
|
|
18
|
+
p.color :mid_gray, hex: "#6c6c6c", ansi: "brightblack" # 242 PmenuSel bg
|
|
19
|
+
|
|
20
|
+
# Accent colors
|
|
21
|
+
p.color :pink, hex: "#d7005f", ansi: "red" # 161 Keyword, Operator
|
|
22
|
+
p.color :green, hex: "#87ff00", ansi: "green" # 118 Function, PreProc
|
|
23
|
+
p.color :yellow, hex: "#afaf87", ansi: "yellow" # 144 String, Character
|
|
24
|
+
p.color :purple, hex: "#af5fff", ansi: "magenta" # 135 Number, Boolean, Constant
|
|
25
|
+
p.color :orange, hex: "#ff8700", ansi: "yellow" # 208 Identifier, StorageClass
|
|
26
|
+
p.color :cyan, hex: "#5fd7ff", ansi: "cyan" # 81 Type, Define, Structure
|
|
27
|
+
p.color :search, hex: "#ffd787", ansi: "yellow" # 222 Search bg
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
t.default_colors foreground: :fg, background: :bg
|
|
31
|
+
|
|
32
|
+
# Programming faces
|
|
33
|
+
t.face :comment, foreground: :comment
|
|
34
|
+
t.face :preprocessing_directive, foreground: :green
|
|
35
|
+
t.face :keyword, foreground: :pink, bold: true
|
|
36
|
+
t.face :string, foreground: :yellow
|
|
37
|
+
t.face :number, foreground: :purple
|
|
38
|
+
t.face :constant, foreground: :purple, bold: true
|
|
39
|
+
t.face :function_name, foreground: :green
|
|
40
|
+
t.face :type, foreground: :cyan
|
|
41
|
+
t.face :variable, foreground: :orange
|
|
42
|
+
t.face :operator, foreground: :pink
|
|
43
|
+
t.face :punctuation
|
|
44
|
+
t.face :builtin, foreground: :cyan
|
|
45
|
+
t.face :property, foreground: :orange
|
|
46
|
+
|
|
47
|
+
# Basic faces
|
|
48
|
+
# StatusLine: ctermfg=238 (#444444) on ctermbg=253 (#DADADA)
|
|
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
|
+
# Search: ctermfg=0 ctermbg=222
|
|
54
|
+
t.face :isearch, foreground: :bg, background: :search
|
|
55
|
+
t.face :floating_window, foreground: :fg, background: :bg2
|
|
56
|
+
|
|
57
|
+
# Completion faces
|
|
58
|
+
# Pmenu: ctermfg=81 ctermbg=16; PmenuSel: ctermfg=252 ctermbg=242
|
|
59
|
+
t.face :completion_popup, foreground: :cyan, background: :bg
|
|
60
|
+
t.face :completion_popup_selected, foreground: :fg, background: :mid_gray
|
|
61
|
+
|
|
62
|
+
# Dired faces
|
|
63
|
+
t.face :dired_directory, foreground: :green, bold: true
|
|
64
|
+
t.face :dired_symlink, foreground: :cyan
|
|
65
|
+
t.face :dired_executable, foreground: :green
|
|
66
|
+
t.face :dired_flagged, foreground: :pink
|
|
67
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Sonokai theme for Textbringer (default style)
|
|
2
|
+
# Based on https://github.com/sainnhe/sonokai
|
|
3
|
+
#
|
|
4
|
+
# A dark theme only. Falls back to dark palette on light terminals.
|
|
5
|
+
|
|
6
|
+
Textbringer::Theme.define "sonokai" do |t|
|
|
7
|
+
t.palette :dark do |p|
|
|
8
|
+
# Base tones
|
|
9
|
+
p.color :black, hex: "#080808", ansi: "black"
|
|
10
|
+
p.color :bg_dim, hex: "#080808", ansi: "black"
|
|
11
|
+
p.color :bg0, hex: "#262626", ansi: "black"
|
|
12
|
+
p.color :bg1, hex: "#303030", ansi: "brightblack"
|
|
13
|
+
p.color :bg2, hex: "#303030", ansi: "brightblack"
|
|
14
|
+
p.color :bg3, hex: "#3a3a3a", ansi: "brightblack"
|
|
15
|
+
p.color :bg4, hex: "#3a3a3a", ansi: "brightblack"
|
|
16
|
+
p.color :fg, hex: "#bcbcbc", ansi: "white"
|
|
17
|
+
p.color :grey, hex: "#949494", ansi: "white"
|
|
18
|
+
p.color :grey_dim, hex: "#585858", ansi: "brightblack"
|
|
19
|
+
|
|
20
|
+
# Accent colors
|
|
21
|
+
p.color :red, hex: "#ff5f5f", ansi: "red"
|
|
22
|
+
p.color :orange, hex: "#ffaf5f", ansi: "yellow"
|
|
23
|
+
p.color :yellow, hex: "#d7af5f", ansi: "yellow"
|
|
24
|
+
p.color :green, hex: "#87af5f", ansi: "green"
|
|
25
|
+
p.color :blue, hex: "#87afd7", ansi: "cyan"
|
|
26
|
+
p.color :purple, hex: "#d787d7", ansi: "magenta"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
t.default_colors foreground: :fg, background: :bg0
|
|
30
|
+
|
|
31
|
+
# Programming faces (from sonokai highlight groups)
|
|
32
|
+
t.face :comment, foreground: :grey
|
|
33
|
+
t.face :preprocessing_directive, foreground: :red
|
|
34
|
+
t.face :keyword, foreground: :red
|
|
35
|
+
t.face :string, foreground: :yellow
|
|
36
|
+
t.face :number, foreground: :purple
|
|
37
|
+
t.face :constant, foreground: :orange
|
|
38
|
+
t.face :function_name, foreground: :green
|
|
39
|
+
t.face :type, foreground: :blue
|
|
40
|
+
t.face :variable, foreground: :orange
|
|
41
|
+
t.face :operator, foreground: :red
|
|
42
|
+
t.face :punctuation
|
|
43
|
+
t.face :builtin, foreground: :green
|
|
44
|
+
t.face :property, foreground: :blue
|
|
45
|
+
|
|
46
|
+
# Basic faces
|
|
47
|
+
t.face :mode_line, foreground: :fg, background: :bg3
|
|
48
|
+
t.face :link, foreground: :blue, underline: true
|
|
49
|
+
t.face :control
|
|
50
|
+
t.face :region, background: :bg4
|
|
51
|
+
t.face :isearch, foreground: :bg0, background: :green
|
|
52
|
+
t.face :floating_window, foreground: :fg, background: :bg_dim
|
|
53
|
+
|
|
54
|
+
# Completion faces
|
|
55
|
+
t.face :completion_popup, foreground: :fg, background: :bg2
|
|
56
|
+
t.face :completion_popup_selected, foreground: :bg0, background: :blue
|
|
57
|
+
|
|
58
|
+
# Dired faces
|
|
59
|
+
t.face :dired_directory, foreground: :green
|
|
60
|
+
t.face :dired_symlink, foreground: :blue
|
|
61
|
+
t.face :dired_executable, foreground: :green
|
|
62
|
+
t.face :dired_flagged, foreground: :red
|
|
63
|
+
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). GUI hex colors — no cterm values in source.
|
|
4
|
+
# Computed colors derived from tokyonight's blend formulas.
|
|
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: "#283457", 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
|
data/lib/textbringer/version.rb
CHANGED