Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #179 from vim-ruby/private-protected-indenting

Private/protected indenting
  • Loading branch information...
commit 2597860f4ee117d6d762d6caa98e73e89e41769b 2 parents 934f157 + b9fc8a2
@AndrewRadev AndrewRadev authored
View
58 doc/vim-ruby.txt
@@ -1,7 +1,9 @@
*vim-ruby.txt*
-1. Ruby motions |ruby-motion|
-2. Ruby text objects |ruby-text-objects|
+1. Ruby motions |ruby-motion|
+2. Ruby text objects |ruby-text-objects|
+3. Access modifier indentation |ruby-access-modifier-indentation|
+
==============================================================================
1. Ruby motions *ruby-motion*
@@ -58,4 +60,56 @@ aM "a class", select from "class" until matching "end"
iM "inner class", select contents of "class"/"end"
block, excluding the "class" and "end" themselves.
+==============================================================================
+3. Access modifier indentation *ruby-access-modifier-indentation*
+ *g:ruby_indent_access_modifier_style*
+
+Different access modifier indentation styles can be used by setting: >
+
+ :let g:ruby_indent_access_modifier_style = 'normal'
+ :let g:ruby_indent_access_modifier_style = 'indent'
+ :let g:ruby_indent_access_modifier_style = 'outdent'
+<
+By default, the "normal" access modifier style is used.
+
+Access modifier style "normal":
+>
+ class Indent
+ private :method
+ protected :method
+ private
+ def method; end
+ protected
+ def method; end
+ public
+ def method; end
+ end
+<
+Access modifier style "indent":
+>
+ class Indent
+ private :method
+ protected :method
+ private
+ def method; end
+ protected
+ def method; end
+ public
+ def method; end
+ end
+<
+Access modifier style "outdent":
+>
+ class Indent
+ private :method
+ protected :method
+ private
+ def method; end
+ protected
+ def method; end
+ public
+ def method; end
+ end
+<
+
vim:tw=78:sw=4:ts=8:ft=help:norl:
View
65 indent/ruby.vim
@@ -13,12 +13,18 @@ if exists("b:did_indent")
endif
let b:did_indent = 1
+if !exists('g:ruby_indent_access_modifier_style')
+ " Possible values: "normal", "indent", "outdent"
+ let g:ruby_indent_access_modifier_style = 'normal'
+endif
+
setlocal nosmartindent
" Now, set up our indentation expression and keys that trigger it.
setlocal indentexpr=GetRubyIndent(v:lnum)
-setlocal indentkeys=0{,0},0),0],!^F,o,O,e
+setlocal indentkeys=0{,0},0),0],!^F,o,O,e,:
setlocal indentkeys+==end,=else,=elsif,=when,=ensure,=rescue,==begin,==end
+setlocal indentkeys+==private,=protected,=public
" Only define the function once.
if exists("*GetRubyIndent")
@@ -92,6 +98,12 @@ let s:bracket_continuation_regex = '%\@<!\%([({[]\)\s*\%(#.*\)\=$'
" Regex that defines the first part of a splat pattern
let s:splat_regex = '[[,(]\s*\*\s*\%(#.*\)\=$'
+" Regex that describes all indent access modifiers
+let s:access_modifier_regex = '\C^\s*\%(private\|public\|protected\)\s*\%(#.*\)\=$'
+
+" Regex that describes the indent access modifiers (excludes public)
+let s:indent_access_modifier_regex = '\C^\s*\%(private\|protected\)\s*\%(#.*\)\=$'
+
" Regex that defines blocks.
"
" Note that there's a slight problem with this regex and s:continuation_regex.
@@ -315,6 +327,25 @@ function s:Match(lnum, regex)
endif
endfunction
+" Locates the containing class/module's definition line, ignoring nested classes
+" along the way.
+"
+function! s:FindContainingClass()
+ let saved_position = getpos('.')
+
+ while searchpair(s:end_start_regex, s:end_middle_regex, s:end_end_regex, 'bW',
+ \ s:end_skip_expr) > 0
+ if expand('<cword>') =~# '\<class\|module\>'
+ let found_lnum = line('.')
+ call setpos('.', saved_position)
+ return found_lnum
+ endif
+ endif
+
+ call setpos('.', saved_position)
+ return 0
+endfunction
+
" 3. GetRubyIndent Function {{{1
" =========================
@@ -335,6 +366,24 @@ function GetRubyIndent(...)
let line = getline(clnum)
let ind = -1
+ " If this line is an access modifier keyword, align according to the closest
+ " class declaration.
+ if g:ruby_indent_access_modifier_style == 'indent'
+ if s:Match(clnum, s:access_modifier_regex)
+ let class_line = s:FindContainingClass()
+ if class_line > 0
+ return indent(class_line) + &sw
+ endif
+ endif
+ elseif g:ruby_indent_access_modifier_style == 'outdent'
+ if s:Match(clnum, s:access_modifier_regex)
+ let class_line = s:FindContainingClass()
+ if class_line > 0
+ return indent(class_line)
+ endif
+ endif
+ endif
+
" If we got a closing bracket on an empty line, find its match and indent
" according to it. For parentheses we indent to its column - 1, for the
" others we indent to the containing line's MSL's level. Return -1 if fail.
@@ -411,6 +460,20 @@ function GetRubyIndent(...)
let line = getline(lnum)
let ind = indent(lnum)
+ if g:ruby_indent_access_modifier_style == 'indent'
+ " If the previous line was a private/protected keyword, add a
+ " level of indent.
+ if s:Match(lnum, s:indent_access_modifier_regex)
+ return indent(lnum) + &sw
+ endif
+ elseif g:ruby_indent_access_modifier_style == 'outdent'
+ " If the previous line was a private/protected/public keyword, add
+ " a level of indent, since the keyword has been out-dented.
+ if s:Match(lnum, s:access_modifier_regex)
+ return indent(lnum) + &sw
+ endif
+ endif
+
" If the previous line ended with a block opening, add a level of indent.
if s:Match(lnum, s:block_regex)
return indent(s:GetMSL(lnum)) + &sw
View
137 spec/indent/indent_access_modifier_spec.rb
@@ -0,0 +1,137 @@
+require 'spec_helper'
+
+describe "Indenting" do
+ after :each do
+ vim.command 'let g:ruby_indent_access_modifier_style = "normal"'
+ end
+
+ specify "default indented access modifiers" do
+ assert_correct_indenting <<-EOF
+ class OuterClass
+
+ private :method
+ protected :method
+ def method; end
+ protected
+ def method; end
+ private
+ def method; end
+ public
+ def method; end
+
+ class InnerClass
+
+ private :method
+ protected :method
+ def method; end
+ protected
+ def method; end
+ private
+ def method; end
+ public
+ def method; end
+
+ end
+
+ private :method
+ protected :method
+ def method; end
+ protected
+ def method; end
+ private
+ def method; end
+ public
+ def method; end
+
+ end
+ EOF
+ end
+
+ specify "indented access modifiers" do
+ vim.command 'let g:ruby_indent_access_modifier_style = "indent"'
+
+ assert_correct_indenting <<-EOF
+ class OuterClass
+
+ private :method
+ protected :method
+ def method; end
+ protected
+ def method; end
+ private
+ def method; end
+ public
+ def method; end
+
+ class InnerClass
+
+ private :method
+ protected :method
+ def method; end
+ protected
+ def method; end
+ private
+ def method; end
+ public
+ def method; end
+
+ end
+
+ private :method
+ protected :method
+ def method; end
+ protected
+ def method; end
+ private
+ def method; end
+ public
+ def method; end
+
+ end
+ EOF
+ end
+
+ specify "outdented access modifiers" do
+ vim.command 'let g:ruby_indent_access_modifier_style = "outdent"'
+
+ assert_correct_indenting <<-EOF
+ class OuterClass
+
+ private :method
+ protected :method
+ def method; end
+ protected
+ def method; end
+ private
+ def method; end
+ public
+ def method; end
+
+ class InnerClass
+
+ private :method
+ protected :method
+ def method; end
+ protected
+ def method; end
+ private
+ def method; end
+ public
+ def method; end
+
+ end
+
+ private :method
+ protected :method
+ def method; end
+ protected
+ def method; end
+ private
+ def method; end
+ public
+ def method; end
+
+ end
+ EOF
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.