module Rcodetools::ProcessParticularLine

Common routines for XMPCompletionFilter/XMPDocFilter

Constants

OPERATOR_CHARS

Public Instance Methods

__magic_help_code(result, v, meth) click to toggle source
# File lib/rcodetools/completion.rb, line 181
  def __magic_help_code(result, v, meth)
    code = <<-EOC
  #{result} = #{v}.method(#{meth}).inspect.match( %r[\\A#<(?:Unbound)?Method: (.*?)>\\Z] )[1].sub(/\\A.*?\\((.*?)\\)(.*)\\Z/){ "\#{$1}\#{$2}" }.sub(/#<Class:(.*?)>#/) { "\#{$1}." }
  #{result} = #{v}.to_s + ".new" if #{result} == 'Class#new' and #{v}.private_method_defined?(:initialize)
  #{result} = "Object#" + #{meth} if #{result} =~ /^Kernel#/ and Kernel.instance_methods(false).map{|x| x.to_s}.include? #{meth}
  #{result}
EOC
  end
_handle_brackets(expr_orig, expr) click to toggle source
# File lib/rcodetools/completion.rb, line 62
def _handle_brackets(expr_orig, expr)
  [ %w[{ }], %w[( )], %w[ ]! ].each do |left, right|
    n_left  = expr_orig.count(left)  - expr.count(left)
    n_right = expr_orig.count(right) - expr.count(right)
    n = n_left - n_right
    @postfix << ";#{left}" * n if n >= 0
  end
end
_handle_do_end(right_stripped) click to toggle source
# File lib/rcodetools/completion.rb, line 55
def _handle_do_end(right_stripped)
  right_stripped << "\n"
  n_do = right_stripped.scan(/[\s\)]do\s/).length
  n_end = right_stripped.scan(/\bend\b/).length
  @postfix = ";begin" * (n_do - n_end)
