class Pry::Editor

Public Instance Methods

edit_tempfile_with_content(initial_content, line=1) click to toggle source
# File lib/pry/editor.rb, line 7
def edit_tempfile_with_content(initial_content, line=1)
  temp_file do |f|
    f.puts(initial_content)
    f.flush
    f.close(false)
    invoke_editor(f.path, line, true)
    File.read(f.path)
  end
end
invoke_editor(file, line, blocking=true) click to toggle source
# File lib/pry/editor.rb, line 17
def invoke_editor(file, line, blocking=true)
  raise CommandError, "Please set Pry.config.editor or export $VISUAL or $EDITOR" unless Pry.config.editor

  editor_invocation = build_editor_invocation_string(file, line, blocking)
  return nil unless editor_invocation

  if jruby?
    open_editor_on_jruby(editor_invocation)
  else
    open_editor(editor_invocation)
  end
end

Private Instance Methods

blocking_flag_for_editor(blocking) click to toggle source

Some editors that run outside the terminal allow you to control whether or not to block the process from which they were launched (in this case, Pry). For those editors, return the flag that produces the desired behavior.

# File lib/pry/editor.rb, line 74
def blocking_flag_for_editor(blocking)
  case editor_name
  when /^emacsclient/
    '--no-wait' unless blocking
  when /^[gm]vim/
    '--nofork' if blocking
  when /^jedit/
    '-wait' if blocking
  when /^mate/, /^subl/
    '-w' if blocking
  end
end
build_editor_invocation_string(file, line, blocking) click to toggle source

Generate the string that's used to start the editor. This includes all the flags we want as well as the file and line number we want to open at.

# File lib/pry/editor.rb, line 35
def build_editor_invocation_string(file, line, blocking)

  if Pry.config.editor.respond_to?(:call)
    args = [file, line, blocking][0...(Pry.config.editor.arity)]
    Pry.config.editor.call(*args)
  else
    sanitized_file = if windows?
                       file.gsub(/\//, '\')
                     else
                       Shellwords.escape(file)
                     end

    "#{Pry.config.editor} #{blocking_flag_for_editor(blocking)} #{start_line_syntax_for_editor(sanitized_file, line)}"
  end
end
editor_name() click to toggle source

Get the name of the binary that Pry.config.editor points to.

This is useful for deciding which flags we pass to the editor as we can just use the program's name and ignore any absolute paths.

@example

Pry.config.editor="/home/conrad/bin/textmate -w"
editor_name
# => textmate
# File lib/pry/editor.rb, line 123
def editor_name
  File.basename(Pry.config.editor).split(" ").first
end
open_editor(editor_invocation) click to toggle source

Start the editor running, using the calculated invocation string

# File lib/pry/editor.rb, line 52
def open_editor(editor_invocation)
  # Note we dont want to use Pry.config.system here as that
  # may be invoked non-interactively (i.e via Open4), whereas we want to
  # ensure the editor is always interactive
  system(editor_invocation) or raise CommandError, "`#{editor_invocation}` gave exit status: #{$?.exitstatus}"
end
open_editor_on_jruby(editor_invocation) click to toggle source

We need JRuby specific code here cos just shelling out using system() appears to be pretty broken :/

# File lib/pry/editor.rb, line 61
def open_editor_on_jruby(editor_invocation)
  begin
    require 'spoon'
    pid = Spoon.spawnp(*editor_invocation.split)
    Process.waitpid(pid)
  rescue FFI::NotFoundError
    system(editor_invocation)
  end
end
start_line_syntax_for_editor(file_name, line_number) click to toggle source

Return the syntax for a given editor for starting the editor and moving to a particular line within that file

# File lib/pry/editor.rb, line 89
def start_line_syntax_for_editor(file_name, line_number)
  # special case for 1st line
  return file_name if line_number <= 1

  case editor_name
  when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/
    "+#{line_number} #{file_name}"
  when /^mate/, /^geany/
    "-l #{line_number} #{file_name}"
  when /^subl/
    "#{file_name}:#{line_number}"
  when /^uedit32/
    "#{file_name}/#{line_number}"
  when /^jedit/
    "#{file_name} +line:#{line_number}"
  else
    if windows?
      "#{file_name}"
    else
      "+#{line_number} #{file_name}"
    end
  end
end