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.
  ]

  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
302
303
304
305
306
307
# 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?
        lvars = IRB.CurrentContext&.local_variables || []
        IRB::Color.colorize_code(output, complete: complete, local_variables: lvars)
      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]
    begin
      require 'rdoc'
      Reline.add_dialog_proc(:show_doc, SHOW_DOC_DIALOG, Reline::DEFAULT_DIALOG_CONTEXT)
    rescue LoadError
    end
  end
end

Instance Method Details

#auto_indent(&block) ⇒ Object



317
318
319
# File 'lib/irb/input-method.rb', line 317

def auto_indent(&block)
  @auto_indent_proc = block
end

#check_termination(&block) ⇒ Object



309
310
311
# File 'lib/irb/input-method.rb', line 309

def check_termination(&block)
  @check_termination_proc = block
end

#dynamic_prompt(&block) ⇒ Object



313
314
315
# File 'lib/irb/input-method.rb', line 313

def dynamic_prompt(&block)
  @prompt_proc = block
end

#encodingObject

The external encoding for standard input.



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

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)


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

def eof?
  @eof
end

#getsObject

Reads the next line from this input method.

See IO#gets for more information.



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

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



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

def inspect
  config = Reline::Config.new
  str = "RelineInputMethod 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.



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

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)


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

def readable_after_eof?
  true
end