Skip to content

Commit b32a977

Browse files
committed
Use color name instead of code (integer) in dialog color APIs
As pointed out in the [comment](#413 (comment)), the code is actually a control sequence and not only for colors. To make the dialog color APIs safer to use, we should restrict its usages and extract away the bg/fg concept from the input. So in this commit, I made these changes: 1. The dialog_*_bg/fg_color APIs only takes and returns color names (symbol): - :black - :red - :green - :yellow - :blue - :magenta - :cyan - :white 2. Add additional dialog_*_bg/fg_color_sequence APIs to access the raw code.
1 parent 6436169 commit b32a977

File tree

4 files changed

+131
-57
lines changed

4 files changed

+131
-57
lines changed

lib/reline.rb

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,21 @@ def match?(other)
4646
keyword_init: true
4747
)
4848

49+
DIALOG_COLOR_APIS = [
50+
:dialog_default_bg_color,
51+
:dialog_default_bg_color_sequence,
52+
:dialog_default_bg_color=,
53+
:dialog_default_fg_color,
54+
:dialog_default_fg_color_sequence,
55+
:dialog_default_fg_color=,
56+
:dialog_pointer_bg_color,
57+
:dialog_pointer_bg_color_sequence,
58+
:dialog_pointer_bg_color=,
59+
:dialog_pointer_fg_color,
60+
:dialog_pointer_fg_color_sequence,
61+
:dialog_pointer_fg_color=
62+
]
63+
4964
class Core
5065
ATTR_READER_NAMES = %i(
5166
completion_append_character
@@ -73,14 +88,7 @@ class Core
7388
def_delegators :config,
7489
:autocompletion,
7590
:autocompletion=,
76-
:dialog_default_bg_color,
77-
:dialog_default_bg_color=,
78-
:dialog_default_fg_color,
79-
:dialog_default_fg_color=,
80-
:dialog_pointer_bg_color,
81-
:dialog_pointer_bg_color=,
82-
:dialog_pointer_fg_color,
83-
:dialog_pointer_fg_color=
91+
*DIALOG_COLOR_APIS
8492

8593
def initialize
8694
self.output = STDOUT
@@ -264,10 +272,10 @@ def get_screen_size
264272
contents: result,
265273
scrollbar: true,
266274
height: 15,
267-
bg_color: config.dialog_default_bg_color,
268-
pointer_bg_color: config.dialog_pointer_bg_color,
269-
fg_color: config.dialog_default_fg_color,
270-
pointer_fg_color: config.dialog_pointer_fg_color
275+
bg_color: config.dialog_default_bg_color_sequence,
276+
pointer_bg_color: config.dialog_pointer_bg_color_sequence,
277+
fg_color: config.dialog_default_fg_color_sequence,
278+
pointer_fg_color: config.dialog_pointer_fg_color_sequence
271279
)
272280
}
273281
Reline::DEFAULT_DIALOG_CONTEXT = Array.new
@@ -553,10 +561,7 @@ def self.insert_text(*args, &block)
553561
def_single_delegators :core, :add_dialog_proc
554562
def_single_delegators :core, :dialog_proc
555563
def_single_delegators :core, :autocompletion, :autocompletion=
556-
def_single_delegators :core, :dialog_default_bg_color, :dialog_default_bg_color=
557-
def_single_delegators :core, :dialog_pointer_bg_color, :dialog_pointer_bg_color=
558-
def_single_delegators :core, :dialog_default_fg_color, :dialog_default_fg_color=
559-
def_single_delegators :core, :dialog_pointer_fg_color, :dialog_pointer_fg_color=
564+
def_single_delegators :core, *DIALOG_COLOR_APIS
560565

561566
def_single_delegators :core, :readmultiline
562567
def_instance_delegators self, :readmultiline
@@ -579,10 +584,10 @@ def self.core
579584
core.filename_quote_characters = ""
580585
core.special_prefixes = ""
581586
core.add_dialog_proc(:autocomplete, Reline::DEFAULT_DIALOG_PROC_AUTOCOMPLETE, Reline::DEFAULT_DIALOG_CONTEXT)
582-
core.dialog_default_bg_color = 46 # Cyan
583-
core.dialog_default_fg_color = 37 # White
584-
core.dialog_pointer_bg_color = 45 # Magenta
585-
core.dialog_pointer_fg_color = 37 # White
587+
core.dialog_default_bg_color = :cyan
588+
core.dialog_default_fg_color = :white
589+
core.dialog_pointer_bg_color = :magenta
590+
core.dialog_pointer_fg_color = :white
586591
}
587592
end
588593

