]> 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:

prevent ':' from indenting inside unfinished string
authorJohann Klähn <kljohann@gmail.com>
Tue, 7 Jan 2014 16:28:46 +0000 (17:28 +0100)
committerJohann Klähn <kljohann@gmail.com>
Tue, 7 Jan 2014 18:10:50 +0000 (19:10 +0100)
indent/python.vim
spec/indent/indent_spec.rb
spec/spec_helper.rb

index 9b8e9b187bf96182e10097fcad61e59176520c2e..d86eabbcbb667f1e88a26a71177cb2ec17070afa 100644 (file)
@@ -27,11 +27,10 @@ let s:block_rules = {
 let s:paren_pairs = ['()', '{}', '[]']
 let s:control_statement = '^\s*\(if\|while\|with\|for\|except\)\>'
 let s:stop_statement = '^\s*\(break\|continue\|raise\|return\|pass\)\>'
-if v:version >= 704 || (v:version == 703 && has('patch1037'))
-  let s:string_literal = '".\{-}\\\@1<!"\|''.\{-}\\\@1<!'''
-else
-  let s:string_literal = '".\{-}\\\@<!"\|''.\{-}\\\@<!'''
-endif
+
+" Skip strings and comments
+let s:skip = 'synIDattr(synID(line("."), col("."), 0), "name") ' .
+           \ '=~? "string\\|comment"'
 
 " compatibility with vim patch 7.3.629: 'sw' can be set to -1 to follow 'ts'
 if exists('*shiftwidth')
@@ -65,16 +64,13 @@ function! s:find_opening_paren(...)
 
     let stopline = max([0, line('.') - s:maxoff])
 
-    " Skip strings and comments
-    let skip = 'synIDattr(synID(line("."), col("."), 0), "name") ' .
-             \ '=~? "string\\|comment"'
-
     " Return if cursor is in a comment or string
-    exe 'if' skip '| return [0, 0] | endif'
+    exe 'if' s:skip '| return [0, 0] | endif'
 
     let positions = []
     for p in s:paren_pairs
-        call add(positions, searchpairpos('\V'.p[0], '', '\V'.p[1], 'bnW', skip, stopline))
+        call add(positions, searchpairpos(
+           \ '\V'.p[0], '', '\V'.p[1], 'bnW', s:skip, stopline))
     endfor
 
     " Remove empty matches and return the type with the closest match
@@ -174,21 +170,30 @@ endfunction
 
 function! s:indent_like_previous_line(lnum)
     let lnum = prevnonblank(a:lnum - 1)
+
+    " No previous line, keep current indent.
+    if lnum < 1
+      return -1
+    endif
+
     let text = getline(lnum)
     let start = s:find_start_of_multiline_statement(lnum)
     let base = indent(start)
 
-    " Remove string literals.
-    let text = substitute(text, s:string_literal, '', 'g')
+    " Jump to last character in previous line.
+    call cursor(lnum, len(text))
+    let ignore_last_char = eval(s:skip)
 
-    " If the previous line ended with a colon and is not a comment, indent
-    " relative to statement start.
-    if text =~ '^[^#]*:\s*\(#.*\)\?$'
+    " Search for final colon that is not inside a string or comment.
+    while search(':\s*\%(#.*\)\?$', 'bcW', lnum)
+      if eval(s:skip)
+        normal! h
+      else
         return base + s:sw()
-    endif
-
+      endif
+    endwhile
 
-    if text =~ '\\$'
+    if text =~ '\\$' && !ignore_last_char
         " If this line is the continuation of a control statement
         " indent further to distinguish the continuation line
         " from the next logical line.
index 9fa034dc7879eb6f712deec2da9382a5f1527c4c..cd79e3681d2b12193cd5d533ca1994d8ec00f30d 100644 (file)
@@ -102,6 +102,25 @@ shared_examples_for "vim" do
     end
   end
 
+  describe "when inside an unfinished string" do
+    it "does not indent" do
+      vim.feedkeys 'i"test:\<ESC>'
+      vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
+              ).downcase.should include 'string'
+      vim.feedkeys 'a\<CR>'
+      proposed_indent.should == 0
+      indent.should == 0
+    end
+
+    it "does not dedent" do
+      vim.feedkeys 'iif True:\<CR>"test:\<ESC>'
+      vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
+              ).downcase.should include 'string'
+      proposed_indent.should == shiftwidth
+      indent.should == shiftwidth
+    end
+  end
+
   describe "when using simple control structures" do
       it "indents shiftwidth spaces" do
           vim.feedkeys 'iwhile True:\<CR>pass'
index b1e82a123e7bdbb3a2665ffc4ea69feb17bcf276..022f65bdc8a46d65138d797aaf867eb8f8f2d654 100644 (file)
@@ -14,6 +14,7 @@ Vimrunner::RSpec.configure do |config|
     # vim.add_plugin(plugin_path, 'indent/python.vim')
 
     vim.command "set rtp^=#{plugin_path}"
+    vim.command "runtime syntax/python.vim"
     vim.command "runtime indent/python.vim"
 
     vim