require'columnize'require'forwardable'require_relative'helper'moduleByebugmoduleCommandFunctions### Pad a string with dots at the end to fit :width setting#defpad_with_dots(string)ifstring.size>Command.settings[:width]string[Command.settings[:width]-3..-1]="..."endend### Find param in subcmds.## @param is downcased and can be abbreviated to the minimum length listed in# the subcommands.#deffind(subcmds,param)param.downcase!fortry_subcmdinsubcmdsdoif(param.size>=try_subcmd.min)and(try_subcmd.name[0..param.size-1]==param)returntry_subcmdendendreturnnilend### Build formatted list of subcmds#defformat_subcmds(subcmds)cmd_name=self.class.names.join("|")s="\n"\"--\n"\"List of \"#{cmd_name}\" subcommands:\n"\"--\n"forsubcmdinsubcmdsdos+="#{cmd_name}#{subcmd.name} -- #{subcmd.short_help}\n"endreturnsendend# Root dir for byebugBYEBUG_DIR=File.expand_path(File.dirname(__FILE__))unlessdefined?(BYEBUG_DIR)classCommandSubcmdStruct=Struct.new(:name,:min,:short_help,:long_help)unlessdefined?(SubcmdStruct)class<<selfdefcommands@commands||=[]endDEF_OPTIONS={allow_in_control: false,allow_in_post_mortem: true,event: true,always_run: 0,unknown: false,need_context: false}unlessdefined?(DEF_OPTIONS)defhelp(args)output=description.split("\n").map{|l|l.gsub(/^ +/,'')}output.shiftifoutput.first&&output.first.empty?output.popifoutput.last&&output.last.empty?output.join("\n")+"\n"enddefinherited(klass)DEF_OPTIONS.eachdo|o,v|klass.options[o]=vifklass.options[o].nil?endcommands<<klassenddefload_commandsDir[File.join(Byebug.const_get(:BYEBUG_DIR),'commands','*')].each{|file|requirefileiffile=~/\.rb$/}Byebug.constants.grep(/Functions$/).map{|name|Byebug.const_get(name)}.each{|mod|includemod}enddefmethod_missing(meth,*args,&block)ifmeth.to_s=~/^(.+?)=$/@options[$1.intern]=args.firstelseif@options.has_key?(meth)@options[meth]elsesuperendendenddefoptions@options||={}enddefsettings_map@@settings_map||={}endprivate:settings_mapdefsettingsunlessdefined?@settingsand@settings@settings=Object.newmap=settings_mapc=class<<@settings;selfendc.send(:define_method,:[])do|name|raise"No such setting #{name}"unlessmap.has_key?(name)map[name][:getter].callendc=class<<@settings;selfendc.send(:define_method,:[]=)do|name,value|raise"No such setting #{name}"unlessmap.has_key?(name)map[name][:setter].call(value)endend@settingsenddefregister_setting_var(name,default)var_name="@@#{name}"class_variable_set(var_name,default)register_setting_get(name){class_variable_get(var_name)}register_setting_set(name){|value|class_variable_set(var_name,value)}enddefregister_setting_get(name,&block)settings_map[name]||={}settings_map[name][:getter]=blockenddefregister_setting_set(name,&block)settings_map[name]||={}settings_map[name][:setter]=blockendend# Register default settingsregister_setting_var(:basename,false)register_setting_var(:callstyle,:last)register_setting_var(:testing,false)register_setting_var(:force_stepping,false)register_setting_var(:frame_fullpath,true)register_setting_var(:listsize,10)register_setting_var(:stack_trace_on_error,false)register_setting_var(:tracing_plus,false)register_setting_var(:width,ENV['COLUMNS'].to_i>10?ENV['COLUMNS'].to_i:80)Byebug::ARGV=ARGV.cloneunlessdefined?Byebug::ARGVregister_setting_var(:argv,Byebug::ARGV)definitialize(state)@state=stateenddefmatch(input)@match=regexp.match(input)endprotectedextendForwardabledef_delegators:@state,:errmsg,:printdefconfirm(msg)@state.confirm(msg)=='y'enddefdebug_eval(str,b=get_binding)beginval=eval(str,b)rescueStandardError,ScriptError=>eifCommand.settings[:stack_trace_on_error]at=eval("caller(1)",b)print"%s:%s\n",at.shift,e.to_s.sub(/\(eval\):1:(in `.*?':)?/,'')foriinatprint"\tfrom %s\n",iendelseprint"#{e.class} Exception: #{e.message}\n"endthrow:debug_errorendenddefdebug_silent_eval(str)begineval(str,get_binding)rescueStandardError,ScriptErrornilendenddefdebug_warning_eval(str,b=get_binding)begindebug_eval(str,b)rescue:debug_error=>eprint"#{e.class} Exception: #{e.message}\n"endenddefget_binding@state.context?@state.context.frame_binding(@state.frame_pos):TOPLEVEL_BINDINGendendCommand.load_commands### Returns ths settings object.# Use Byebug.settings[] and Byebug.settings[]= methods to query and set# byebug settings. These settings are available:## :autolist - automatically calls 'list' command on breakpoint# :autoeval - evaluates input in the current binding if it's not# recognized as a byebug command# :autoirb - automatically calls 'irb' command on breakpoint# :stack_trace_on_error - shows full stack trace if eval command results in# an exception# :frame_fullpath - displays full paths when showing frame stack# :frame_class_names - displays method's class name when showing frame# stack# :autoreload - makes 'list' command always display up-to-date# source code# :force_stepping - stepping command always move to the new line#defself.settingsCommand.settingsendend