class Pry::Editor

def self.default

def self.default
  if (visual = Pry::Env['VISUAL'])
    return visual
  end
  if (editor = Pry::Env['EDITOR'])
    return editor
  end
  return 'notepad' if Helpers::Platform.windows?
  %w[editor nano vi].find do |editor_exe|
    Kernel.system("which #{editor_exe} > /dev/null 2>&1")
  end
end

def blocking_flag_for_editor(blocking)

For those editors, return the flag that produces the desired behavior.
not to block the process from which they were launched (in this case, Pry).
Some editors that run outside the terminal allow you to control whether or
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/, /^redcar/, /^code/
    '-w' if blocking
  end
end

def build_editor_invocation_string(file, line, blocking)

want to open at.
all the flags we want as well as the file and line number we
Generate the string that's used to start the editor. This includes
def build_editor_invocation_string(file, line, blocking)
  if pry_instance.config.editor.respond_to?(:call)
    args = [file, line, blocking][0...(pry_instance.config.editor.arity)]
    pry_instance.config.editor.call(*args)
  else
    sanitized_file = Helpers::Platform.windows? ? file : Shellwords.escape(file)
    editor = pry_instance.config.editor
    flag = blocking_flag_for_editor(blocking)
    start_line = start_line_syntax_for_editor(sanitized_file, line)
    "#{editor} #{flag} #{start_line}"
  end
end

def edit_tempfile_with_content(initial_content, line = 1)

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

def editor_name


# => textmate
editor_name
Pry.config.editor="/home/conrad/bin/textmate -w"
@example

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

Get the name of the binary that Pry.config.editor points to.
def editor_name
  File.basename(pry_instance.config.editor).split(" ").first
end

def initialize(pry_instance)

def initialize(pry_instance)
  @pry_instance = pry_instance
end

def invoke_editor(file, line, blocking = true)

def invoke_editor(file, line, blocking = true)
  unless pry_instance.config.editor
    raise CommandError,
          "Please set Pry.config.editor or export $VISUAL or $EDITOR"
  end
  editor_invocation = build_editor_invocation_string(file, line, blocking)
  return nil unless editor_invocation
  if Helpers::Platform.jruby?
    open_editor_on_jruby(editor_invocation)
  else
    open_editor(editor_invocation)
  end
end

def open_editor(editor_invocation)

Start the editor running, using the calculated invocation string
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(*Shellwords.split(editor_invocation)) ||
    raise(
      CommandError,
      "`#{editor_invocation}` gave exit status: #{$CHILD_STATUS.exitstatus}"
    )
end

def open_editor_on_jruby(editor_invocation)

system() appears to be pretty broken :/
We need JRuby specific code here cos just shelling out using
def open_editor_on_jruby(editor_invocation)
  require 'spoon'
  pid = Spoon.spawnp(*Shellwords.split(editor_invocation))
  Process.waitpid(pid)
rescue FFI::NotFoundError
  system(editor_invocation)
end

def start_line_syntax_for_editor(file_name, line_number)

and moving to a particular line within that file
Return the syntax for a given editor for starting the editor
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 /^code/
    "-g #{file_name}:#{line_number}"
  when /^subl/
    "#{file_name}:#{line_number}"
  when /^uedit32/
    "#{file_name}/#{line_number}"
  when /^jedit/
    "#{file_name} +line:#{line_number}"
  when /^redcar/
    "-l#{line_number} #{file_name}"
  else
    if Helpers::Platform.windows?
      file_name.to_s
    else
      "+#{line_number} #{file_name}"
    end
  end
end