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.
3 shared_examples_for "vim" do
9 # Insert two blank lines.
10 # The first line is a corner case in this plugin that would shadow the
11 # correct behaviour of other tests. Thus we explicitly jump to the first
12 # line when we require so.
13 vim.feedkeys 'i\<CR>\<CR>\<ESC>'
16 describe "when using the indent plugin" do
17 it "sets the indentexpr and indentkeys options" do
18 vim.command("set indentexpr?").should include "GetPythonPEPIndent("
19 vim.command("set indentkeys?").should include "=elif"
22 it "sets autoindent and expandtab" do
23 vim.command("set autoindent?").should match(/\s*autoindent/)
24 vim.command("set expandtab?").should match(/\s*expandtab/)
28 describe "when entering the first line" do
29 before { vim.feedkeys '0ggipass' }
31 it "does not indent" do
33 proposed_indent.should == 0
36 it "does not indent when using '=='" do
42 describe "when after a '(' that is at the end of its line" do
43 before { vim.feedkeys 'itest(\<CR>' }
45 it "indents by one level" do
46 proposed_indent.should == shiftwidth
47 vim.feedkeys 'something'
48 indent.should == shiftwidth
50 indent.should == shiftwidth
53 it "puts the closing parenthesis at the same level" do
55 indent.should == (hang_closing ? shiftwidth : 0)
59 describe "when after an '(' that is followed by something" do
60 before { vim.feedkeys 'itest(something,\<CR>' }
62 it "lines up on following lines" do
64 vim.feedkeys 'more,\<CR>'
68 it "lines up the closing parenthesis" do
73 it "does not touch the closing parenthesis if it is already indented further" do
79 describe "when after an '{' that is followed by a comment" do
80 before { vim.feedkeys 'imydict = { # comment\<CR>' }
82 it "indent by one level" do
83 indent.should == shiftwidth
84 vim.feedkeys '1: 1,\<CR>'
85 indent.should == shiftwidth
88 it "lines up the closing parenthesis" do
90 indent.should == (hang_closing ? shiftwidth : 0)
94 describe "when using gq to reindent a '(' that is" do
95 before { vim.feedkeys 'itest(' }
96 it "something and has a string without spaces at the end" do
97 vim.feedkeys 'something_very_long_blaaaaaaaaa, "some_very_long_string_blaaaaaaaaaaaaaaaaaaaa"\<esc>gqq'
102 describe "when after multiple parens of different types" do
103 it "indents by one level" do
104 vim.feedkeys 'if({\<CR>'
105 indent.should == shiftwidth
108 it "lines up with the last paren" do
109 vim.feedkeys 'ifff({123: 456,\<CR>'
114 describe "when '#' is contained in a string that is followed by a colon" do
115 it "indents by one level" do
116 vim.feedkeys 'iif "some#thing" == "test":#test\<CR>pass'
117 indent.should == shiftwidth
121 describe "when '#' is not contained in a string and is followed by a colon" do
122 it "does not indent" do
123 vim.feedkeys 'iif "some#thing" == "test"#:test\<CR>'
128 describe "when inside an unfinished string" do
129 it "does not indent" do
130 vim.feedkeys 'i"test:\<ESC>'
131 vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
132 ).downcase.should include 'string'
133 vim.feedkeys 'a\<CR>'
134 proposed_indent.should == 0
138 it "does not dedent" do
139 vim.feedkeys 'iif True:\<CR>"test:\<ESC>'
140 vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
141 ).downcase.should include 'string'
142 proposed_indent.should == shiftwidth
143 indent.should == shiftwidth
147 describe "when the previous line has a colon in a string" do
148 before { vim.feedkeys 'itest(":".join(["1","2"]))\<CR>' }
149 it "does not indent" do
150 vim.feedkeys 'if True:'
152 proposed_indent.should == 0
156 describe "when the previous line has a list slice" do
157 it "does not indent" do
158 vim.feedkeys 'ib = a[2:]\<CR>'
160 proposed_indent.should == 0
164 describe "when line is empty inside a block" do
165 it "is indented like the previous line" do
166 vim.feedkeys 'idef a():\<CR>1\<CR>\<CR>2\<ESC>kcc'
167 indent.should == shiftwidth
171 describe "when an empty line is after empty line / before non-empty" do
172 it "is indented like the next line" do
173 vim.feedkeys 'idef a():\<CR>1\<CR>\<CR>\<CR>2\<ESC><<kcc'
178 describe "when an empty line is after empty line / before non-empty (nested)" do
179 it "is indented like the next line" do
180 vim.feedkeys 'idef a():\<CR>1\<CR>\<CR>\<CR>\<ESC>0i\<TAB>2\<ESC>kcc'
181 indent.should == shiftwidth
185 describe "when line is empty inside a block following multi-line statement" do
186 it "is indented like the previous line" do
187 vim.feedkeys 'idef a():\<CR>x = (1 +\<CR>2)\<CR>\<CR>y\<ESC>kcc'
188 indent.should == shiftwidth
192 describe "when line is empty inside a block following stop statement" do
193 it "is indented like the previous line minus shiftwidth" do
194 vim.feedkeys 'iif x:\<CR>if y:\<CR>pass\<CR>\<CR>z\<ESC>kcc'
195 indent.should == shiftwidth
199 describe "when using simple control structures" do
200 it "indents shiftwidth spaces" do
201 vim.feedkeys 'iwhile True:\<CR>pass'
202 indent.should == shiftwidth
206 describe "when using a function definition" do
207 it "indents shiftwidth spaces" do
208 vim.feedkeys 'idef long_function_name(\<CR>arg'
209 indent.should == shiftwidth * 2
213 describe "when using a class definition" do
214 it "indents shiftwidth spaces" do
215 vim.feedkeys 'iclass Foo(\<CR>'
216 indent.should == shiftwidth * 2
220 describe "when writing an 'else' block" do
221 it "aligns to the preceeding 'for' block" do
222 vim.feedkeys 'ifor x in "abc":\<CR>pass\<CR>else:'
226 it "aligns to the preceeding 'if' block" do
227 vim.feedkeys 'ifor x in "abc":\<CR>if True:\<CR>pass\<CR>else:'
228 indent.should == shiftwidth
232 describe "when using parens and control statements" do
233 it "avoids ambiguity by using extra indentation" do
234 vim.feedkeys 'iif (111 and\<CR>'
236 indent.should == shiftwidth * 2
240 vim.feedkeys '222):\<CR>'
241 indent.should == shiftwidth
242 vim.feedkeys 'pass\<CR>'
246 it "still aligns parens properly if not ambiguous" do
247 vim.feedkeys 'iwhile (111 and\<CR>'
249 vim.feedkeys '222):\<CR>'
250 indent.should == shiftwidth
251 vim.feedkeys 'pass\<CR>'
255 it "still handles multiple parens correctly" do
256 vim.feedkeys 'iif (111 and (222 and 333\<CR>'
258 vim.feedkeys 'and 444\<CR>'
260 vim.feedkeys ')\<CR>'
262 indent.should == shiftwidth * 2
266 vim.feedkeys 'and 555):\<CR>'
267 indent.should == shiftwidth
268 vim.feedkeys 'pass\<CR>'
273 describe "when a line breaks with a manual '\\'" do
274 it "indents shiftwidth spaces on normal line" do
275 vim.feedkeys 'ivalue = test + \\\\\<CR>'
276 indent.should == shiftwidth
279 it "indents 2x shiftwidth spaces for control structures" do
280 vim.feedkeys 'iif somevalue == xyz and \\\\\<CR>'
281 indent.should == shiftwidth * 2
284 it "indents relative to line above" do
285 vim.feedkeys 'i\<TAB>value = test + \\\\\<CR>'
286 indent.should == shiftwidth * 2
290 describe "when current line is dedented compared to previous line" do
291 before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<ESC>' }
292 it "and current line has a valid indentation (Part 1)" do
293 vim.feedkeys '0i\<TAB>if y:'
294 proposed_indent.should == -1
297 it "and current line has a valid indentation (Part 2)" do
298 vim.feedkeys '0i\<TAB>\<TAB>if y:'
299 proposed_indent.should == -1
302 it "and current line has an invalid indentation" do
303 vim.feedkeys 'i while True:\<CR>'
304 indent.should == previous_indent + shiftwidth
308 describe "when current line is dedented compared to the last non-empty line" do
309 before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<CR>\<ESC>' }
310 it "and current line has a valid indentation" do
311 vim.feedkeys '0i\<TAB>if y:'
312 proposed_indent.should == -1
316 describe "when an 'if' is followed by" do
317 before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>' }
318 it "an elif, it lines up with the 'if'" do
319 vim.feedkeys 'elif y:'
320 indent.should == shiftwidth * 2
323 it "an 'else', it lines up with the 'if'" do
325 indent.should == shiftwidth * 2
329 describe "when an 'if' contains a try-except" do
331 vim.feedkeys 'iif x:\<CR>try:\<CR>pass\<CR>except:\<CR>pass\<CR>'
332 indent.should == shiftwidth
334 it "an 'else' should be indented to the try" do
336 indent.should == shiftwidth
337 proposed_indent.should == shiftwidth
339 it "an 'else' should keep the indent of the 'if'" do
340 vim.feedkeys 'else:\<ESC><<'
342 proposed_indent.should == 0
346 describe "when a 'for' is followed by" do
347 before { vim.feedkeys 'i\<TAB>\<TAB>for x in y:\<CR>' }
348 it "an 'else', it lines up with the 'for'" do
350 indent.should == shiftwidth * 2
354 describe "when an 'else' is followed by" do
355 before { vim.feedkeys 'i\<TAB>\<TAB>else:\<CR>XXX\<CR>' }
356 it "a 'finally', it lines up with the 'else'" do
357 vim.feedkeys 'finally:'
358 indent.should == shiftwidth * 2
363 describe "when a 'try' is followed by" do
364 before { vim.feedkeys 'i\<TAB>\<TAB>try:\<CR>' }
365 it "an 'except', it lines up with the 'try'" do
366 vim.feedkeys 'except:'
367 indent.should == shiftwidth * 2
370 it "an 'else', it lines up with the 'try'" do
372 indent.should == shiftwidth * 2
375 it "a 'finally', it lines up with the 'try'" do
376 vim.feedkeys 'finally:'
377 indent.should == shiftwidth * 2
381 describe "when an 'except' is followed by" do
382 before { vim.feedkeys 'i\<TAB>\<TAB>except:\<CR>' }
383 it "an 'else', it lines up with the 'except'" do
385 indent.should == shiftwidth * 2
388 it "another 'except', it lines up with the previous 'except'" do
389 vim.feedkeys 'except:'
390 indent.should == shiftwidth * 2
393 it "a 'finally', it lines up with the 'except'" do
394 vim.feedkeys 'finally:'
395 indent.should == shiftwidth * 2
399 describe "when an else is used inside of a nested if" do
400 before { vim.feedkeys 'iif foo:\<CR>\<TAB>if bar:\<CR>\<TAB>\<TAB>pass\<CR>' }
401 it "indents an else to the inner if" do
403 indent.should == shiftwidth * 2
407 describe "when jedi-vim call signatures are used" do
408 before { vim.command 'syn match jediFunction "JEDI_CALL_SIGNATURE" keepend extend' }
410 it "ignores the call signature after a colon" do
411 vim.feedkeys 'iif True: JEDI_CALL_SIGNATURE\<CR>'
412 indent.should == shiftwidth
415 it "ignores the call signature after a function" do
416 vim.feedkeys 'idef f( JEDI_CALL_SIGNATURE\<CR>'
417 indent.should == shiftwidth * 2
422 shared_examples_for "multiline strings" do
427 # Insert two blank lines.
428 # The first line is a corner case in this plugin that would shadow the
429 # correct behaviour of other tests. Thus we explicitly jump to the first
430 # line when we require so.
431 vim.feedkeys 'i\<CR>\<CR>\<ESC>'
434 describe "when after an '(' that is followed by an unfinished string" do
435 before { vim.feedkeys 'itest("""' }
437 it "it indents the next line" do
439 expected_proposed, expected_indent = multiline_indent(0, shiftwidth)
440 proposed_indent.should == expected_proposed
441 indent.should == expected_indent
444 it "with contents it indents the second line to the parenthesis" do
445 vim.feedkeys 'second line\<CR>'
446 expected_proposed, expected_indent = multiline_indent(0, 5)
447 proposed_indent.should == expected_proposed
448 indent.should == expected_indent
452 describe "when after assigning an unfinished string" do
453 before { vim.feedkeys 'itest = """' }
455 it "it indents the next line" do
457 expected_proposed, expected_indent = multiline_indent(0, shiftwidth)
458 proposed_indent.should == expected_proposed
459 indent.should == expected_indent
463 describe "when after assigning an unfinished string" do
464 before { vim.feedkeys 'i test = """' }
466 it "it indents the next line" do
468 expected_proposed, expected_indent = multiline_indent(4, shiftwidth + 4)
469 proposed_indent.should == expected_proposed
470 indent.should == expected_indent
474 describe "when after assigning a finished string" do
475 before { vim.feedkeys 'i test = ""' }
477 it "it does indent the next line" do
482 it "and writing a new string, it does indent the next line" do
483 vim.feedkeys '\<CR>""'
488 describe "when after a docstring" do
489 before { vim.feedkeys 'i """' }
490 it "it does indent the next line to the docstring" do
493 proposed_indent.should == 4
497 describe "when after a docstring with contents" do
498 before { vim.feedkeys 'i """First line' }
499 it "it does indent the next line to the docstring" do
502 proposed_indent.should == 4
506 describe "when breaking a string after opening parenthesis" do
507 before { vim.feedkeys 'i foo("""bar<Left><Left><Left>' }
508 it "it does indent the next line as after an opening multistring" do
510 expected_proposed, expected_indent = multiline_indent(4, 4 + shiftwidth)
511 indent.should == expected_indent
512 proposed_indent.should == expected_proposed
517 SUITE_SHIFTWIDTHS = [4, 3]
518 SUITE_HANG_CLOSINGS = [nil, false, true]
520 SUITE_SHIFTWIDTHS.each do |sw|
521 describe "vim when using width of #{sw}" do
523 vim.command("set sw=#{sw} ts=#{sw} sts=#{sw} et")
525 it "sets shiftwidth to #{sw}" do
526 shiftwidth.should == sw
529 SUITE_HANG_CLOSINGS.each do |hc|
530 describe "vim when hang_closing is set to #{hc}" do
534 it "sets hang_closing to #{hc}" do
535 hang_closing.should == !!hc
538 it_behaves_like "vim"
544 describe "vim when not using python_pep8_indent_multiline_string" do
546 vim.command("set sw=4 ts=4 sts=4 et")
547 vim.command("unlet! g:python_pep8_indent_multiline_string")
549 it_behaves_like "multiline strings"
552 describe "vim when using python_pep8_indent_multiline_first=0" do
554 vim.command("set sw=4 ts=4 sts=4 et")
555 vim.command("let g:python_pep8_indent_multiline_string=0")
557 it_behaves_like "multiline strings"
560 describe "vim when using python_pep8_indent_multiline_string=-1" do
562 vim.command("set sw=4 ts=4 sts=4 et")
563 vim.command("let g:python_pep8_indent_multiline_string=-1")
565 it_behaves_like "multiline strings"
568 describe "vim when using python_pep8_indent_multiline_string=-2" do
570 vim.command("set sw=4 ts=4 sts=4 et")
571 vim.command("let g:python_pep8_indent_multiline_string=-2")
573 it_behaves_like "multiline strings"
576 describe "vim for cython" do
579 vim.command "set ft=cython"
580 vim.command "runtime indent/python.vim"
582 # Insert two blank lines.
583 # The first line is a corner case in this plugin that would shadow the
584 # correct behaviour of other tests. Thus we explicitly jump to the first
585 # line when we require so.
586 vim.feedkeys 'i\<CR>\<CR>\<ESC>'
589 describe "when using a cdef function definition" do
590 it "indents shiftwidth spaces" do
591 vim.feedkeys 'icdef long_function_name(\<CR>arg'
592 indent.should == shiftwidth * 2
596 describe "when using a cpdef function definition" do
597 it "indents shiftwidth spaces" do
598 vim.feedkeys 'icpdef long_function_name(\<CR>arg'
599 indent.should == shiftwidth * 2
604 describe "Handles far away opening parens" do
605 before { vim.feedkeys '\<ESC>ggdGifrom foo import (' }
607 it "indents by one level" do
609 proposed_indent.should == shiftwidth
612 it "indents by one level for 10 lines" do
613 vim.command('set paste | exe "norm 9o" | set nopaste')
614 vim.feedkeys '\<Esc>o'
615 indent.should == shiftwidth
618 it "indents by one level for 50 lines" do
619 vim.command('set paste | exe "norm 49o" | set nopaste')
620 vim.feedkeys '\<Esc>o'
621 indent.should == shiftwidth
625 describe "Handles far away opening square brackets" do
626 before { vim.feedkeys '\<ESC>ggdGibar = [' }
628 it "indents by one level" do
630 proposed_indent.should == shiftwidth
633 it "indents by one level for 10 lines" do
634 vim.command('set paste | exe "norm 9o" | set nopaste')
635 vim.feedkeys '\<Esc>o'
636 indent.should == shiftwidth
639 it "indents by one level for 100 lines" do
640 vim.command('set paste | exe "norm 99o" | set nopaste')
641 vim.feedkeys '\<Esc>o'
642 indent.should == shiftwidth
646 describe "Handles far away opening curly brackets" do
647 before { vim.feedkeys '\<ESC>ggdGijson = {' }
649 it "indents by one level" do
651 vim.feedkeys '\<Esc>o'
652 proposed_indent.should == shiftwidth
655 it "indents by one level for 10 lines" do
656 vim.command('set paste | exe "norm 9o" | set nopaste')
657 vim.feedkeys '\<Esc>o'
658 indent.should == shiftwidth
661 it "indents by one level for 1000 lines" do
662 vim.command('set paste | exe "norm 999o" | set nopaste')
663 vim.feedkeys '\<Esc>o'
664 indent.should == shiftwidth
668 describe "Compact multiline dict" do
669 before { vim.feedkeys '\<ESC>ggdGid = {"one": 1,' }
671 it "gets indented correctly" do
673 proposed_indent.should == 5
675 vim.feedkeys '"two": 2}'
676 proposed_indent.should == 5
679 proposed_indent.should == 0