Skip to content

Commit

Permalink
FaceConfig.new now takes keyword arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
hasumikin committed Oct 10, 2023
1 parent cab307f commit e4d61dd
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 96 deletions.
12 changes: 6 additions & 6 deletions lib/reline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -601,15 +601,15 @@ def self.line_editor
end

Reline::Face.config(:default) do |face|
face.define :default, :default_style
face.define :enhanced, :default_style
face.define :scrollbar, :default_style
face.define :default, style: :default
face.define :enhanced, style: :default
face.define :scrollbar, style: :default
end

Reline::Face.config(:completion_dialog) do |face|
face.define :default, :white_foreground, :cyan_background
face.define :enhanced, :white_foreground, :magenta_background
face.define :scrollbar, :white_foreground, :cyan_background
face.define :default, foreground: :white, background: :cyan
face.define :enhanced, foreground: :white, background: :magenta
face.define :scrollbar, foreground: :white, background: :cyan
end

Reline::HISTORY = Reline::History.new(Reline.core.config)
152 changes: 78 additions & 74 deletions lib/reline/face.rb
Original file line number Diff line number Diff line change
@@ -1,53 +1,56 @@
class Reline::Face
SGR_PARAMETERS = {
# Foreground
black_foreground: 30,
red_foreground: 31,
green_foreground: 32,
yellow_foreground: 33,
blue_foreground: 34,
magenta_foreground: 35,
cyan_foreground: 36,
white_foreground: 37,
bright_black_foreground: 90,
gray_foreground: 90,
bright_red_foreground: 91,
bright_green_foreground: 92,
bright_yellow_foreground: 93,
bright_blue_foreground: 94,
bright_magenta_foreground: 95,
bright_cyan_foreground: 96,
bright_white_foreground: 97,
# Background
black_background: 40,
red_background: 41,
green_background: 42,
yellow_background: 43,
blue_background: 44,
magenta_background: 45,
cyan_background: 46,
white_background: 47,
bright_black_background: 100,
gray_background: 100,
bright_red_background: 101,
bright_green_background: 102,
bright_yellow_background: 103,
bright_blue_background: 104,
bright_magenta_background: 105,
bright_cyan_background: 106,
bright_white_background: 107,
# Style
default_style: 0,
bold: 1,
faint: 2,
italicized: 3,
underlined: 4,
slowly_blinking: 5,
blinking: 5,
rapidly_blinking: 6,
negative: 7,
concealed: 8,
crossed_out: 9
foreground: {
black: 30,
red: 31,
green: 32,
yellow: 33,
blue: 34,
magenta: 35,
cyan: 36,
white: 37,
bright_black: 90,
gray: 90,
bright_red: 91,
bright_green: 92,
bright_yellow: 93,
bright_blue: 94,
bright_magenta: 95,
bright_cyan: 96,
bright_white: 97
},
background: {
black: 40,
red: 41,
green: 42,
yellow: 43,
blue: 44,
magenta: 45,
cyan: 46,
white: 47,
bright_black: 100,
gray: 100,
bright_red: 101,
bright_green: 102,
bright_yellow: 103,
bright_blue: 104,
bright_magenta: 105,
bright_cyan: 106,
bright_white: 107,
},
style: {
default: 0,
bold: 1,
faint: 2,
italicized: 3,
underlined: 4,
slowly_blinking: 5,
blinking: 5,
rapidly_blinking: 6,
negative: 7,
concealed: 8,
crossed_out: 9
}
}.freeze

class FaceConfig
Expand All @@ -57,25 +60,19 @@ def initialize(name, &block)
define(:default) unless self.respond_to?(:default)
end

def define(name, *sgr_values)
sgr_values.each do |value|
sgr_valid?(value) or raise ArgumentError, "invalid SGR parameter: #{value.inspect}"
end
sgr = "\e[" + sgr_values.map { |value|
case value
when Symbol
SGR_PARAMETERS[value]
when Hash
key, v = value.first
sgr_rgb(key, v)
end
}.join(';') + "m"
def define(name, foreground: nil, background: nil, style: nil)
values = {}
values[:foreground] = foreground if foreground
values[:background] = background if background
values[:style] = style if style
sgr = format_to_sgr(values)
define_singleton_method(name) { sgr }
end

private

def sgr_rgb(key, value)
return nil unless rgb_expression?(value)
case key
when :foreground
"38;2;"
Expand All @@ -84,21 +81,28 @@ def sgr_rgb(key, value)
end + value[1, 6].scan(/../).map(&:hex).join(";")
end

