lib/byebug/commands/set.rb



module Byebug

  # Mix-in module to setting settings
  module SetFunctions

    def set_setting(setting_name, setting_value, setting_args)
      case setting_name
      when /^args$/
        if defined?(Byebug::BYEBUG_SCRIPT)
          Command.settings[:argv][1..-1] = setting_args
        else
          Command.settings[:argv] = setting_args
        end
      when /^autoirb$/
        Command.settings[:autoirb] = (setting_value ? 1 : 0)
      when /^autolist$/
        Command.settings[:autolist] = (setting_value ? 1 : 0)
      when /^callstyle$/
        if setting_args[0] and ['short', 'long'].include?(setting_args[0])
          Command.settings[:callstyle] = setting_args[0].to_sym
        else
          print "Invalid callstyle. Should be one of: \"short\" or \"long\"\n"
        end
      when /^history$/
        try_subcmd = setting_args[0]
        subcmd = Command.find(SetCommand::SetHistorySubcommands, try_subcmd)
        return print "Invalid history parameter #{try_subcmd}. Should be" \
                     ' "filename", "save" or "size"' unless subcmd

        sub_sub_cmd = setting_args[1]
        iface = @state.interface
        case subcmd.name
        when /^save$/
          iface.history_save = sub_sub_cmd ? get_onoff(sub_sub_cmd) : true
        when /^size$/
          return print 'You need to specify the history size' unless sub_sub_cmd
          iface.history_length = get_int(sub_sub_cmd, "Set history size")
        when /^filename$/
          return print 'You need to specify a filename' unless sub_sub_cmd
          iface.histfile = File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", sub_sub_cmd)
        end
      when /^linetrace$/
        Byebug.tracing = setting_value
      when /^listsize$/
        listsize = get_int(setting_args[0], "Set listsize", 1, nil, 10)
        return unless listsize
        Command.settings[:listsize] = listsize
      when /^width$/
        return unless width = get_int(setting_args[0], "Set width", 10, nil, 80)
        Command.settings[:width] = width
      when /^post_mortem$/
        if setting_value
          Byebug.post_mortem
        else
          Byebug.post_mortem = false
        end
      when /^autoeval|autoreload|basename|forcestep|fullpath|linetrace_plus|
             testing|stack_trace_on_error$/x
        Command.settings[setting_name.to_sym] = setting_value
      else
        return print "Unknown setting #{@match[1]}.\n"
      end
    end
  end


  # Implements byebug "set" command.
  class SetCommand < Command
    SubcmdStruct2 = Struct.new(:name,
                               :min,
                               :is_bool,
                               :short_help,
                               :long_help) unless defined?(SubcmdStruct2)

    Subcommands =
      [
       ['args', 2, false,
        'Set argument list to the program being debugged when it is started'],
       ['autoeval', 4, true, 'Evaluate every unrecognized command'],
       ['autolist', 4, true, 'Execute "list" command on every breakpoint'],
       ['autoirb', 4, true, 'Invoke IRB on every stop'],
       ['autoreload', 4, true, 'Reload source code when changed'],
       ['basename', 1, true, 'Set filename display style'],
       ['callstyle', 2, false, 'Set how you want call parameters displayed'],
       ['testing', 2, false, 'Used when testing byebug'],
       ['forcestep', 2, true,
        'Make sure "next/step" commands always move to a new line'],
       ['fullpath', 2, true, 'Display full file names in frames'],
       ['history', 2, false, 'Command for setting command history parameters',
        'History parameters are "filename", "save" and "size"'],
       ['linetrace', 3, true, 'Enable line execution tracing'],
       ['linetrace_plus', 10, true,
        'Set line execution tracing to show different lines'],
       ['listsize', 3, false, 'Set number of source lines to list by default'],
       ['post_mortem', 2, true, 'Enable post-mortem mode'],
       ['stack_trace_on_error', 1, true,
        'Display stack trace when "eval" raises exception'],
       ['width', 1, false,
        'Number of characters per line for byebug\'s output']
      ].map do |name, min, is_bool, short_help, long_help|
      SubcmdStruct2.new(name, min, is_bool, short_help, long_help)
    end unless defined?(Subcommands)

    SetHistorySubcommands =
      [
       ['filename', 1, 'Set the filename in which to record command history'],
       ['save', 1, 'Set saving of the history record on exit'],
       ['size', 1, 'Set the size of the command history']
      ].map do |name, min, short_help, long_help|
        Subcmd.new(name, min, short_help, long_help)
      end unless defined?(SetHistorySubcommands)

    self.allow_in_control = true

    def regexp
      /^\s* set (?:\s+(.*))? \s*$/x
    end

    def execute
      return print SetCommand.help(nil) if SetCommand.names.include?(@match[0])

      args = @match[1].split(/[ \t]+/)
      try_subcmd = args.shift
      try_subcmd.downcase!
      if try_subcmd =~ /^no/i
        set_on = false
        try_subcmd = try_subcmd[2..-1]
      else
        set_on = true
      end

      subcmd = Command.find(Subcommands, try_subcmd)
      return print "Unknown set command \"#{try_subcmd}\"\n" unless subcmd

      begin
        set_on = get_onoff(args[0]) if subcmd.is_bool and args.size > 0
      rescue RuntimeError
        return
      end

      set_setting(subcmd.name, set_on, args)

      return print "#{show_setting(subcmd.name)}\n"
    end

    class << self
      def names
        %w(set)
      end

      def description
        %{Modifies parts of byebug environment. Boolean values take on, off, 1
          or 0. You can see these environment settings with the "show" command.}
      end
    end

  end
end