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]="..."endendendclassCommandSubcmd=Struct.new(:name,:min,:help)class<<selfdefcommands@commands||=[]endattr_accessor:allow_in_control,:unknown,:need_contextattr_writer:allow_in_post_mortem,:always_rundefallow_in_post_mortem@allow_in_post_mortem||=!defined?(@allow_in_post_mortem)?true:falseenddefalways_run@always_run||=0enddefhelp(args)ifargs&&args[1]output=format_subcmd(args[1])elseoutput=description.gsub(/^ +/,'')+"\n"output+=format_subcmdsifdefined?self::Subcommandsendoutputenddeffind(subcmds,param)param.downcase!fortry_subcmdinsubcmdsdoif(param.size>=try_subcmd.min)and(try_subcmd.name[0..param.size-1]==param)returntry_subcmdendendreturnnilenddefformat_subcmd(subcmd_name)subcmd=find(self::Subcommands,subcmd_name)return"Invalid \"#{names.join("|")}\" "\"subcommand \"#{args[1]}\"."unlesssubcmdreturn"#{subcmd.help}.\n"enddefformat_subcmdscmd_name=names.join("|")s="\n"\"--\n"\"List of \"#{cmd_name}\" subcommands:\n"\"--\n"w=self::Subcommands.map(&:name).max_by(&:size).sizeforsubcmdinself::Subcommandsdos+=sprintf"%s %-#{w}s -- %s\n",cmd_name,subcmd.name,subcmd.helpendreturnsenddefinherited(klass)commands<<klassenddefload_commandsDir[File.join(File.dirname(__FILE__),'commands','*')].each{|file|requirefile}Byebug.constants.grep(/Functions$/).map{|name|Byebug.const_get(name)}.each{|mod|includemod}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.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]=blockenddefcommand_exists?(command)ENV['PATH'].split(File::PATH_SEPARATOR).any?{|d|File.exist?File.join(d,command)}enddefterminal_widthifENV['COLUMNS']=~/^\d+$/ENV['COLUMNS'].to_ielsifSTDIN.tty?&&command_exists?('stty')`stty size`.scan(/\d+/)[1].to_ielsenilendendend# Register default settingsregister_setting_var(:basename,false)register_setting_var(:callstyle,:long)register_setting_var(:testing,false)register_setting_var(:forcestep,false)register_setting_var(:fullpath,true)register_setting_var(:listsize,10)register_setting_var(:stack_on_error,false)register_setting_var(:linetrace_plus,false)cols=terminal_width||160register_setting_var(:width,cols>10?cols:160)Byebug::ARGV=ARGV.cloneunlessdefined?Byebug::ARGVregister_setting_var(:argv,Byebug::ARGV)definitialize(state)@match,@state=nil,stateenddefmatch(input)@match=regexp.match(input)endprotectedextendForwardabledef_delegators:@state,:errmsg,:printdefconfirm(msg)@state.confirm(msg)=='y'enddefbb_eval(str,b=get_binding)begineval(str,b)rescueStandardError,ScriptError=>eat=eval('Thread.current.backtrace_locations(1)',b)print"#{at.shift}: #{e.class} Exception(#{e.message})\n"foriinatprint"\tfrom #{i}\n"endnilendenddefbb_warning_eval(str,b=get_binding)begineval(str,b)rescueStandardError,ScriptError=>eprint"#{e.class} Exception: #{e.message}\n"nilendenddefget_bindingpos=@state.frame_pos@state.context?@state.context.frame_binding(pos):TOPLEVEL_BINDINGenddefget_context(thnum)Byebug.contexts.find{|c|c.thnum==thnum}endendCommand.load_commands### Returns ths settings object.# Use Byebug.settings[] and Byebug.settings[]= methods to query and set# byebug settings. These settings are available:## :autoeval - evaluates input in the current binding if it's not# recognized as a byebug command# :autoirb - automatically calls 'irb' command on breakpoint# :autolist - automatically calls 'list' command on breakpoint# :autoreload - makes 'list' command always display up-to-date source# code# :frame_class_names - displays method's class name when showing frame stack# :forcestep - stepping command always move to the new line# :fullpath - displays full paths when showing frame stack# :stack_on_error - shows full stack trace if eval command results in an# exception#defself.settingsCommand.settingsendend