def sgr_valid?(sgr_value)
case sgr_value
when Symbol
SGR_PARAMETERS.keys.include?(sgr_value)
when Hash
sgr_value.count == 1 or return false
key, value = sgr_value.first
%i(foreground background).include?(key) or return false
rgb?(value) or return false
else
false
end
def format_to_sgr(values)
"\e[" << values.map do |key, value|
case key
when :foreground, :background
case value
when Symbol
SGR_PARAMETERS[key][value]
when String
sgr_rgb(key, value)
end
when :style
[ value ].flatten.map { |style_name| SGR_PARAMETERS[:style][style_name] }
end.then do |rendition_expression|
unless rendition_expression
raise ArgumentError, "invalid SGR parameter: #{value.inspect}"
end
rendition_expression
end
end.join(';') << "m"
end

def rgb?(color)
def rgb_expression?(color)
color.respond_to?(:match?) and color.match?(/\A#[0-9a-fA-F]{6}\z/)
end
end
Expand Down
45 changes: 29 additions & 16 deletions test/reline/test_face.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ class Reline::Face::Test < Reline::TestCase
class WithSetupTest < self
def setup
Reline::Face.config(:my_config) do |face|
face.define :default, :blue_foreground
face.define :enhanced, { foreground: "#FF1020" }, :black_background, :bold, :underlined
face.define :default, foreground: :blue
face.define :enhanced, foreground: "#FF1020", background: :black, style: [:bold, :underlined]
end
Reline::Face.config(:another_config) do |face|
face.define :another_label, :red_foreground
face.define :another_label, foreground: :red
end
@face = Reline::Face[:my_config]
end
Expand All @@ -27,21 +27,21 @@ def test_not_respond_to_another_label

def test_existing_config_override_default
Reline::Face.config(:my_config) do |face|
face.define :default, :red_foreground
face.define :default, foreground: :red
end
assert_equal "\e[31m", Reline::Face[:my_config].default
end

def test_existing_config_override_false
Reline::Face.config(:my_config, false) do |face|
face.define :default, :red_foreground
face.define :default, foreground: :red
end
assert_equal "\e[34m", Reline::Face[:my_config].default
end

def test_new_config_override_false
Reline::Face.config(:new_config, false) do |face|
face.define :default, :red_foreground
face.define :default, foreground: :red
end
assert_equal "\e[31m", Reline::Face[:new_config].default
end
Expand All @@ -56,18 +56,26 @@ def test_my_config_default
assert_equal "\e[m", face.default
end

def test_invalid_keyword
assert_raise ArgumentError do
Reline::Face.config(:invalid_config) do |face|
face.define :default, invalid_keyword: :red
end
end
end

def test_invalid_foreground_name
assert_raise ArgumentError do
Reline::Face.config(:invalid_config) do |face|
face.define :default, :invalid_foreground
face.define :default, foreground: :invalid_name
end
end
end

def test_invalid_background_name
assert_raise ArgumentError do
Reline::Face.config(:invalid_config) do |face|
face.define :default, :invalid_background
face.define :default, background: :invalid_name
end
end
end
Expand All @@ -85,21 +93,26 @@ def setup
end

def test_rgb?
assert_equal true, @face_config.send(:rgb?, "#FFFFFF")
assert_equal true, @face_config.send(:rgb_expression?, "#FFFFFF")
end

def test_invalid_rgb?
assert_equal false, @face_config.send(:rgb?, "FFFFFF")
assert_equal false, @face_config.send(:rgb?, "#FFFFF")
assert_equal false, @face_config.send(:rgb_expression?, "FFFFFF")
assert_equal false, @face_config.send(:rgb_expression?, "#FFFFF")
end

def test_sgr_valid?
assert_equal true, @face_config.send(:sgr_valid?, :white_foreground)
assert_equal true, @face_config.send(:sgr_valid?, { foreground: "#ffffff" })
def test_format_to_sgr
assert_equal(
"\e[37;41;1;3m",
@face_config.send(:format_to_sgr, foreground: :white, background: :red, style: [:bold, :italicized])
)
end

def test_invalid_sgr_valid?
assert_equal false, @face_config.send(:sgr_valid?, { invalid_key: "#ffffff" })
def test_format_to_sgr_with_single_style
assert_equal(
"\e[37;41;1m",
@face_config.send(:format_to_sgr, foreground: :white, background: :red, style: :bold)
)
end

def test_sgr_rgb
Expand Down

0 comments on commit e4d61dd

Please sign in to comment.