Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a new class Reline::Face to configure character attributes #552

Merged
merged 34 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1224863
Reine::Face
hasumikin Jun 12, 2023
17114b9
fix test_yamatanooroti
hasumikin Jun 13, 2023
e033f88
Define singleton methods to make accessors to attributes of a face
hasumikin Jun 15, 2023
629db24
s/display/foreground/
hasumikin Oct 10, 2023
a993e52
s/default/default_style/ && s/normal_line/default/ && s/enhanced_line…
hasumikin Oct 10, 2023
cab307f
fix typo
hasumikin Oct 10, 2023
e4d61dd
FaceConfig.new now takes keyword arguments
hasumikin Oct 10, 2023
0e7acfb
Update lib/reline/face.rb
hasumikin Oct 14, 2023
b442c57
Update test/reline/test_face.rb
hasumikin Oct 14, 2023
389ff41
Fix to correspond to frozen_string_literal
hasumikin Oct 14, 2023
c3f92f1
Face::FaceConfig -> Face::Config
hasumikin Oct 14, 2023
d652fc0
Merge branch 'master' into reline_face
hasumikin Oct 14, 2023
1550519
ref https://github.com/ruby/reline/pull/552#pullrequestreview-1677282576
hasumikin Oct 14, 2023
6e4b4e9
delete unused ivar
hasumikin Oct 14, 2023
e8eb85b
ref https://github.com/ruby/reline/pull/552#discussion_r1358783723
hasumikin Oct 14, 2023
7ea200e
insert "\e[0m" into all SGR
hasumikin Oct 16, 2023
26cb115
tiny fix
hasumikin Oct 23, 2023
9286c59
ESSENTIAL_DEFINE_NAMES
hasumikin Oct 23, 2023
f001348
Change to Hash-accessor style
hasumikin Oct 23, 2023
28197be
Cache array method call in local variable
hasumikin Oct 24, 2023
efb75ed
Tests for Face configuration variations
hasumikin Nov 2, 2023
e7a6d56
resolve https://github.com/ruby/reline/pull/552#pullrequestreview-171…
hasumikin Nov 3, 2023
5a53084
amend to
hasumikin Nov 3, 2023
67a8497
check invalid SGR parameter in :style
hasumikin Nov 3, 2023
c02205c
The order of define values should be preserved
hasumikin Nov 3, 2023
728ca2d
Update test/reline/test_face.rb
hasumikin Nov 4, 2023
cde902e
Update test/reline/test_face.rb
hasumikin Nov 4, 2023
23d2360
Add methods: load_initial_config and reset_to_initial_config. And tea…
hasumikin Nov 5, 2023
2eee3b0
omission in amending "style: :default" to "style: :reset"
hasumikin Nov 5, 2023
76dd7b0
refs https://github.com/ruby/reline/issues/598
hasumikin Nov 6, 2023
1ce4818
Fix link
hasumikin Nov 6, 2023
7c5133c
amend method name
hasumikin Nov 6, 2023
a33109f
Merge branch 'master' into reline_face
hasumikin Nov 6, 2023
544f3d1
Update lib/reline/face.rb
hasumikin Nov 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ end
gem 'bundler'
gem 'rake'
gem 'test-unit'
gem 'test-unit-rr'
24 changes: 16 additions & 8 deletions lib/reline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require 'reline/line_editor'
require 'reline/history'
require 'reline/terminfo'
require 'reline/face'
require 'rbconfig'

module Reline
Expand Down Expand Up @@ -36,10 +37,8 @@ def match?(other)
DialogRenderInfo = Struct.new(
:pos,
:contents,
:bg_color,
:pointer_bg_color,
:fg_color,
:pointer_fg_color,
:face,
:bg_color, # For the time being, this line should stay here for the compatibility with IRB.
:width,
:height,
:scrollbar,
Expand Down Expand Up @@ -260,10 +259,7 @@ def get_screen_size
contents: result,
scrollbar: true,
height: [15, preferred_dialog_height].min,
bg_color: 46,
pointer_bg_color: 45,
fg_color: 37,
pointer_fg_color: 37
face: :completion_dialog
)
}
Reline::DEFAULT_DIALOG_CONTEXT = Array.new
Expand Down Expand Up @@ -606,4 +602,16 @@ def self.update_iogate
io
end

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

