class Editors

Editor class. Lets you edit both real and temporary files, and returns their values after editing.

@author Jeff Sandberg

Constants

MAJOR
MINOR
PATCH
VERSION

Attributes

content[R]

Public Class Methods

file(file, line = 1, blocking = true) click to toggle source

Edit a file from the filesystem, and return its value @param file [String] A file path to edit @param line [Fixnum] The line of the file to place the cursor at @param blocking [Boolean] Pass the editor a blocking flag

@return [String] The value of the file AFTER it was edited

# File lib/editor.rb, line 42
def file(file, line = 1, blocking = true)
  new(file: file, line: line, blocking: blocking).content
end
new(options = {}) click to toggle source

Initialize a new editor, with options. You should probably use Editor.edit or Editor.new instead of these You must pass a file OR temp string, but NOT both

@param options [Hash] @option file [String] options (nil) A file path to edit @option temp [String] options (nil) The content of the tempfile, prior to editing @option line [String] options (1) The line of the file to place the cursor at @option blocking [Boolean] options (true) Pass the editor a blocking flag @return [Editor] Editor object, with content set to the return value from the file

# File lib/editor.rb, line 24
def initialize(options = {})
  opts = { file: nil, temp: nil, line: 1, blocking: true }.merge(options)
  if !opts_is_valid?opts
    fail ArgumentError, 'define file OR temp'
  elsif opts[:file]
    edit_file(opts)
  elsif opts[:temp]
    edit_temp(opts)
  end
end
temp(initial_content, line = 1) click to toggle source

Edits a temporary file, and return its value @param initial_content [String] The content of the tempfile, prior to editing @param line [Fixnum] Tempfile line to place cursor at

@return [String] The value of the tempfile AFTER it was edited

# File lib/editor.rb, line 51
def temp(initial_content, line = 1)
  new(temp: initial_content, line: line, blocking: true).content
end

Private Instance Methods

build_editor_invocation_string(file, line, blocking) click to toggle source

Builds the string that is used to call the editor @param file [String] File path @param line [Fixnum] Line number @param blocking [Boolean]

@return [String] Editor invocation string

# File lib/editor.rb, line 130
def build_editor_invocation_string(file, line, blocking)
  sanitized_file = windows? ? file.gsub(/\//, '\\') : Shellwords.escape(file)
  "#{default_editor} #{blocking_flag_for_editor(blocking)} #{start_line_syntax_for_editor(sanitized_file, line)}"
end
default_editor() click to toggle source

Get the user’s configured visual or editor ENV

@return [String] The editor command

# File lib/editor.rb, line 154
def default_editor
  # Visual = Advanced editor
  return ENV['VISUAL'] if ENV['VISUAL'] && !ENV['VISUAL'].empty?
  # Editor = basic editor
  return ENV['EDITOR'] if ENV['EDITOR'] && !ENV['EDITOR'].empty?
  if windows?
    'notepad'
  else
    %w(editor nano vi).find do |editor|
      system("which #{editor} > /dev/null 2>&1")
    end
  end
end
edit_file(opts = {}) click to toggle source

Open the file in the users editor of choice @param opts [Hash] Options hash @option file [String] options (nil) A file path to edit @option line [String] options (1) The line of the file to place the cursor at @option blocking [Boolean] options (true) Pass the editor a blocking flag

@return [String] The value of the tempfile AFTER it was edited

# File lib/editor.rb, line 73
def edit_file(opts = {})
  File.open(opts[:file]) do |f|
    invoke_editor(f.path, opts[:line], opts[:blocking])
    @content = File.read(f.path)
  end
end
edit_temp(opts = {}) click to toggle source

Put a string in a temp file and present it to the user for editing @param opts [Hash] Options hash @option temp [String] options (nil) The content of the tempfile, prior to editing @option line [String] options (1) The line of the file to place the cursor at

@return [String] The value of the tempfile AFTER it was edited

# File lib/editor.rb, line 86
def edit_temp(opts = {})
  temp_file do |f|
    f.puts(opts[:temp])
    f.flush
    f.close(false)
    invoke_editor(f.path, opts[:line], true)
    @content = File.read(f.path)
  end
end
invoke_editor(file, line = 1, blocking = true) click to toggle source

Open the users default editor with the params specified @param file [String] File path @param line [Fixnum] Line number to place cursor at @param blocking = true [Boolean] If the editor should be blocking

# File lib/editor.rb, line 100
def invoke_editor(file, line = 1, blocking = true)
  fail 'Please export $VISUAL or $EDITOR' unless default_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
open_editor(editor_invocation) click to toggle source

Open the editor @param editor_invocation [String] Value from build_editor_invocation_string

# File lib/editor.rb, line 137
def open_editor(editor_invocation)
  system(*Shellwords.split(editor_invocation)) || fail("`#{editor_invocation}` gave exit status: #{$CHILD_STATUS.exitstatus}")
end
open_editor_on_jruby(editor_invocation) click to toggle source

jRuby doesn’t like open_editor, so we have to muck about with this @param editor_invocation [String] Value from build_editor_invocation_string

# File lib/editor.rb, line 143
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
opts_is_valid?(opts = {}) click to toggle source

Checks if an options hash contains both file and temp values @param opts [Hash] Options hash

@return [Boolean]

# File lib/editor.rb, line 62
def opts_is_valid?(opts = {})
  !(opts[:file].nil? && opts[:temp].nil?) || (opts[:file] && opts[:temp])
end
temp_file(ext = '.rb') { |file| ... } click to toggle source

Create and yield a tempfile @param ext [String] File extension for the file to user

@yieldparam [File] The tempfile object

# File lib/editor.rb, line 117
def temp_file(ext = '.rb')
  file = Tempfile.new(['editors', ext])
  yield file
ensure
  file.close(true) if file
end