aboutsummaryrefslogtreecommitdiffstats
path: root/lib/reline/face.rb
diff options
context:
space:
mode:
authortomoya ishida <tomoyapenguin@gmail.com>2023-11-13 21:42:25 +0900
committergit <svn-admin@ruby-lang.org>2023-11-13 12:42:31 +0000
commit90b49024c0d5fe8fe60942b96dcbd1f610042f1b (patch)
tree71d11125058e206f912f1a17d3027cfb1e969a8e /lib/reline/face.rb
parent8e64c87f64508bf7192d44581632aff6dce15bf6 (diff)
downloadruby-90b49024c0d5fe8fe60942b96dcbd1f610042f1b.tar.gz
[ruby/reline] Fallback to 256color if COLORTERM != truecolor
(https://github.com/ruby/reline/pull/604) * Fallback to 256color if COLORTERM != truecolor * Add Reline::Face.force_truecolor to force truecolor without COLORTERM env https://github.com/ruby/reline/commit/090e1e4df0
Diffstat (limited to 'lib/reline/face.rb')
-rw-r--r--lib/reline/face.rb42
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/reline/face.rb b/lib/reline/face.rb
index b78f3b1ca5..e18ec957e8 100644
--- a/lib/reline/face.rb
+++ b/lib/reline/face.rb
@@ -74,6 +74,13 @@ class Reline::Face
@definition[name] = values
end
+ def reconfigure
+ @definition.each_value do |values|
+ values.delete(:escape_sequence)
+ values[:escape_sequence] = format_to_sgr(values.to_a).freeze
+ end
+ end
+
def [](name)
@definition.dig(name, :escape_sequence) or raise ArgumentError, "unknown face: #{name}"
end
@@ -82,6 +89,14 @@ class Reline::Face
def sgr_rgb(key, value)
return nil unless rgb_expression?(value)
+ if Reline::Face.truecolor?
+ sgr_rgb_truecolor(key, value)
+ else
+ sgr_rgb_256color(key, value)
+ end
+ end
+
+ def sgr_rgb_truecolor(key, value)
case key
when :foreground
"38;2;"
@@ -90,6 +105,24 @@ class Reline::Face
end + value[1, 6].scan(/../).map(&:hex).join(";")
end
+ def sgr_rgb_256color(key, value)
+ # 256 colors are
+ # 0..15: standard colors, hight intensity colors
+ # 16..232: 216 colors (R, G, B each 6 steps)
+ # 233..255: grayscale colors (24 steps)
+ # This methods converts rgb_expression to 216 colors
+ rgb = value[1, 6].scan(/../).map(&:hex)
+ # Color steps are [0, 95, 135, 175, 215, 255]
+ r, g, b = rgb.map { |v| v <= 95 ? v / 48 : (v - 35) / 40 }
+ color = (16 + 36 * r + 6 * g + b)
+ case key
+ when :foreground
+ "38;5;#{color}"
+ when :background
+ "48;5;#{color}"
+ end
+ end
+
def format_to_sgr(ordered_values)
sgr = "\e[" + ordered_values.map do |key_value|
key, value = key_value
@@ -124,6 +157,15 @@ class Reline::Face
private_constant :SGR_PARAMETERS, :Config
+ def self.truecolor?
+ @force_truecolor || %w[truecolor 24bit].include?(ENV['COLORTERM'])
+ end
+
+ def self.force_truecolor
+ @force_truecolor = true
+ @configs&.each_value(&:reconfigure)
+ end
+
def self.[](name)
@configs[name]
end