require 'coderay' class Pry # Load io-console if possible, so that we can use $stdout.winsize. begin require 'io/console' rescue LoadError end ## # 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 include Helpers::BaseHelpers # @return [String] String containing the spaces to be inserted before the next line. attr_reader :indent_level # @return [Array] The stack of open tokens. attr_reader :stack # 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. # # :pre_constant and :preserved_constant are the CodeRay 0.9.8 and 1.0.0 # classifications of "true", "false", and "nil". IGNORE_TOKENS = [:space, :content, :string, :method, :ident, :constant, :pre_constant, :predefined_constant] # 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) # # :reserved and :keywords are the CodeRay 0.9.8 and 1.0.0 respectively # classifications of "super", "next", "return", etc. STATEMENT_END_TOKENS = IGNORE_TOKENS + [:regexp, :integer, :float, :keyword, :delimiter, :reserved] # Collection of tokens that should appear dedented even though they # don't affect the surrounding code. MIDWAY_TOKENS = %w(when else elsif ensure rescue) def initialize reset end # reset internal state def reset @stack = [] @indent_level = '' @heredoc_queue = [] @close_heredocs = {} @string_start = nil self end # Indents a string and returns it. This string can either be a single line # or multiple ones. # # @example # str = < 0 end end end end