lib/reline/config.rb

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,11 @@ class InvalidInputrc < RuntimeError
4545
attr_accessor v
4646
end
4747

48-
attr_accessor(
49-
:autocompletion,
50-
:dialog_default_bg_color,
51-
:dialog_default_fg_color,
52-
:dialog_pointer_bg_color,
53-
:dialog_pointer_fg_color,
54-
)
48+
attr_accessor :autocompletion
49+
attr_reader :dialog_default_bg_color_sequence,
50+
:dialog_default_fg_color_sequence,
51+
:dialog_pointer_bg_color_sequence,
52+
:dialog_pointer_fg_color_sequence
5553

5654
def initialize
5755
@additional_key_bindings = {} # from inputrc
@@ -77,10 +75,10 @@ def initialize
7775
@test_mode = false
7876
@autocompletion = false
7977
@convert_meta = true if seven_bit_encoding?(Reline::IOGate.encoding)
80-
@dialog_default_bg_color = nil
81-
@dialog_pointer_bg_color = nil
82-
@dialog_default_fg_color = nil
83-
@dialog_pointer_fg_color = nil
78+
@dialog_default_bg_color_sequence = nil
79+
@dialog_pointer_bg_color_sequence = nil
80+
@dialog_default_fg_color_sequence = nil
81+
@dialog_pointer_fg_color_sequence = nil
8482
end
8583

8684
def reset
@@ -106,6 +104,65 @@ def editing_mode_is?(*val)
106104
(val.respond_to?(:any?) ? val : [val]).any?(@editing_mode_label)
107105
end
108106

107+
def dialog_default_bg_color=(color)
108+
@dialog_default_bg_color_sequence = dialog_color_to_code(:bg, color)
109+
end
110+
111+
def dialog_default_fg_color=(color)
112+
@dialog_default_fg_color_sequence = dialog_color_to_code(:fg, color)
113+
end
114+
115+
def dialog_pointer_bg_color=(color)
116+
@dialog_pointer_bg_color_sequence = dialog_color_to_code(:bg, color)
117+
end
118+
119+
def dialog_pointer_fg_color=(color)
120+
@dialog_pointer_fg_color_sequence = dialog_color_to_code(:fg, color)
121+
end
122+
123+
def dialog_default_bg_color
124+
dialog_code_to_color(:bg, @dialog_default_bg_color_sequence)
125+
end
126+
127+
def dialog_default_fg_color
128+
dialog_code_to_color(:fg, @dialog_default_fg_color_sequence)
129+
end
130+
131+
def dialog_pointer_bg_color
132+
dialog_code_to_color(:bg, @dialog_pointer_bg_color_sequence)
133+
end
134+
135+
def dialog_pointer_fg_color
136+
dialog_code_to_color(:fg, @dialog_pointer_fg_color_sequence)
137+
end
138+
139+
COLORS = [
140+
:black,
141+
:red,
142+
:green,
143+
:yellow,
144+
:blue,
145+
:magenta,
146+
:cyan,
147+
:white
148+
].freeze
149+
150+
private def dialog_color_to_code(type, color)
151+
base = type == :bg ? 40 : 30
152+
c = COLORS.index(color.to_sym)
153+
154+
if c
155+
base + c
156+
else
157+
raise ArgumentError.new("Unknown color: #{color}.\nAvailable colors: #{COLORS.join(", ")}")
158+
end
159+
end
160+
161+
private def dialog_code_to_color(type, code)
162+
base = type == :bg ? 40 : 30
163+
COLORS[code - base]
164+
end
165+
109166
def keymap
110167
@key_actors[@keymap_label]
111168
end
@@ -339,13 +396,13 @@ def bind_variable(name, value)
339396
when 'emacs-mode-string'
340397
@emacs_mode_string = retrieve_string(value)
341398
when 'dialog-default-bg-color'
342-
@dialog_default_bg_color = value.to_i
343-
when 'dialog-pointer-bg-color'
344-
@dialog_pointer_bg_color = value.to_i
399+
self.dialog_default_bg_color = value
345400
when 'dialog-default-fg-color'
346-
@dialog_default_fg_color = value.to_i
401+
self.dialog_default_fg_color = value
402+
when 'dialog-pointer-bg-color'
403+
self.dialog_pointer_bg_color = value
347404
when 'dialog-pointer-fg-color'
348-
@dialog_pointer_fg_color = value.to_i
405+
self.dialog_pointer_fg_color = value
349406
when *VARIABLE_NAMES then
350407
variable_name = :"@#{name.tr(?-, ?_)}"
351408
instance_variable_set(variable_name, value.nil? || value == '1' || value == 'on')