end
_handle_keywords(expr_orig, column) click to toggle source
# File lib/rcodetools/completion.rb, line 71
def _handle_keywords(expr_orig, column)
  %w[if unless while until for].each do |keyw|
    pos = expr_orig.index(/\b#{keyw}\b/)
    @postfix << ";begin" if pos and pos < column # if * xxx

    pos = expr_orig.index(/;\s*#{keyw}\b/)
    @postfix << ";begin" if pos and column < pos # * ; if xxx
  end
end
add_BEGIN() click to toggle source
# File lib/rcodetools/completion.rb, line 140
  def add_BEGIN
    <<XXX
BEGIN {
class Object
  def method_missing(meth, *args, &block)
    # ignore NoMethodError
  end
end
}
XXX
  end
aref_or_aset?(right_stripped, last_char) click to toggle source
# File lib/rcodetools/completion.rb, line 81
def aref_or_aset?(right_stripped, last_char)
  if last_char == [
    case right_stripped
    when /\]\s*=/ then "[]="
    when /\]/     then "[]"
    end
  end
end
current_phrase(expr) click to toggle source
# File lib/rcodetools/completion.rb, line 118
def current_phrase(expr)
  paren_level = 0
  start = 0
  (expr.length-1).downto(0) do |i|
    c = expr[i,1]
    if c =~ /[\)\}\]]/
      paren_level += 1
      next
    end
    if paren_level > 0
      next if c =~ /[, ]/
    else
      break (start = i+1) if c =~ /[ ,\(\{\[]/
    end
    if c =~ /[\(\{\[]/
      paren_level -= 1
      break (start = i+1) if paren_level < 0
    end
  end
  expr[start..-1]
end
fill_literal!(expr) click to toggle source
# File lib/rcodetools/completion.rb, line 11
def fill_literal!(expr)
  [ "\"", "'", "`" ].each do |q|
    expr.gsub!(/#{q}(.+)#{q}/){ '"' + "x"*$1.length + '"' }
  end
  expr.gsub!(/(%([wWqQxrs])?(\W))(.+?)\3/){
    percent = $2 == 'x' ? '%'+$3 : $1 # avoid executing shell command
    percent + "x"*$4.length + $3
  }
  [ %w[( )], %w[{ }], %w[ ]!, %w[< >] ].each do |b,e|
    rb, re = [b,e].map{ |x| Regexp.quote(x)}
    expr.gsub!(/(%([wWqQxrs])?(#{rb}))(.+)#{re}/){
      percent = $2 == 'x' ? '%'+$3 : $1 # avoid executing shell command
      percent + "x"*$4.length + e
    }
  end
end
runtime_data(code, lineno, column=nil) click to toggle source
# File lib/rcodetools/completion.rb, line 177
def runtime_data(code, lineno, column=nil)
  runtime_data_with_class(code, lineno, column)[1]
end
runtime_data_with_class(code, lineno, column=nil) click to toggle source
# File lib/rcodetools/completion.rb, line 154
def runtime_data_with_class(code, lineno, column=nil)
  newcode = code.to_a.enum_with_index.map{|line, i|
    i+1==lineno ? prepare_line(line.chomp, column) : line
  }.join
  newcode << add_BEGIN if @ignore_NoMethodError
  debugprint "newcode", newcode.gsub(/;/, "\n"), "-"*80
  stdout, stderr = execute(newcode)
  output = stderr.readlines
  debugprint "stderr", output, "-"*80
  output = output.reject{|x| /^-:[0-9]+: warning/.match(x)}
  runtime_data = extract_data(output)
  if exception = /^-:[0-9]+:.*/.match(output.join)
    raise NewCodeError, exception[0].chomp
  end
  begin
    dat = runtime_data.results[1][0]
    debugprint "dat = #{dat.inspect}"
    [dat[0], dat[1..-1].to_s]
  rescue
    raise RuntimeDataError, runtime_data.inspect
  end
end
set_expr_and_postfix!(expr, column, ®exp) click to toggle source
# File lib/rcodetools/completion.rb, line 33
def set_expr_and_postfix!(expr, column, &regexp)
  expr.extend ExpressionExtension

  @postfix = ""
  expr_orig = expr.clone
  column ||= expr.length
  last_char = expr[column-1]
  expr.replace expr[ regexp[column] ]
  debugprint "expr_orig=#{expr_orig}", "expr(sliced)=#{expr}"
  right_stripped = Regexp.last_match.post_match
  _handle_do_end right_stripped
  aref_or_aset = aref_or_aset? right_stripped, last_char
  debugprint "aref_or_aset=#{aref_or_aset.inspect}"
  set_last_word! expr, aref_or_aset
  fill_literal! expr_orig
  _handle_brackets expr_orig, expr
  expr << aref_or_aset if aref_or_aset
  _handle_keywords expr_orig, column
  debugprint "expr(processed)=#{expr}"
  expr
end
set_last_word!(expr, aref_or_aset=nil) click to toggle source
# File lib/rcodetools/completion.rb, line 90
def set_last_word!(expr, aref_or_aset=nil)
  debugprint "expr(before set_last_word)=#{expr}"
  if aref_or_aset
    opchars = "" 
  else
    opchars = expr.slice!(/\s*[#{OPERATOR_CHARS}]+$/)
    debugprint "expr(strip opchars)=#{expr}"
  end
  
  expr.replace(if expr =~ /[\"\\`]$/      # String operations
                 "''"
               else
                 fill_literal! expr
                 phrase = current_phrase(expr)
                 if aref_or_aset
                   expr.eval_string = expr[0..-2]
                   expr.meth = aref_or_aset
                 elsif phrase.match( /^(.+)\.(.*)$/ )
                   expr.eval_string, expr.meth = $1, $2
                 elsif opchars != ''
                   expr
                 end
                 debugprint "expr.eval_string=#{expr.eval_string}", "expr.meth=#{expr.meth}"
                 phrase
               end << (opchars || '')) # ` font-lock hack
  debugprint "expr(after set_last_word)=#{expr}"
end