/tools/Ruby/lib/ruby/1.8/irb/completion.rb

http://github.com/agross/netopenspace · Ruby · 205 lines · 147 code · 33 blank · 25 comment · 5 complexity · 96279bbb70b6d8d6a1ddc9961cff499a MD5 · raw file

  1. #
  2. # irb/completor.rb -
  3. # $Release Version: 0.9$
  4. # $Revision: 11708 $
  5. # $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
  6. # by Keiju ISHITSUKA(keiju@ishitsuka.com)
  7. # From Original Idea of shugo@ruby-lang.org
  8. #
  9. require "readline"
  10. module IRB
  11. module InputCompletor
  12. @RCS_ID='-$Id: completion.rb 11708 2007-02-12 23:01:19Z shyouhei $-'
  13. ReservedWords = [
  14. "BEGIN", "END",
  15. "alias", "and",
  16. "begin", "break",
  17. "case", "class",
  18. "def", "defined", "do",
  19. "else", "elsif", "end", "ensure",
  20. "false", "for",
  21. "if", "in",
  22. "module",
  23. "next", "nil", "not",
  24. "or",
  25. "redo", "rescue", "retry", "return",
  26. "self", "super",
  27. "then", "true",
  28. "undef", "unless", "until",
  29. "when", "while",
  30. "yield",
  31. ]
  32. CompletionProc = proc { |input|
  33. bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
  34. # puts "input: #{input}"
  35. case input
  36. when /^(\/[^\/]*\/)\.([^.]*)$/
  37. # Regexp
  38. receiver = $1
  39. message = Regexp.quote($2)
  40. candidates = Regexp.instance_methods(true)
  41. select_message(receiver, message, candidates)
  42. when /^([^\]]*\])\.([^.]*)$/
  43. # Array
  44. receiver = $1
  45. message = Regexp.quote($2)
  46. candidates = Array.instance_methods(true)
  47. select_message(receiver, message, candidates)
  48. when /^([^\}]*\})\.([^.]*)$/
  49. # Proc or Hash
  50. receiver = $1
  51. message = Regexp.quote($2)
  52. candidates = Proc.instance_methods(true) | Hash.instance_methods(true)
  53. select_message(receiver, message, candidates)
  54. when /^(:[^:.]*)$/
  55. # Symbol
  56. if Symbol.respond_to?(:all_symbols)
  57. sym = $1
  58. candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
  59. candidates.grep(/^#{sym}/)
  60. else
  61. []
  62. end
  63. when /^::([A-Z][^:\.\(]*)$/
  64. # Absolute Constant or class methods
  65. receiver = $1
  66. candidates = Object.constants
  67. candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
  68. when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/
  69. # Constant or class methods
  70. receiver = $1
  71. message = Regexp.quote($4)
  72. begin
  73. candidates = eval("#{receiver}.constants | #{receiver}.methods", bind)
  74. rescue Exception
  75. candidates = []
  76. end
  77. candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
  78. when /^(:[^:.]+)\.([^.]*)$/
  79. # Symbol
  80. receiver = $1
  81. message = Regexp.quote($2)
  82. candidates = Symbol.instance_methods(true)
  83. select_message(receiver, message, candidates)
  84. when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
  85. # Numeric
  86. receiver = $1
  87. message = Regexp.quote($5)
  88. begin
  89. candidates = eval(receiver, bind).methods
  90. rescue Exception
  91. candidates = []
  92. end
  93. select_message(receiver, message, candidates)
  94. when /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/
  95. # Numeric(0xFFFF)
  96. receiver = $1
  97. message = Regexp.quote($2)
  98. begin
  99. candidates = eval(receiver, bind).methods
  100. rescue Exception
  101. candidates = []
  102. end
  103. select_message(receiver, message, candidates)
  104. when /^(\$[^.]*)$/
  105. candidates = global_variables.grep(Regexp.new(Regexp.quote($1)))
  106. # when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
  107. when /^((\.?[^.]+)+)\.([^.]*)$/
  108. # variable
  109. receiver = $1
  110. message = Regexp.quote($3)
  111. gv = eval("global_variables", bind)
  112. lv = eval("local_variables", bind)
  113. cv = eval("self.class.constants", bind)
  114. if (gv | lv | cv).include?(receiver)
  115. # foo.func and foo is local var.
  116. candidates = eval("#{receiver}.methods", bind)
  117. elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
  118. # Foo::Bar.func
  119. begin
  120. candidates = eval("#{receiver}.methods", bind)
  121. rescue Exception
  122. candidates = []
  123. end
  124. else
  125. # func1.func2
  126. candidates = []
  127. ObjectSpace.each_object(Module){|m|
  128. begin
  129. name = m.name
  130. rescue Exception
  131. name = ""
  132. end
  133. next if name != "IRB::Context" and
  134. /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
  135. candidates.concat m.instance_methods(false)
  136. }
  137. candidates.sort!
  138. candidates.uniq!
  139. end
  140. select_message(receiver, message, candidates)
  141. when /^\.([^.]*)$/
  142. # unknown(maybe String)
  143. receiver = ""
  144. message = Regexp.quote($1)
  145. candidates = String.instance_methods(true)
  146. select_message(receiver, message, candidates)
  147. else
  148. candidates = eval("methods | private_methods | local_variables | self.class.constants", bind)
  149. (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
  150. end
  151. }
  152. Operators = ["%", "&", "*", "**", "+", "-", "/",
  153. "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
  154. "[]", "[]=", "^",]
  155. def self.select_message(receiver, message, candidates)
  156. candidates.grep(/^#{message}/).collect do |e|
  157. case e
  158. when /^[a-zA-Z_]/
  159. receiver + "." + e
  160. when /^[0-9]/
  161. when *Operators
  162. #receiver + " " + e
  163. end
  164. end
  165. end
  166. end
  167. end
  168. if Readline.respond_to?("basic_word_break_characters=")
  169. Readline.basic_word_break_characters= " \t\n\"\\'`><=;|&{("
  170. end
  171. Readline.completion_append_character = nil
  172. Readline.completion_proc = IRB::InputCompletor::CompletionProc