test/reline/test_config.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -411,16 +411,16 @@ def test_relative_xdg_config_home
411411

412412
def test_dialog_configurations
413413
@config.read_lines(<<~LINES.lines)
414-
set dialog-default-bg-color 1
415-
set dialog-pointer-bg-color 2
416-
set dialog-default-fg-color 3
417-
set dialog-pointer-fg-color 4
414+
set dialog-default-bg-color white
415+
set dialog-pointer-bg-color black
416+
set dialog-default-fg-color cyan
417+
set dialog-pointer-fg-color magenta
418418
LINES
419419

420-
assert_equal 1, @config.dialog_default_bg_color
421-
assert_equal 2, @config.dialog_pointer_bg_color
422-
assert_equal 3, @config.dialog_default_fg_color
423-
assert_equal 4, @config.dialog_pointer_fg_color
420+
assert_equal :white, @config.dialog_default_bg_color
421+
assert_equal :black, @config.dialog_pointer_bg_color
422+
assert_equal :cyan, @config.dialog_default_fg_color
423+
assert_equal :magenta, @config.dialog_pointer_fg_color
424424
end
425425
end
426426

test/reline/test_reline.rb

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,31 @@ def test_completion_append_character
4848

4949
def test_dialog_color_configuration
5050
# defaults
51-
assert_equal(46, Reline.dialog_default_bg_color)
52-
assert_equal(37, Reline.dialog_default_fg_color)
53-
assert_equal(45, Reline.dialog_pointer_bg_color)
54-
assert_equal(37, Reline.dialog_pointer_fg_color)
55-
56-
Reline.dialog_default_bg_color = 40
57-
assert_equal(40, Reline.dialog_default_bg_color)
58-
Reline.dialog_default_fg_color = 47
59-
assert_equal(47, Reline.dialog_default_fg_color)
60-
Reline.dialog_pointer_bg_color = 37
61-
assert_equal(37, Reline.dialog_pointer_bg_color)
62-
Reline.dialog_pointer_fg_color = 30
63-
assert_equal(30, Reline.dialog_pointer_fg_color)
51+
assert_equal(:cyan, Reline.dialog_default_bg_color)
52+
assert_equal(:white, Reline.dialog_default_fg_color)
53+
assert_equal(:magenta, Reline.dialog_pointer_bg_color)
54+
assert_equal(:white, Reline.dialog_pointer_fg_color)
55+
56+
Reline.dialog_default_bg_color = :black
57+
assert_equal(:black, Reline.dialog_default_bg_color)
58+
assert_equal(40, Reline.dialog_default_bg_color_sequence)
59+
60+
Reline.dialog_default_fg_color = :white
61+
assert_equal(:white, Reline.dialog_default_fg_color)
62+
assert_equal(37, Reline.dialog_default_fg_color_sequence)
63+
64+
Reline.dialog_pointer_bg_color = :white
65+
assert_equal(:white, Reline.dialog_pointer_bg_color)
66+
assert_equal(47, Reline.dialog_pointer_bg_color_sequence)
67+
68+
Reline.dialog_pointer_fg_color = :black
69+
assert_equal(:black, Reline.dialog_pointer_fg_color)
70+
assert_equal(30, Reline.dialog_pointer_fg_color_sequence)
71+
72+
# test value validation
73+
assert_raise(ArgumentError) do
74+
Reline.dialog_pointer_fg_color = :foo
75+
end
6476
end
6577

6678
def test_basic_word_break_characters

0 commit comments

Comments
 (0)