Module: FancyIrb

Extended by:
SizeDetector
Defined in:
lib/fancy_irb.rb,
lib/fancy_irb/irb_ext.rb,
lib/fancy_irb/version.rb,
lib/fancy_irb/size_detector.rb,
lib/fancy_irb/terminal_info.rb,
lib/fancy_irb/error_capturer.rb,
lib/fancy_irb/implementation.rb

Defined Under Namespace

Modules: ContextExt, IrbExtCommon, IrbExtPrompt, IrbExtPromptLegacy, SizeDetector, TerminalInfo Classes: ErrorCapturer

Constant Summary collapse

DEFAULT_OPTIONS =
{
  :rocket_mode     => true,       # activate or deactivate #=> rocket output
  :rocket_prompt   => '#=> ',     # prompt to use for the rocket
  :result_prompt   => '=> ',      # prompt to use for normal output
  :unicode_display_width => true, # set to false if you don't want to check for proper
                                  # string width for better performance
  :colorize => {                  # colors hash. Set to nil to deactivate colors
    :rocket_prompt => [:blue],
    :result_prompt => [:blue],
    :input_prompt  => nil,
    :irb_errors    => [:red, :clean],
    :stderr        => [:red, :bright],
    :stdout        => nil,
    :input         => nil,
   },
}
SKIP_ROCKET_METHODS =
%w[
  system
  spawn
].map(&:to_sym)
TRACK_HEIGHT_INPUT_METHODS =

TODO: each_byte, each_char, each_codepoint, each, etc

%w[
  binread
  read
  gets
  getc
  getbyte
  readbyte
  readchar
  readline
  readlines
  readpartial
  sysread
].map(&:to_sym)
VERSION =
'2.1.2'

Class Attribute Summary collapse

Class Method Summary collapse

Methods included from SizeDetector

height_of, width_of

Class Attribute Details

.error_capturerObject (readonly)

Returns the value of attribute error_capturer.



7
8
9
# File 'lib/fancy_irb/implementation.rb', line 7

def error_capturer
  @error_capturer
end

.skip_next_rocketObject

Returns the value of attribute skip_next_rocket.



8
9
10
# File 'lib/fancy_irb/implementation.rb', line 8

def skip_next_rocket
  @skip_next_rocket
end

Class Method Details

.append_input_color(string) ⇒ Object

Note: No reset, relies on next one



74
75
76
77
78
79
80
# File 'lib/fancy_irb/implementation.rb', line 74

def append_input_color(string)
  if input_color = @options[:colorize][:input]
    string + Paint.color(*Array(input_color))
  else
    string
  end
end

.apply_user_options(user_options) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/fancy_irb/implementation.rb', line 33

def apply_user_options(user_options)
  DEFAULT_OPTIONS.each{ |key, value|
    # (ugly) 1 level deep merge, maybe refactor
    if key == :colorize
      if user_options.has_key?(:colorize) && user_options[:colorize].nil?
        @options[:colorize] = {}
      else
        value.each{ |key2, _|
          if user_options[key] && user_options[key].has_key?(key2)
            @options[:colorize][key2] = user_options[key][key2]
          end
        }
      end
    else
      @options[key] =
          user_options.has_key?(key) ? user_options[key] : DEFAULT_OPTIONS[key]
    end
  }
end

.colorize(string, colorize_key) ⇒ Object



69
70
71
# File 'lib/fancy_irb/implementation.rb', line 69

def colorize(string, colorize_key)
  Paint::NOTHING + Paint[string, *Array(@options[:colorize][colorize_key])]
end

.extend!Object

hook into IRB



19
20
21
22
23
# File 'lib/fancy_irb/implementation.rb', line 19

def extend!
  require_relative 'irb_ext'
  require_relative 'core_ext'
  require_relative 'clean_up'
end

.get_offset_from_relineObject



105
106
107
108
109
# File 'lib/fancy_irb/implementation.rb', line 105

def get_offset_from_reline
  last_buffer = (Reline::HISTORY || [])[-1] || ""
  last_line = last_buffer.split("\n").last
  1 + @current_indent + width_of(last_line)
end

.handle_prompt(prompt, scanner_indent) ⇒ Object

, track_indent)



