]> git.madduck.net Git - etc/vim.git/commitdiff

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Fix keeping indent with 'else' for 'if' after 'try-except' (#52)
authorDaniel Hahler <github@thequod.de>
Mon, 4 Jul 2016 04:32:30 +0000 (06:32 +0200)
committerHynek Schlawack <hs@ox.cx>
Mon, 4 Jul 2016 04:32:30 +0000 (06:32 +0200)
Fixes https://github.com/hynek/vim-python-pep8-indent/issues/47.

indent/python.vim
spec/indent/indent_spec.rb

index 5c701e479bcd437d6c0fe31f34642a1c8aec83dc..7bbc41510e55a8868eaaa07eb7c48a4aa9fc678b 100644 (file)
@@ -35,10 +35,12 @@ setlocal shiftwidth=4
 let s:maxoff = 50
 let s:block_rules = {
             \ '^\s*elif\>': ['if', 'elif'],
-            \ '^\s*else\>': ['if', 'elif', 'for', 'try', 'except'],
             \ '^\s*except\>': ['try', 'except'],
             \ '^\s*finally\>': ['try', 'except', 'else']
             \ }
+let s:block_rules_multiple = {
+            \ '^\s*else\>': ['if', 'elif', 'for', 'try', 'except'],
+            \ }
 let s:paren_pairs = ['()', '{}', '[]']
 if &ft == 'pyrex' || &ft == 'cython'
     let b:control_statement = '\v^\s*(class|def|if|while|with|for|except|cdef|cpdef)>'
@@ -136,22 +138,28 @@ function! s:find_start_of_multiline_statement(lnum)
     endwhile
 endfunction
 
-" Find the block starter that matches the current line
-function! s:find_start_of_block(lnum, types)
+" Find possible indent(s) of the block starter that matches the current line.
+function! s:find_start_of_block(lnum, types, multiple)
+    let r = []
     let re = '\V\^\s\*\('.join(a:types, '\|').'\)\>'
-
     let lnum = a:lnum
     let last_indent = indent(lnum) + 1
     while lnum > 0 && last_indent > 0
-        if indent(lnum) < last_indent
+        let indent = indent(lnum)
+        if indent < last_indent
             if getline(lnum) =~# re
-                return lnum
+                if !a:multiple
+                    return [indent]
+                endif
+                if !len(r) || index(r, indent) == -1
+                    let r += [indent]
+                endif
             endif
             let last_indent = indent(lnum)
         endif
         let lnum = prevnonblank(lnum - 1)
     endwhile
-    return 0
+    return r
 endfunction
 
 " Is "expr" true for every position in "lnum", beginning at "start"?
@@ -212,20 +220,31 @@ endfunction
 " Match indent of first block of this type.
 function! s:indent_like_block(lnum)
     let text = getline(a:lnum)
+    for [multiple, block_rules] in [
+                \ [0, s:block_rules],
+                \ [1, s:block_rules_multiple]]
+        for [line_re, blocks] in items(block_rules)
+            if text !~# line_re
+                continue
+            endif
 
-    for [line_re, blocks] in items(s:block_rules)
-        if text !~# line_re
-            continue
-        endif
-
-        let lnum = s:find_start_of_block(a:lnum - 1, blocks)
-        if lnum > 0
-            return indent(lnum)
-        else
-            return -1
-        endif
+            let indents = s:find_start_of_block(a:lnum - 1, blocks, multiple)
+            if !len(indents)
+                return -1
+            endif
+            if len(indents) == 1
+                return indents[0]
+            endif
+            " Multiple valid indents, e.g. for 'else' with both try and if.
+            let indent = indent(a:lnum)
+            for possible_indent in indents
+                if indent == possible_indent
+                    return indent
+                endif
+            endfor
+            return -2
+        endfor
     endfor
-
     return -2
 endfunction
 
index e43e799b39c6ccbfb486c7d6ac67867dbaab9785..5c9838aab2404e3475e77edf6c2e2fa6c6faa030 100644 (file)
@@ -353,6 +353,23 @@ shared_examples_for "vim" do
      end
   end
 
+  describe "when an 'if' contains a try-except" do
+     before {
+       vim.feedkeys 'iif x:\<CR>try:\<CR>pass\<CR>except:\<CR>pass\<CR>'
+       indent.should == shiftwidth
+     }
+     it "an 'else' should be indented to the try" do
+       vim.feedkeys 'else:'
+       indent.should == shiftwidth
+       proposed_indent.should == shiftwidth
+     end
+     it "an 'else' should keep the indent of the 'if'" do
+       vim.feedkeys 'else:\<ESC><<'
+       indent.should == 0
+       proposed_indent.should == 0
+     end
+  end
+
   describe "when a 'for' is followed by" do
      before { vim.feedkeys 'i\<TAB>\<TAB>for x in y:\<CR>' }
      it "an 'else', it lines up with the 'for'" do