diff --git a/.gitignore b/.gitignore index d0b8649e..b4777dcf 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,8 @@ pkg/ coverage/ .yardoc/ /tags + +# Not sure if Pry devs use RVM or want the Gemfile.lock in the repo, thus I'm +# ignoring them for now. +.rvmrc +Gemfile.lock diff --git a/lib/pry.rb b/lib/pry.rb index d364b110..fcd6ef7d 100644 --- a/lib/pry.rb +++ b/lib/pry.rb @@ -191,3 +191,4 @@ require "pry/plugins" require "pry/core_extensions" require "pry/pry_class" require "pry/pry_instance" +require "pry/indent" diff --git a/lib/pry/config.rb b/lib/pry/config.rb index 37e236de..f5999214 100644 --- a/lib/pry/config.rb +++ b/lib/pry/config.rb @@ -126,6 +126,10 @@ class Pry # The proc is passed the pry output object, the command string # to eval, and a reference to the pry instance attr_accessor :system + + # @return [TrueClass|FalseClass] Whether or not code should be indented + # using Pry::Indent. + attr_accessor :indent end end diff --git a/lib/pry/indent.rb b/lib/pry/indent.rb new file mode 100644 index 00000000..2d33508a --- /dev/null +++ b/lib/pry/indent.rb @@ -0,0 +1,136 @@ +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 2 spaces. + # + # @author Yorick Peterse + # @since 04-10-2011 + # + class Indent + # Array containing all the indentation levels. + attr_reader :stack + + # The amount of spaces to insert for each indent level. + Spaces = ' '.freeze + + # Array containing all the tokens that should increase the indentation + # level. + OpenTokens = [ + 'def', + 'class', + 'module', + '[', + '{', + 'do', + 'if', + 'while', + 'for' + ] + + # Collection of tokens that decrease the indentation level. + ClosingTokens = ['end', ']', '}'] + + # 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. + IgnoreTokens = [:space, :content, :string, :delimiter] + + # Collection of tokens that should only increase the indentation level of + # the next line. + OpenTokensNext = ['else', 'elsif'] + + ## + # Creates a new instance of the class and starts with a fresh stack. The + # stack is used to keep track of the indentation level for each line of + # code. + # + # @author Yorick Peterse + # @since 05-10-2011 + # + def initialize + @stack = [] + end + + ## + # Indents a string and returns it. This string can either be a single line + # or multiple ones. + # + # @example + # str = <