require 'coderay' class Pry ## # Pry::Indent is a class that can be used to indent a number of lines # containing Ruby code similar as to how IRB does it (but better). The class # works by tokenizing a string using CodeRay and then looping over those # tokens. Based on the tokens in a line of code that line (or the next one) # will be indented or un-indented by correctly. # class Indent # String containing the spaces to be inserted before the next line. attr_reader :indent_level # The amount of spaces to insert for each indent level. SPACES = ' ' # Hash containing all the tokens that should increase the indentation # level. The keys of this hash are open tokens, the values the matching # tokens that should prevent a line from being indented if they appear on # the same line. OPEN_TOKENS = { 'def' => 'end', 'class' => 'end', 'module' => 'end', 'do' => 'end', 'if' => 'end', 'unless' => 'end', 'while' => 'end', 'until' => 'end', 'for' => 'end', 'case' => 'end', 'begin' => 'end', '[' => ']', '{' => '}', '(' => ')' } # Which tokens can either be open tokens, or appear as modifiers on # a single-line. SINGLELINE_TOKENS = %w(if while until unless rescue) # Collection of token types that should be ignored. Without this list # keywords such as "class" inside strings would cause the code to be # indented incorrectly. IGNORE_TOKENS = [:space, :content, :string, :delimiter, :method, :ident] # Tokens that indicate the end of a statement (i.e. that, if they appear # directly before an "if" indicates that that if applies to the same line, # not the next line) STATEMENT_END_TOKENS = IGNORE_TOKENS + [:regexp, :integer, :float] # Collection of tokens that should appear dedented even though they # don't affect the surrounding code. MIDWAY_TOKENS = %w(when else elsif rescue) def initialize reset end # reset internal state def reset @stack = [] @indent_level = '' self end # Indents a string and returns it. This string can either be a single line # or multiple ones. # # @example # str = <