Module: IRB::Color
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Defined in: | lib/irb/color.rb |
Constant Summary
-
ALL =
private
A constant of all-bit 1 to match any Ripper’s state in
#dispatch_seq
-1
-
BLUE =
# File 'lib/irb/color.rb', line 1534
-
BOLD =
# File 'lib/irb/color.rb', line 91
-
CLEAR =
# File 'lib/irb/color.rb', line 80
-
CYAN =
# File 'lib/irb/color.rb', line 1736
-
ERROR_TOKENS =
private
# File 'lib/irb/color.rb', line 75TOKEN_SEQ_EXPRS.keys.select { |k| k.to_s.end_with?('error') }
-
GREEN =
# File 'lib/irb/color.rb', line 1332
-
MAGENTA =
# File 'lib/irb/color.rb', line 1635
-
RED =
# File 'lib/irb/color.rb', line 1231
-
REVERSE =
# File 'lib/irb/color.rb', line 117
-
TOKEN_KEYWORDS =
private
# File 'lib/irb/color.rb', line 19{ on_kw: ['nil', 'self', 'true', 'false', '__FILE__', '__LINE__', '__ENCODING__'], on_const: ['ENV'], }
-
UNDERLINE =
# File 'lib/irb/color.rb', line 104
-
YELLOW =
# File 'lib/irb/color.rb', line 1433
Class Attribute Summary
- .colorable? ⇒ Boolean readonly
- .supported? ⇒ Boolean readonly private
Class Method Summary
- .clear
- .colorize(text, seq)
-
.colorize_code(code, complete: true, ignore_error: false)
If
complete
is false (code is incomplete), this does not warn compile_error. - .inspect_colorable?(obj, seen: {}.compare_by_identity) ⇒ Boolean
- .dispatch_seq(token, expr, str, in_symbol:) private
- .scan(code, allow_last_error:) private
- .without_circular_ref(obj, seen:, &block) private
Class Attribute Details
.colorable? ⇒ Boolean
(readonly)
[ GitHub ]
# File 'lib/irb/color.rb', line 79
def colorable? $stdout.tty? && supported? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb')) end
.supported? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'lib/irb/color.rb', line 164
def supported? return @supported if defined?(@supported) @supported = Ripper::Lexer::Elem.method_defined?(:state) end
Class Method Details
.clear
[ GitHub ]# File 'lib/irb/color.rb', line 104
def clear return '' unless colorable? "\e[#{CLEAR}m" end
.colorize(text, seq)
[ GitHub ]# File 'lib/irb/color.rb', line 109
def colorize(text, seq) return text unless colorable? seq = seq.map { |s| "\e[#{const_get(s)}m" }.join('') "#{seq}#{text}#{clear}" end
.colorize_code(code, complete: true, ignore_error: false)
If complete
is false (code is incomplete), this does not warn compile_error. This option is needed to avoid warning a user when the compile_error is happening because the input is not wrong but just incomplete.
# File 'lib/irb/color.rb', line 118
def colorize_code(code, complete: true, ignore_error: false) return code unless colorable? symbol_state = SymbolState.new colored = +'' length = 0 end_seen = false scan(code, allow_last_error: !complete) do |token, str, expr| # IRB::ColorPrinter skips colorizing fragments with any invalid token if ignore_error && ERROR_TOKENS.include?(token) return Reline::Unicode.escape_for_print(code) end in_symbol = symbol_state.scan_token(token) str.each_line do |line| line = Reline::Unicode.escape_for_print(line) if seq = dispatch_seq(token, expr, line, in_symbol: in_symbol) colored << seq.map { |s| "\e[#{s}m" }.join('') colored << line.sub(/\Z/, clear) else colored << line end end length += str.bytesize end_seen = true if token == :on___end__ end # give up colorizing incomplete Ripper tokens unless end_seen or length == code.bytesize return Reline::Unicode.escape_for_print(code) end colored end
.dispatch_seq(token, expr, str, in_symbol:) (private)
[ GitHub ]# File 'lib/irb/color.rb', line 202
def dispatch_seq(token, expr, str, in_symbol:) if ERROR_TOKENS.include?(token) TOKEN_SEQ_EXPRS[token][0] elsif in_symbol [YELLOW] elsif TOKEN_KEYWORDS.fetch(token, []).include?(str) [CYAN, BOLD] elsif (seq, exprs = TOKEN_SEQ_EXPRS[token]; (expr & (exprs || 0)) != 0) seq else nil end end
.inspect_colorable?(obj, seen: {}.compare_by_identity) ⇒ Boolean
# File 'lib/irb/color.rb', line 83
def inspect_colorable?(obj, seen: {}.compare_by_identity) case obj when String, Symbol, Regexp, Integer, Float, FalseClass, TrueClass, NilClass true when Hash without_circular_ref(obj, seen: seen) do obj.all? { |k, v| inspect_colorable?(k, seen: seen) && inspect_colorable?(v, seen: seen) } end when Array without_circular_ref(obj, seen: seen) do obj.all? { |o| inspect_colorable?(o, seen: seen) } end when Range inspect_colorable?(obj.begin, seen: seen) && inspect_colorable?(obj.end, seen: seen) when Module !obj.name.nil? else false end end
.scan(code, allow_last_error:) (private)
[ GitHub ]# File 'lib/irb/color.rb', line 169
def scan(code, allow_last_error:) pos = [1, 0] verbose, $VERBOSE = $VERBOSE, nil RubyLex.compile_with_errors_suppressed(code) do |inner_code, line_no| lexer = Ripper::Lexer.new(inner_code, '(ripper)', line_no) if lexer.respond_to?(:scan) # Ruby 2.7+ lexer.scan.each do |elem| str = elem.tok next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem. next if ([elem.pos[0], elem.pos[1] + str.bytesize] <=> pos) <= 0 str.each_line do |line| if line.end_with?("\n") pos[0] += 1 pos[1] = 0 else pos[1] += line.bytesize end end yield(elem.event, str, elem.state) end else lexer.parse.each do |elem| yield(elem.event, elem.tok, elem.state) end end end ensure $VERBOSE = verbose end
.without_circular_ref(obj, seen:, &block) (private)
[ GitHub ]# File 'lib/irb/color.rb', line 156
def without_circular_ref(obj, seen:, &block) return false if seen.key?(obj) seen[obj] = true block.call ensure seen.delete(obj) end