58
59
60
61
62
63
# File 'lib/fancy_irb/implementation.rb', line 58

def handle_prompt(prompt, scanner_indent)#, track_indent)
  # @tracked_indent = 2 if track_indent
  @current_indent = width_of(prompt) + scanner_indent# + @tracked_indent

  append_input_color colorize(prompt, :input_prompt)
end

.output_value(context, _scanner) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/fancy_irb/implementation.rb', line 82

def output_value(context, _scanner)
  output = context.inspect_last_value
  if @options[:rocket_mode] && !@skip_next_rocket && !output.include?("\n")
    offset = get_offset_from_reline
    cols_to_show  = offset + width_of(@options[:rocket_prompt] + output)
    lines_to_show = 1 + @tracked_height

    if TerminalInfo.lines > lines_to_show && TerminalInfo.cols > cols_to_show
      print \
        Paint::NOTHING +
        TerminalInfo::TPUT[:sc] +                    # save current cursor position
        TerminalInfo::TPUT[:cuu1] * lines_to_show +  # move cursor upwards    to the original input line
        TerminalInfo::TPUT[:cuf1] * offset +         # move cursor rightwards to the original input offset
        colorize(@options[:rocket_prompt], :rocket_prompt) +   # draw rocket prompt
        output +                                               # draw output
        TerminalInfo::TPUT[:rc]                      # return to normal cursor position
      return
    end
  end
  @skip_next_rocket = false
  puts colorize(@options[:result_prompt], :result_prompt) + output
end

.patch_stream(object, stream_name) ⇒ Object



133
134
135
136
137
138
# File 'lib/fancy_irb/implementation.rb', line 133

def patch_stream(object, stream_name)
  object.define_singleton_method :write do |data|
    FancyIrb.track_height data
    super FancyIrb.colorize(data, stream_name)
  end
end

.present_and_clear_captured_error!Object



144
145
146
147
148
149
150
151
152
153
# File 'lib/fancy_irb/implementation.rb', line 144

def present_and_clear_captured_error!
  if @error_capturer
    @error_capturer.restore_original_stdout
    $stderr.puts colorize(
      @error_capturer.error_string.chomp,
      :irb_errors,
    )
    @error_capturer = nil
  end
end

.register_error_capturer!Object



140
141
142
# File 'lib/fancy_irb/implementation.rb', line 140

def register_error_capturer!
  @error_capturer = ErrorCapturer.new
end

.register_height_trackers(object, methods_) ⇒ Object

TODO testing and improving, e.g. getc does not contain ā€œnā€



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/fancy_irb/implementation.rb', line 112

def register_height_trackers(object, methods_)
  methods_.each{ |method_|
    if object.respond_to?(method_)
      object.send :define_singleton_method, method_ do |*args|
        res = super(*args)
        FancyIrb.track_height(res)
        res
      end
    end
  }
end

.register_skipped_rockets(object_class, methods_) ⇒ Object



124
125
126
127
128
129
130
131
# File 'lib/fancy_irb/implementation.rb', line 124

def register_skipped_rockets(object_class, methods_)
  methods_.each{ |method_|
    object_class.send :define_method, method_ do |*args|
      FancyIrb.skip_next_rocket = true
      super(*args)
    end
  }
end

.reset_line!Object



53
54
55
56
# File 'lib/fancy_irb/implementation.rb', line 53

def reset_line!
  @tracked_height = 0
  @tracked_indent = 0
end

.set_defaultsObject



25
26
27
28
29
30
31
# File 'lib/fancy_irb/implementation.rb', line 25

def set_defaults
  @skip_next_rocket = false
  @current_indent = Float::INFINITY

  @options = DEFAULT_OPTIONS.dup
  @options[:colorize] = @options[:colorize].dup if @options[:colorize]
end

.start(user_options = {}) ⇒ Object



10
11
12
13
14
15
16
# File 'lib/fancy_irb/implementation.rb', line 10

def start(user_options = {})
  set_defaults
  apply_user_options(user_options)
  reset_line!
  extend!
  true
end

.track_height(data) ⇒ Object



65
66
67
# File 'lib/fancy_irb/implementation.rb', line 65

def track_height(data)
  @tracked_height += height_of(data, TerminalInfo.cols)
end