require'byebug/command'require'byebug/helpers/file'require'byebug/helpers/parse'moduleByebug## List parts of the source code.#classListCommand<CommandincludeHelpers::FileHelperincludeHelpers::ParseHelperself.allow_in_post_mortem=truedefself.regexp/^\s* l(?:ist)? (?:\s*([-=])|\s+(\S+))? \s*$/xenddefself.description<<-EOD
l[ist][[-=]][ nn-mm]
#{short_description}
Lists lines forward from current line or from the place where code was
last listed. If "list-" is specified, lists backwards instead. If
"list=" is specified, lists from current line regardless of where code
was last listed. A line range can also be specified to list specific
sections of code.
EODenddefself.short_description'Lists lines of source code'enddefexecutemsg="No sourcefile available for #{frame.file}"raise(msg)unlessFile.exist?(frame.file)max_lines=n_lines(frame.file)b,e=range(@match[2],max_lines)raise('Invalid line range')unlessvalid_range?(b,e,max_lines)display_lines(b,e)processor.prev_line=bendprivate## Line range to be printed by `list`.## If <input> is set, range is parsed from it.## Otherwise it's automatically chosen.#defrange(input,max_line)size=[Setting[:listsize],max_line].minreturnset_range(size,max_line)unlessinputparse_range(input,size,max_line)enddefvalid_range?(first,last,max)first<=last&&(1..max).cover?(first)&&(1..max).cover?(last)end## Set line range to be printed by list## @param size - number of lines to be printed# @param max_line - max line number that can be printed## @return first line number to list# @return last line number to list#defset_range(size,max_line)first=amend(lower(size,@match[1]||'+'),max_line-size+1)[first,move(first,size-1)]enddefparse_range(input,size,max_line)first,err=get_int(lower_bound(input),'List',1,max_line)raise(err)unlessfirstifupper_bound(input)last,err=get_int(upper_bound(input),'List',1,max_line)raise(err)unlesslastlast=amend(last,max_line)elsefirst-=(size/2)end[first,last||move(first,size-1)]enddefamend(line,max_line)return1ifline<1[max_line,line].minenddeflower(size,direction='+')prev_line=processor.prev_linereturnframe.line-size/2ifdirection=='='||prev_line.nil?move(prev_line,size,direction)enddefmove(line,size,direction='+')line.send(direction,size)end## Show a range of lines in the current file.## @param min [Integer] Lower bound# @param max [Integer] Upper bound#defdisplay_lines(min,max)puts"\n[#{min}, #{max}] in #{frame.file}"File.foreach(frame.file).with_indexdo|line,lineno|breakiflineno+1>maxnextunless(min..max).cover?(lineno+1)mark=lineno+1==frame.line?'=> ':' 'putsformat("#{mark}%#{max.to_s.size}d: %s",lineno+1,line)endend## @param range [String] A string with an integer range format## @return [String] The lower bound of the given range#deflower_bound(range)split_range(range)[0]end## @param range [String] A string with an integer range format## @return [String] The upper bound of the given range#defupper_bound(range)split_range(range)[1]end## @param str [String] A string with an integer range format## @return [Array] The upper & lower bounds of the given range#defsplit_range(str)str.split(/[-,]/)endendend