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

Merge pull request #41 from blueyed/fix-jedi-call-signatures
authorDaniel Hahler <github@thequod.de>
Tue, 12 May 2015 16:24:52 +0000 (18:24 +0200)
committerDaniel Hahler <github@thequod.de>
Tue, 12 May 2015 16:24:52 +0000 (18:24 +0200)
Handle jedi-vim call signatures when looking for colon in prev line

.travis.yml
Gemfile
indent/python.vim
spec/indent/indent_spec.rb
spec/spec_helper.rb

index 1ee869df79882eff83264ca483e3a252404da335..e31bfcd670ed9428fab9d5d08caa4d503c36fd83 100644 (file)
@@ -6,4 +6,5 @@ before_script:
     - "export DISPLAY=:99.0"
     - "sh -e /etc/init.d/xvfb start"
     - "bundle install"
+    - "vim --version"
 script: bundle exec rspec
diff --git a/Gemfile b/Gemfile
index 7d08815c845b39fbc6fb975e9f5e92bd2c330aed..71f7701a9e70566e4189bf49d9785cfe86d5c5f6 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,3 +1,3 @@
 source 'https://rubygems.org'
-gem "vimrunner", "0.3.0"
+gem "vimrunner", "0.3.1"
 gem "rspec"
index 007c7e160ea0810803a8086de4f289fe497c0b00..a1dd43fb7511d264dee45ff186d7f5b0fac1a0b1 100644 (file)
@@ -43,9 +43,25 @@ let s:paren_pairs = ['()', '{}', '[]']
 let s:control_statement = '^\s*\(class\|def\|if\|while\|with\|for\|except\)\>'
 let s:stop_statement = '^\s*\(break\|continue\|raise\|return\|pass\)\>'
 
-" Skip strings and comments
+" Skip strings and comments. Return 1 for chars to skip.
+" jedi* refers to syntax definitions from jedi-vim for call signatures, which
+" are inserted temporarily into the buffer.
 let s:skip_special_chars = 'synIDattr(synID(line("."), col("."), 0), "name") ' .
-            \ '=~? "string\\|comment"'
+            \ '=~? "\\vstring|comment|jedi\\S"'
+
+let s:skip_after_opening_paren = 'synIDattr(synID(line("."), col("."), 0), "name") ' .
+            \ '=~? "\\vcomment|jedi\\S"'
+
+" Also ignore anything concealed.
+" Wrapper around synconcealed for older Vim (7.3.429, used on Travis CI).
+function! s:is_concealed(line, col)
+    let concealed = synconcealed(a:line, a:col)
+    return len(concealed) && concealed[0]
+endfunction
+if has('conceal')
+    let s:skip_special_chars .= '|| s:is_concealed(line("."), col("."))'
+endif
+
 
 let s:skip_search = 'synIDattr(synID(line("."), col("."), 0), "name") ' .
             \ '=~? "comment"'
@@ -134,6 +150,27 @@ function! s:find_start_of_block(lnum, types)
     return 0
 endfunction
 
+" Is "expr" true for every position in "lnum", beginning at "start"?
+" (optionally up to a:1 / 4th argument)
+function! s:match_expr_on_line(expr, lnum, start, ...)
+    let text = getline(a:lnum)
+    let end = a:0 ? a:1 : len(text)
+    if a:start > end
+        return 1
+    endif
+    let save_pos = getpos('.')
+    let r = 1
+    for i in range(a:start, end)
+        call cursor(a:lnum, i)
+        if !(eval(a:expr) || text[i-1] =~ '\s')
+            let r = 0
+            break
+        endif
+    endfor
+    call setpos('.', save_pos)
+    return r
+endfunction
+
 " Line up with open parenthesis/bracket/brace.
 function! s:indent_like_opening_paren(lnum)
     let [paren_lnum, paren_col] = s:find_opening_paren(a:lnum)
@@ -143,7 +180,8 @@ function! s:indent_like_opening_paren(lnum)
     let text = getline(paren_lnum)
     let base = indent(paren_lnum)
 
