Class: IRB::RelineInputMethod

Inherits:
InputMethod show all
Includes:
Reline
Defined in:
lib/irb/input-method.rb

Direct Known Subclasses

ReidlineInputMethod

Constant Summary collapse

SHOW_DOC_DIALOG =
->() {
  dialog.trap_key = nil
  alt_d = [
    [Reline::Key.new(nil, 0xE4, true)], # Normal Alt+d.
    [27, 100], # Normal Alt+d when convert-meta isn't used.
    [195, 164], # The "ä" that appears when Alt+d is pressed on xterm.
    [226, 136, 130] # The "∂" that appears when Alt+d in pressed on iTerm2.
  ]
  begin
    require 'rdoc'
  rescue LoadError
    return nil
  end

  if just_cursor_moving and completion_journey_data.nil?
    return nil
  end
  cursor_pos_to_render, result, pointer, autocomplete_dialog = context.pop(4)
  return nil if result.nil? or pointer.nil? or pointer < 0
  name = result[pointer]
  name = IRB::InputCompletor.retrieve_completion_data(name, doc_namespace: true)

  options = {}
  options[:extra_doc_dirs] = IRB.conf[:EXTRA_DOC_DIRS] unless IRB.conf[:EXTRA_DOC_DIRS].empty?
  driver = RDoc::RI::Driver.new(options)

  if key.match?(dialog.name)
    begin
      driver.display_names([name])
    rescue RDoc::RI::Driver::NotFoundError
    end
  end

  begin
    name = driver.expand_name(name)
  rescue RDoc::RI::Driver::NotFoundError
    return nil
  rescue
    return nil # unknown error
  end
  doc = nil
  used_for_class = false
  if not name =~ /#|\./
    found, klasses, includes, extends = driver.classes_and_includes_and_extends_for(name)
    if not found.empty?
      doc = driver.class_document(name, found, klasses, includes, extends)
      used_for_class = true
    end
  end
  unless used_for_class
    doc = RDoc::Markup::Document.new
    begin
      driver.add_method(doc, name)
    rescue RDoc::RI::Driver::NotFoundError
      doc = nil
    rescue
      return nil # unknown error
    end
  end
  return nil if doc.nil?
  width = 40

  right_x = cursor_pos_to_render.x + autocomplete_dialog.width
  if right_x + width > screen_width
    right_width = screen_width - (right_x + 1)
    left_x = autocomplete_dialog.column - width
    left_x = 0 if left_x < 0
    left_width = width > autocomplete_dialog.column ? autocomplete_dialog.column : width
    if right_width.positive? and left_width.positive?
      if right_width >= left_width
        width = right_width
        x = right_x
      else
        width = left_width
        x = left_x
      end
    elsif right_width.positive? and left_width <= 0
      width = right_width
      x = right_x
    elsif right_width <= 0 and left_width.positive?
      width = left_width
      x = left_x
    else # Both are negative width.
      return nil
    end
  else
    x = right_x
  end
  formatter = RDoc::Markup::ToAnsi.new
  formatter.width = width
  dialog.trap_key = alt_d
  message = 'Press Alt+d to read the full document'
  contents = [message] + doc.accept(formatter).split("\n")

  y = cursor_pos_to_render.y
  DialogRenderInfo.new(pos: Reline::CursorPos.new(x, y), contents: contents, width: width, bg_color: '49')
}

Instance Attribute Summary

Attributes inherited from InputMethod

#file_name, #prompt

Instance Method Summary collapse

Methods inherited from InputMethod

#winsize

Constructor Details

#initializeRelineInputMethod

Creates a new input method object using Reline



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/irb/input-method.rb', line 268

def initialize
  IRB.__send__(:set_encoding, Reline.encoding_system_needs.name, override: false)
  super

  @line_no = 0
  @line = []
  @eof = false

  @stdin = ::IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
  @stdout = ::IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")

  if Reline.respond_to?("basic_word_break_characters=")
    Reline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
  end
  Reline.completion_append_character = nil
  Reline.completer_quote_characters = ''
  Reline.completion_proc = IRB::InputCompletor::CompletionProc
  Reline.output_modifier_proc =
    if IRB.conf[:USE_COLORIZE]
      proc do |output, complete: |
        next unless IRB::Color.colorable?
        IRB::Color.colorize_code(output, complete: complete)
      end
    else
      proc do |output|
        Reline::Unicode.escape_for_print(output)
      end
    end
  Reline.dig_perfect_match_proc = IRB::InputCompletor::PerfectMatchedProc
  Reline.autocompletion = IRB.conf[:USE_AUTOCOMPLETE]
  if IRB.conf[:USE_AUTOCOMPLETE]
    Reline.add_dialog_proc(:show_doc, SHOW_DOC_DIALOG, Reline::DEFAULT_DIALOG_CONTEXT)
  end
end

Instance Method Details

#auto_indent(&block) ⇒ Object



311
312
313
# File 'lib/irb/input-method.rb', line 311

def auto_indent(&block)
  @auto_indent_proc = block
end

#check_termination(&block) ⇒ Object



303
304
305
# File 'lib/irb/input-method.rb', line 303

def check_termination(&block)
  @check_termination_proc = block
end

#dynamic_prompt(&block) ⇒ Object



307
308
309
# File 'lib/irb/input-method.rb', line 307

def dynamic_prompt(&block)
  @prompt_proc = block
end

#encodingObject

The external encoding for standard input.



456
457
458
# File 'lib/irb/input-method.rb', line 456

def encoding
  @stdin.external_encoding
end

#eof?Boolean

Whether the end of this input method has been reached, returns true if there is no more data to read.

See IO#eof? for more information.

Returns:

  • (Boolean)


434
435
436
# File 'lib/irb/input-method.rb', line 434

def eof?
  @eof
end

#getsObject

Reads the next line from this input method.

See IO#gets for more information.



416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'lib/irb/input-method.rb', line 416

def gets
  Reline.input = @stdin
  Reline.output = @stdout
  Reline.prompt_proc = @prompt_proc
  Reline.auto_indent_proc = @auto_indent_proc if @auto_indent_proc
  if l = readmultiline(@prompt, false, &@check_termination_proc)
    HISTORY.push(l) if !l.empty?
    @line[@line_no += 1] = l + "\n"
  else
    @eof = true
    l
  end
end

#inspectObject

For debug message



461
462
463
464
465
466
467
468
469
470
471
# File 'lib/irb/input-method.rb', line 461

def inspect
  config = Reline::Config.new
  str = "ReidlineInputMethod with Reline #{Reline::VERSION}"
  if config.respond_to?(:inputrc_path)
    inputrc_path = File.expand_path(config.inputrc_path)
  else
    inputrc_path = File.expand_path(ENV['INPUTRC'] || '~/.inputrc')
  end
  str += " and #{inputrc_path}" if File.exist?(inputrc_path)
  str
end

#line(line_no) ⇒ Object

Returns the current line number for #io.

#line counts the number of times #gets is called.

See IO#lineno for more information.



451
452
453
# File 'lib/irb/input-method.rb', line 451

def line(line_no)
  @line[line_no]
end

#readable_after_eof?Boolean

Whether this input method is still readable when there is no more data to read.

See IO#eof for more information.

Returns:

  • (Boolean)


442
443
444
# File 'lib/irb/input-method.rb', line 442

def readable_after_eof?
  true
end