1# 2# irb/context.rb - irb context 3# $Release Version: 0.9.6$ 4# $Revision: 39048 $ 5# by Keiju ISHITSUKA(keiju@ruby-lang.org) 6# 7# -- 8# 9# 10# 11require "irb/workspace" 12require "irb/inspector" 13 14module IRB 15 # A class that wraps the current state of the irb session, including the 16 # configuration of IRB.conf. 17 class Context 18 # Creates a new IRB context. 19 # 20 # The optional +input_method+ argument: 21 # 22 # +nil+:: uses stdin or Readline 23 # +String+:: uses a File 24 # +other+:: uses this as InputMethod 25 def initialize(irb, workspace = nil, input_method = nil, output_method = nil) 26 @irb = irb 27 if workspace 28 @workspace = workspace 29 else 30 @workspace = WorkSpace.new 31 end 32 @thread = Thread.current if defined? Thread 33# @irb_level = 0 34 35 # copy of default configuration 36 @ap_name = IRB.conf[:AP_NAME] 37 @rc = IRB.conf[:RC] 38 @load_modules = IRB.conf[:LOAD_MODULES] 39 40 @use_readline = IRB.conf[:USE_READLINE] 41 @verbose = IRB.conf[:VERBOSE] 42 @io = nil 43 44 self.inspect_mode = IRB.conf[:INSPECT_MODE] 45 self.math_mode = IRB.conf[:MATH_MODE] if IRB.conf[:MATH_MODE] 46 self.use_tracer = IRB.conf[:USE_TRACER] if IRB.conf[:USE_TRACER] 47 self.use_loader = IRB.conf[:USE_LOADER] if IRB.conf[:USE_LOADER] 48 self.eval_history = IRB.conf[:EVAL_HISTORY] if IRB.conf[:EVAL_HISTORY] 49 50 @ignore_sigint = IRB.conf[:IGNORE_SIGINT] 51 @ignore_eof = IRB.conf[:IGNORE_EOF] 52 53 @back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT] 54 55 self.prompt_mode = IRB.conf[:PROMPT_MODE] 56 57 if IRB.conf[:SINGLE_IRB] or !defined?(IRB::JobManager) 58 @irb_name = IRB.conf[:IRB_NAME] 59 else 60 @irb_name = IRB.conf[:IRB_NAME]+"#"+IRB.JobManager.n_jobs.to_s 61 end 62 @irb_path = "(" + @irb_name + ")" 63 64 case input_method 65 when nil 66 case use_readline? 67 when nil 68 if (defined?(ReadlineInputMethod) && STDIN.tty? && 69 IRB.conf[:PROMPT_MODE] != :INF_RUBY) 70 @io = ReadlineInputMethod.new 71 else 72 @io = StdioInputMethod.new 73 end 74 when false 75 @io = StdioInputMethod.new 76 when true 77 if defined?(ReadlineInputMethod) 78 @io = ReadlineInputMethod.new 79 else 80 @io = StdioInputMethod.new 81 end 82 end 83 84 when String 85 @io = FileInputMethod.new(input_method) 86 @irb_name = File.basename(input_method) 87 @irb_path = input_method 88 else 89 @io = input_method 90 end 91 self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY] 92 93 if output_method 94 @output_method = output_method 95 else 96 @output_method = StdioOutputMethod.new 97 end 98 99 @echo = IRB.conf[:ECHO] 100 if @echo.nil? 101 @echo = true 102 end 103 self.debug_level = IRB.conf[:DEBUG_LEVEL] 104 end 105 106 # The top-level workspace, see WorkSpace#main 107 def main 108 @workspace.main 109 end 110 111 # The toplevel workspace, see #home_workspace 112 attr_reader :workspace_home 113 # WorkSpace in the current context 114 attr_accessor :workspace 115 # The current thread in this context 116 attr_reader :thread 117 # The current input method 118 # 119 # Can be either StdioInputMethod, ReadlineInputMethod, FileInputMethod or 120 # other specified when the context is created. See ::new for more 121 # information on +input_method+. 122 attr_accessor :io 123 124 # Current irb session 125 attr_accessor :irb 126 # A copy of the default <code>IRB.conf[:AP_NAME]</code> 127 attr_accessor :ap_name 128 # A copy of the default <code>IRB.conf[:RC]</code> 129 attr_accessor :rc 130 # A copy of the default <code>IRB.conf[:LOAD_MODULES]</code> 131 attr_accessor :load_modules 132 # Can be either name from <code>IRB.conf[:IRB_NAME]</code>, or the number of 133 # the current job set by JobManager, such as <code>irb#2</code> 134 attr_accessor :irb_name 135 # Can be either the #irb_name surrounded by parenthesis, or the 136 # +input_method+ passed to Context.new 137 attr_accessor :irb_path 138 139 # Whether +Readline+ is enabled or not. 140 # 141 # A copy of the default <code>IRB.conf[:USE_READLINE]</code> 142 # 143 # See #use_readline= for more information. 144 attr_reader :use_readline 145 # A copy of the default <code>IRB.conf[:INSPECT_MODE]</code> 146 attr_reader :inspect_mode 147 148 # A copy of the default <code>IRB.conf[:PROMPT_MODE]</code> 149 attr_reader :prompt_mode 150 # Standard IRB prompt 151 # 152 # See IRB@Customizing+the+IRB+Prompt for more information. 153 attr_accessor :prompt_i 154 # IRB prompt for continuated strings 155 # 156 # See IRB@Customizing+the+IRB+Prompt for more information. 157 attr_accessor :prompt_s 158 # IRB prompt for continuated statement (e.g. immediately after an +if+) 159 # 160 # See IRB@Customizing+the+IRB+Prompt for more information. 161 attr_accessor :prompt_c 162 # See IRB@Customizing+the+IRB+Prompt for more information. 163 attr_accessor :prompt_n 164 # Can be either the default <code>IRB.conf[:AUTO_INDENT]</code>, or the 165 # mode set by #prompt_mode= 166 # 167 # To enable auto-indentation in irb: 168 # 169 # IRB.conf[:AUTO_INDENT] = true 170 # 171 # or 172 # 173 # irb_context.auto_indent_mode = true 174 # 175 # or 176 # 177 # IRB.CurrentContext.auto_indent_mode = true 178 # 179 # See IRB@Configuration for more information. 180 attr_accessor :auto_indent_mode 181 # The format of the return statement, set by #prompt_mode= using the 182 # +:RETURN+ of the +mode+ passed to set the current #prompt_mode. 183 attr_accessor :return_format 184 185 # Whether <code>^C</code> (+control-c+) will be ignored or not. 186 # 187 # If set to +false+, <code>^C</code> will quit irb. 188 # 189 # If set to +true+, 190 # 191 # * during input: cancel input then return to top level. 192 # * during execute: abandon current execution. 193 attr_accessor :ignore_sigint 194 # Whether <code>^D</code> (+control-d+) will be ignored or not. 195 # 196 # If set to +false+, <code>^D</code> will quit irb. 197 attr_accessor :ignore_eof 198 # Whether to echo the return value to output or not. 199 # 200 # Uses IRB.conf[:ECHO] if available, or defaults to +true+. 201 # 202 # puts "hello" 203 # # hello 204 # #=> nil 205 # IRB.CurrentContext.echo = false 206 # puts "omg" 207 # # omg 208 attr_accessor :echo 209 # Whether verbose messages are displayed or not. 210 # 211 # A copy of the default <code>IRB.conf[:VERBOSE]</code> 212 attr_accessor :verbose 213 # The debug level of irb 214 # 215 # See #debug_level= for more information. 216 attr_reader :debug_level 217 218 # The limit of backtrace lines displayed as top +n+ and tail +n+. 219 # 220 # The default value is 16. 221 # 222 # Can also be set using the +--back-trace-limit+ command line option. 223 # 224 # See IRB@Command+line+options for more command line options. 225 attr_accessor :back_trace_limit 226 227 # Alias for #use_readline 228 alias use_readline? use_readline 229 # Alias for #rc 230 alias rc? rc 231 alias ignore_sigint? ignore_sigint 232 alias ignore_eof? ignore_eof 233 alias echo? echo 234 235 # Returns whether messages are displayed or not. 236 def verbose? 237 if @verbose.nil? 238 if defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod) 239 false 240 elsif !STDIN.tty? or @io.kind_of?(FileInputMethod) 241 true 242 else 243 false 244 end 245 else 246 @verbose 247 end 248 end 249 250 # Whether #verbose? is +true+, and +input_method+ is either 251 # StdioInputMethod or ReadlineInputMethod, see #io for more information. 252 def prompting? 253 verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) || 254 (defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod))) 255 end 256 257 # The return value of the last statement evaluated. 258 attr_reader :last_value 259 260 # Sets the return value from the last statement evaluated in this context 261 # to #last_value. 262 def set_last_value(value) 263 @last_value = value 264 @workspace.evaluate self, "_ = IRB.CurrentContext.last_value" 265 end 266 267 # Sets the +mode+ of the prompt in this context. 268 # 269 # See IRB@Customizing+the+IRB+Prompt for more information. 270 def prompt_mode=(mode) 271 @prompt_mode = mode 272 pconf = IRB.conf[:PROMPT][mode] 273 @prompt_i = pconf[:PROMPT_I] 274 @prompt_s = pconf[:PROMPT_S] 275 @prompt_c = pconf[:PROMPT_C] 276 @prompt_n = pconf[:PROMPT_N] 277 @return_format = pconf[:RETURN] 278 if ai = pconf.include?(:AUTO_INDENT) 279 @auto_indent_mode = ai 280 else 281 @auto_indent_mode = IRB.conf[:AUTO_INDENT] 282 end 283 end 284 285 # Whether #inspect_mode is set or not, see #inspect_mode= for more detail. 286 def inspect? 287 @inspect_mode.nil? or @inspect_mode 288 end 289 290 # Whether #io uses a File for the +input_method+ passed when creating the 291 # current context, see ::new 292 def file_input? 293 @io.class == FileInputMethod 294 end 295 296 # Specifies the inspect mode with +opt+: 297 # 298 # +true+:: display +inspect+ 299 # +false+:: display +to_s+ 300 # +nil+:: inspect mode in non-math mode, 301 # non-inspect mode in math mode 302 # 303 # See IRB::Inspector for more information. 304 # 305 # Can also be set using the +--inspect+ and +--noinspect+ command line 306 # options. 307 # 308 # See IRB@Command+line+options for more command line options. 309 def inspect_mode=(opt) 310 311 if i = Inspector::INSPECTORS[opt] 312 @inspect_mode = opt 313 @inspect_method = i 314 i.init 315 else 316 case opt 317 when nil 318 if Inspector.keys_with_inspector(Inspector::INSPECTORS[true]).include?(@inspect_mode) 319 self.inspect_mode = false 320 elsif Inspector.keys_with_inspector(Inspector::INSPECTORS[false]).include?(@inspect_mode) 321 self.inspect_mode = true 322 else 323 puts "Can't switch inspect mode." 324 return 325 end 326 when /^\s*\{.*\}\s*$/ 327 begin 328 inspector = eval "proc#{opt}" 329 rescue Exception 330 puts "Can't switch inspect mode(#{opt})." 331 return 332 end 333 self.inspect_mode = inspector 334 when Proc 335 self.inspect_mode = IRB::Inspector(opt) 336 when Inspector 337 prefix = "usr%d" 338 i = 1 339 while Inspector::INSPECTORS[format(prefix, i)]; i += 1; end 340 @inspect_mode = format(prefix, i) 341 @inspect_method = opt 342 Inspector.def_inspector(format(prefix, i), @inspect_method) 343 else 344 puts "Can't switch inspect mode(#{opt})." 345 return 346 end 347 end 348 print "Switch to#{unless @inspect_mode; ' non';end} inspect mode.\n" if verbose? 349 @inspect_mode 350 end 351 352 # Obsolete method. 353 # 354 # Can be set using the +--noreadline+ and +--readline+ command line 355 # options. 356 # 357 # See IRB@Command+line+options for more command line options. 358 def use_readline=(opt) 359 print "This method is obsolete." 360 print "Do nothing." 361 end 362 363 # Sets the debug level of irb 364 # 365 # Can also be set using the +--irb_debug+ command line option. 366 # 367 # See IRB@Command+line+options for more command line options. 368 def debug_level=(value) 369 @debug_level = value 370 RubyLex.debug_level = value 371 end 372 373 # Whether or not debug mode is enabled, see #debug_level=. 374 def debug? 375 @debug_level > 0 376 end 377 378 def evaluate(line, line_no) # :nodoc: 379 @line_no = line_no 380 set_last_value(@workspace.evaluate(self, line, irb_path, line_no)) 381# @workspace.evaluate("_ = IRB.conf[:MAIN_CONTEXT]._") 382# @_ = @workspace.evaluate(line, irb_path, line_no) 383 end 384 385 def inspect_last_value # :nodoc: 386 @inspect_method.inspect_value(@last_value) 387 end 388 389 alias __exit__ exit 390 # Exits the current session, see IRB.irb_exit 391 def exit(ret = 0) 392 IRB.irb_exit(@irb, ret) 393 end 394 395 NOPRINTING_IVARS = ["@last_value"] # :nodoc: 396 NO_INSPECTING_IVARS = ["@irb", "@io"] # :nodoc: 397 IDNAME_IVARS = ["@prompt_mode"] # :nodoc: 398 399 alias __inspect__ inspect 400 def inspect # :nodoc: 401 array = [] 402 for ivar in instance_variables.sort{|e1, e2| e1 <=> e2} 403 ivar = ivar.to_s 404 name = ivar.sub(/^@(.*)$/, '\1') 405 val = instance_eval(ivar) 406 case ivar 407 when *NOPRINTING_IVARS 408 array.push format("conf.%s=%s", name, "...") 409 when *NO_INSPECTING_IVARS 410 array.push format("conf.%s=%s", name, val.to_s) 411 when *IDNAME_IVARS 412 array.push format("conf.%s=:%s", name, val.id2name) 413 else 414 array.push format("conf.%s=%s", name, val.inspect) 415 end 416 end 417 array.join("\n") 418 end 419 alias __to_s__ to_s 420 alias to_s inspect 421 end 422end 423