-    let nothing_after_opening_paren = text =~ '\%'.(paren_col + 1).'c\s*$'
+    let nothing_after_opening_paren = s:match_expr_on_line(
+                \ s:skip_after_opening_paren, paren_lnum, paren_col+1)
     let starts_with_closing_paren = getline(a:lnum) =~ '^\s*[])}]'
 
     if nothing_after_opening_paren
@@ -204,13 +242,18 @@ function! s:indent_like_previous_line(lnum)
     call cursor(lnum, len(text))
     let ignore_last_char = eval(s:skip_special_chars)
 
-    " Search for final colon that is not inside a string or comment.
-    while search(':\s*\%(#.*\)\?$', 'bcW', lnum)
-      if eval(s:skip_special_chars)
+    " Search for final colon that is not inside something to be ignored.
+    while search(':', 'bcW', lnum)
+        let curpos = getpos(".")[2]
+        if curpos == 1 | break | endif
+        if eval(s:skip_special_chars)
+            normal! h
+            continue
+        endif
+        if !s:match_expr_on_line(s:skip_special_chars, lnum, curpos)
+            return base + s:sw()
+        endif
         normal! h
-      else
-        return base + s:sw()
-      endif
     endwhile
 
     if text =~ '\\$' && !ignore_last_char
index cd37f1f2fd0c688ae81af3b48e3ee2cde372059b..1999d27057fd1c1744ad8598602d026ced6e3f92 100644 (file)
@@ -76,6 +76,21 @@ shared_examples_for "vim" do
     end
   end
 
+  describe "when after an '{' that is followed by a comment" do
+    before { vim.feedkeys 'imydict = {  # comment\<CR>' }
+
+    it "indent by one level" do
+      indent.should == shiftwidth
+      vim.feedkeys '1: 1,\<CR>'
+      indent.should == shiftwidth
+    end
+
+    it "lines up the closing parenthesis" do
+      vim.feedkeys '}'
+      indent.should == 0
+    end
+  end
+
   describe "when using gq to reindent a '(' that is" do
     before { vim.feedkeys 'itest(' }
     it "something and has a string without spaces at the end" do
@@ -129,6 +144,15 @@ shared_examples_for "vim" do
     end
   end
 
+  describe "when the previous line has a colon in a string" do
+    before { vim.feedkeys 'itest(":".join(["1","2"]))\<CR>' }
+    it "does not indent" do
+      vim.feedkeys 'if True:'
+      indent.should == 0
+      proposed_indent.should == 0
+    end
+  end
+
   describe "when after an '(' that is followed by an unfinished string" do
     before { vim.feedkeys 'itest("""' }
 
@@ -374,6 +398,20 @@ shared_examples_for "vim" do
      end
   end
 
+  describe "when jedi-vim call signatures are used" do
+    before { vim.command 'syn match jediFunction "JEDI_CALL_SIGNATURE" keepend extend' }
+
+    it "ignores the call signature after a colon" do
+      vim.feedkeys 'iif True:  JEDI_CALL_SIGNATURE\<CR>'
+      indent.should == shiftwidth
+    end
+
+    it "ignores the call signature after a function" do
+      vim.feedkeys 'idef f(  JEDI_CALL_SIGNATURE\<CR>'
+      indent.should == shiftwidth * 2
+    end
+  end
+
   def shiftwidth
     @shiftwidth ||= vim.echo("exists('*shiftwidth') ? shiftwidth() : &sw").to_i
   end
index 022f65bdc8a46d65138d797aaf867eb8f8f2d654..82b152cd0cc49bd65300c830270cd2ab25cae940 100644 (file)
@@ -2,8 +2,13 @@ require 'vimrunner'
 require 'vimrunner/rspec'
 
 Vimrunner::RSpec.configure do |config|
+  # Use a single Vim instance for the test suite. Set to false to use an
+  # instance per test (slower, but can be easier to manage).
   # FIXME: reuse_server = true seems to hang after a certain number of test cases
-  config.reuse_server = false
+  #  - Travis CI hangs after 15 successful tests.
+  #  - Locally it may hang also, with Vim and Xorg using 100% CPU.
+  # Therefore default to false in both cases.
+  config.reuse_server = ENV['CI'] ? false : false
 
   config.start_vim do
     vim = Vimrunner.start