Reline::Face.config(:completion_dialog) do |face|
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)
141 changes: 141 additions & 0 deletions lib/reline/face.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# frozen_string_literal: true

class Reline::Face
hasumikin marked this conversation as resolved.
Show resolved Hide resolved
SGR_PARAMETERS = {
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: {
reset: 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 Config
ESSENTIAL_DEFINE_NAMES = %i(default enhanced scrollbar).freeze
RESET_SGR = "\e[0m".freeze

def initialize(name, &block)
@definition = {}
block.call(self)
ESSENTIAL_DEFINE_NAMES.each do |name|
@definition[name] ||= { style: :default, escape_sequence: RESET_SGR }
end
end

attr_reader :definition

def define(name, **values)
values[:escape_sequence] = format_to_sgr(values.to_a).freeze
@definition[name] = values
end

def [](name)
@definition.dig(name, :escape_sequence) or raise ArgumentError, "unknown face: #{name}"
end

private

def sgr_rgb(key, value)
return nil unless rgb_expression?(value)
case key
when :foreground
"38;2;"
hasumikin marked this conversation as resolved.
Show resolved Hide resolved
when :background
"48;2;"
end + value[1, 6].scan(/../).map(&:hex).join(";")
end

def format_to_sgr(ordered_values)
sgr = "\e[" + ordered_values.map do |key_value|
key, value = 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 do |style_name|
SGR_PARAMETERS[:style][style_name]
end.then do |sgr_parameters|
sgr_parameters.include?(nil) ? nil : sgr_parameters
end
end.then do |rendition_expression|
unless rendition_expression
raise ArgumentError, "invalid SGR parameter: #{value.inspect}"
end
rendition_expression
end
end.join(';') + "m"
sgr == RESET_SGR ? RESET_SGR : RESET_SGR + sgr
end

def rgb_expression?(color)
color.respond_to?(:match?) and color.match?(/\A#[0-9a-fA-F]{6}\z/)
end
end

private_constant :SGR_PARAMETERS, :Config

def self.[](name)
@configs[name]
end

def self.config(name, &block)
@configs ||= {}
@configs[name] = Config.new(name, &block)
end

def self.configs
@configs.transform_values(&:definition)
end

end

23 changes: 10 additions & 13 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -831,27 +831,24 @@ def add_dialog_proc(name, p, context = nil)
dialog.column = 0
dialog.width = @screen_size.last
end
face = Reline::Face[dialog_render_info.face || :default]
scrollbar_sgr = face[:scrollbar]
default_sgr = face[:default]
enhanced_sgr = face[:enhanced]
dialog.contents = contents.map.with_index do |item, i|
if i == pointer
fg_color = dialog_render_info.pointer_fg_color
bg_color = dialog_render_info.pointer_bg_color
else
fg_color = dialog_render_info.fg_color
bg_color = dialog_render_info.bg_color
end
line_sgr = i == pointer ? enhanced_sgr : default_sgr
str_width = dialog.width - (scrollbar_pos.nil? ? 0 : @block_elem_width)
str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, str_width), str_width)
colored_content = "\e[#{bg_color}m\e[#{fg_color}m#{str}"
colored_content = "#{line_sgr}#{str}"
if scrollbar_pos
color_seq = "\e[37m"
if scrollbar_pos <= (i * 2) and (i * 2 + 1) < (scrollbar_pos + bar_height)
colored_content + color_seq + @full_block
colored_content + scrollbar_sgr + @full_block
elsif scrollbar_pos <= (i * 2) and (i * 2) < (scrollbar_pos + bar_height)
colored_content + color_seq + @upper_half_block
colored_content + scrollbar_sgr + @upper_half_block
elsif scrollbar_pos <= (i * 2 + 1) and (i * 2) < (scrollbar_pos + bar_height)
colored_content + color_seq + @lower_half_block
colored_content + scrollbar_sgr + @lower_half_block
else
colored_content + color_seq + ' ' * @block_elem_width
colored_content + scrollbar_sgr + ' ' * @block_elem_width
end
else
colored_content
Expand Down
1 change: 1 addition & 0 deletions test/reline/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

require 'reline'
require 'test/unit'
require 'test/unit/rr'

begin
require 'rbconfig'
Expand Down
Loading