]> git.madduck.net Git - etc/vim.git/blob - spec/indent/indent_spec.rb

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:

55e2fba42debd58c112b670391dcf43cba755f5c
[etc/vim.git] / spec / indent / indent_spec.rb
1 require "spec_helper"
2
3 shared_examples_for "vim" do
4   before(:each) {
5     # clear buffer
6     vim.normal 'gg"_dG'
7
8     # Insert two blank lines.
9     # The first line is a corner case in this plugin that would shadow the
10     # correct behaviour of other tests. Thus we explicitly jump to the first
11     # line when we require so.
12     vim.feedkeys 'i\<CR>\<CR>\<ESC>'
13   }
14
15   describe "when using the indent plugin" do
16     it "sets the indentexpr and indentkeys options" do
17       vim.command("set indentexpr?").should include "GetPythonPEPIndent("
18       vim.command("set indentkeys?").should include "=elif"
19     end
20
21     it "sets autoindent and expandtab" do
22       vim.command("set autoindent?").should match(/\s*autoindent/)
23       vim.command("set expandtab?").should match(/\s*expandtab/)
24     end
25   end
26
27   describe "when entering the first line" do
28     before { vim.feedkeys '0ggipass' }
29
30     it "does not indent" do
31       indent.should == 0
32       proposed_indent.should == 0
33     end
34
35     it "does not indent when using '=='" do
36       vim.normal "=="
37       indent.should == 0
38     end
39   end
40
41   describe "when after a '(' that is at the end of its line" do
42     before { vim.feedkeys 'itest(\<CR>' }
43
44     it "indents by one level" do
45       proposed_indent.should == shiftwidth
46       vim.feedkeys 'something'
47       indent.should == shiftwidth
48       vim.normal '=='
49       indent.should == shiftwidth
50     end
51
52     it "puts the closing parenthesis at the same level" do
53       vim.feedkeys ')'
54       indent.should == (hang_closing ? shiftwidth : 0)
55     end
56   end
57
58   describe "when after an '(' that is followed by something" do
59     before { vim.feedkeys 'itest(something,\<CR>' }
60
61     it "lines up on following lines" do
62       indent.should == 5
63       vim.feedkeys 'more,\<CR>'
64       indent.should == 5
65     end
66
67     it "lines up the closing parenthesis" do
68       vim.feedkeys ')'
69       indent.should == 5
70     end
71
72     it "does not touch the closing parenthesis if it is already indented further" do
73       vim.feedkeys '  )'
74       indent.should == 7
75     end
76   end
77
78   describe "when after an '{' that is followed by a comment" do
79     before { vim.feedkeys 'imydict = {  # comment\<CR>' }
80
81     it "indent by one level" do
82       indent.should == shiftwidth
83       vim.feedkeys '1: 1,\<CR>'
84       indent.should == shiftwidth
85     end
86
87     it "lines up the closing parenthesis" do
88       vim.feedkeys '}'
89       indent.should == (hang_closing ? shiftwidth : 0)
90     end
91   end
92
93   describe "when using gq to reindent a '(' that is" do
94     before { vim.feedkeys 'itest(' }
95     it "something and has a string without spaces at the end" do
96       vim.feedkeys 'something_very_long_blaaaaaaaaa, "some_very_long_string_blaaaaaaaaaaaaaaaaaaaa"\<esc>gqq'
97       indent.should == 5
98     end
99   end
100
101   describe "when after multiple parens of different types" do
102     it "indents by one level" do
103       vim.feedkeys 'if({\<CR>'
104       indent.should == shiftwidth
105     end
106
107     it "lines up with the last paren" do
108       vim.feedkeys 'ifff({123: 456,\<CR>'
109       indent.should == 5
110     end
111   end
112
113   describe "when '#' is contained in a string that is followed by a colon" do
114     it "indents by one level" do
115         vim.feedkeys 'iif "some#thing" == "test":#test\<CR>pass'
116         indent.should == shiftwidth
117     end
118   end
119
120   describe "when '#' is not contained in a string and is followed by a colon" do
121     it "does not indent" do
122         vim.feedkeys 'iif "some#thing" == "test"#:test\<CR>'
123         indent.should == 0
124     end
125   end
126
127   describe "when inside an unfinished string" do
128     it "does not indent" do
129       vim.feedkeys 'i"test:\<ESC>'
130       vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
131               ).downcase.should include 'string'
132       vim.feedkeys 'a\<CR>'
133       proposed_indent.should == -1
134       indent.should == 0
135     end
136
137     it "does not dedent" do
138       vim.feedkeys 'iif True:\<CR>"test:\<ESC>'
139       vim.echo('synIDattr(synID(line("."), col("."), 0), "name")'
140               ).downcase.should include 'string'
141       proposed_indent.should == shiftwidth
142       indent.should == shiftwidth
143     end
144   end
145
146   describe "when the previous line has a colon in a string" do
147     before { vim.feedkeys 'itest(":".join(["1","2"]))\<CR>' }
148     it "does not indent" do
149       vim.feedkeys 'if True:'
150       indent.should == 0
151       proposed_indent.should == 0
152     end
153   end
154
155   describe "when the previous line has a list slice" do
156     it "does not indent" do
157       vim.feedkeys 'ib = a[2:]\<CR>'
158       indent.should == 0
159       proposed_indent.should == 0
160     end
161   end
162
163   describe "when line is empty inside a block" do
164     it "is indented like the previous line" do
165       vim.feedkeys 'idef a():\<CR>1\<CR>\<CR>2\<ESC>kcc'
166       indent.should == shiftwidth
167     end
168   end
169
170   describe "when an empty line is after empty line / before non-empty" do
171     it "is indented like the next line" do
172       vim.feedkeys 'idef a():\<CR>1\<CR>\<CR>\<CR>2\<ESC><<kcc'
173       indent.should == 0
174     end
175   end
176
177   describe "when an empty line is after empty line / before non-empty (nested)" do
178     it "is indented like the next line" do
179       vim.feedkeys 'idef a():\<CR>1\<CR>\<CR>\<CR>\<ESC>0i\<TAB>2\<ESC>kcc'
180       indent.should == shiftwidth
181     end
182   end
183
184   describe "when line is empty inside a block following multi-line statement" do
185     it "is indented like the previous line" do
186       vim.feedkeys 'idef a():\<CR>x = (1 +\<CR>2)\<CR>\<CR>y\<ESC>kcc'
187       indent.should == shiftwidth
188     end
189   end
190
191   describe "when line is empty inside a block following stop statement" do
192     it "is indented like the previous line minus shiftwidth" do
193       vim.feedkeys 'iif x:\<CR>if y:\<CR>pass\<CR>\<CR>z\<ESC>kcc'
194       indent.should == shiftwidth
195     end
196   end
197
198   describe "when using simple control structures" do
199       it "indents shiftwidth spaces" do
200           vim.feedkeys 'iwhile True:\<CR>pass'
201           indent.should == shiftwidth
202       end
203   end
204
205   describe "when using a function definition" do
206       it "handles indent with closing parenthesis on same line" do
207           vim.feedkeys 'idef long_function_name(\<CR>arg'
208           indent.should == shiftwidth
209           vim.feedkeys '):'
210           indent.should == shiftwidth * 2
211       end
212
213       it "handles indent with closing parenthesis on new line" do
214           vim.feedkeys 'idef long_function_name(\<CR>arg'
215           indent.should == shiftwidth
216           vim.feedkeys '\<CR>'
217           indent.should == shiftwidth
218           vim.feedkeys ')'
219           indent.should == (hang_closing ? shiftwidth * 2 : 0)
220           vim.feedkeys ':'
221           indent.should == (hang_closing ? shiftwidth * 2 : 0)
222           vim.feedkeys '\<Esc>k'
223           indent.should == shiftwidth
224       end
225   end
226
227   describe "when using a class definition" do
228       it "indents shiftwidth spaces" do
229           vim.feedkeys 'iclass Foo(\<CR>'
230           indent.should == shiftwidth
231       end
232   end
233
234   describe "when writing an 'else' block" do
235     it "aligns to the preceeding 'for' block" do
236       vim.feedkeys 'ifor x in "abc":\<CR>pass\<CR>else:'
237       indent.should == 0
238     end
239
240     it "aligns to the preceeding 'if' block" do
241       vim.feedkeys 'ifor x in "abc":\<CR>if True:\<CR>pass\<CR>else:'
242       indent.should == shiftwidth
243     end
244   end
245
246   describe "when using parens and control statements" do
247     it "avoids ambiguity by using extra indentation" do
248       vim.feedkeys 'iif (111 and\<CR>'
249       if shiftwidth == 4
250         indent.should == shiftwidth * 2
251       else
252         indent.should == 4
253       end
254       vim.feedkeys '222):\<CR>'
255       indent.should == shiftwidth
256       vim.feedkeys 'pass\<CR>'
257       indent.should == 0
258     end
259
260     it "still aligns parens properly if not ambiguous" do
261       vim.feedkeys 'iwhile (111 and\<CR>'
262       indent.should == 7
263       vim.feedkeys '222):\<CR>'
264       indent.should == shiftwidth
265       vim.feedkeys 'pass\<CR>'
266       indent.should == 0
267     end
268
269     it "handles nested expressions (Flake8's E127)" do
270       vim.feedkeys 'i[\<CR>x for x in foo\<CR>if (\<CR>'
271       indent.should == shiftwidth * 2
272     end
273
274     it "still handles multiple parens correctly" do
275       vim.feedkeys 'iif (111 and (222 and 333\<CR>'
276       indent.should == 13
277       vim.feedkeys 'and 444\<CR>'
278       indent.should == 13
279       vim.feedkeys ')\<CR>'
280       if shiftwidth == 4
281         indent.should == shiftwidth * 2
282       else
283         indent.should == 4
284       end
285       vim.feedkeys 'and 555):\<CR>'
286       indent.should == shiftwidth
287       vim.feedkeys 'pass\<CR>'
288       indent.should == 0
289     end
290   end
291
292   describe "when a line breaks with a manual '\\'" do
293     it "indents shiftwidth spaces on normal line" do
294         vim.feedkeys 'ivalue = test + \\\\\<CR>'
295         indent.should == shiftwidth
296     end
297
298     it "indents 2x shiftwidth spaces for control structures" do
299         vim.feedkeys 'iif somevalue == xyz and \\\\\<CR>'
300         indent.should == shiftwidth * 2
301     end
302
303     it "indents relative to line above" do
304         vim.feedkeys 'i\<TAB>value = test + \\\\\<CR>'
305         indent.should == shiftwidth * 2
306     end
307   end
308
309   describe "when current line is dedented compared to previous line" do
310      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<ESC>' }
311      it "and current line has a valid indentation (Part 1)" do
312         vim.feedkeys '0i\<TAB>if y:'
313         proposed_indent.should == -1
314      end
315
316      it "and current line has a valid indentation (Part 2)" do
317         vim.feedkeys '0i\<TAB>\<TAB>if y:'
318         proposed_indent.should == -1
319      end
320
321      it "and current line has an invalid indentation" do
322         vim.feedkeys 'i    while True:\<CR>'
323         indent.should == previous_indent + shiftwidth
324      end
325   end
326
327   describe "when current line is dedented compared to the last non-empty line" do
328      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>y = True\<CR>\<CR>\<ESC>' }
329      it "and current line has a valid indentation" do
330         vim.feedkeys '0i\<TAB>if y:'
331         proposed_indent.should == -1
332      end
333   end
334
335   describe "when an 'if' is followed by" do
336      before { vim.feedkeys 'i\<TAB>\<TAB>if x:\<CR>' }
337      it "an elif, it lines up with the 'if'" do
338         vim.feedkeys 'elif y:'
339         indent.should == shiftwidth * 2
340      end
341
342      it "an 'else', it lines up with the 'if'" do
343         vim.feedkeys 'else:'
344         indent.should == shiftwidth * 2
345      end
346   end
347
348   describe "when an 'if' contains a try-except" do
349      before {
350        vim.feedkeys 'iif x:\<CR>try:\<CR>pass\<CR>except:\<CR>pass\<CR>'
351        indent.should == shiftwidth
352      }
353      it "an 'else' should be indented to the try" do
354        vim.feedkeys 'else:'
355        indent.should == shiftwidth
356        proposed_indent.should == shiftwidth
357      end
358      it "an 'else' should keep the indent of the 'if'" do
359        vim.feedkeys 'else:\<ESC><<'
360        indent.should == 0
361        proposed_indent.should == 0
362      end
363   end
364
365   describe "when a 'for' is followed by" do
366      before { vim.feedkeys 'i\<TAB>\<TAB>for x in y:\<CR>' }
367      it "an 'else', it lines up with the 'for'" do
368         vim.feedkeys 'else:'
369         indent.should == shiftwidth * 2
370      end
371   end
372
373   describe "when an 'else' is followed by" do
374      before { vim.feedkeys 'i\<TAB>\<TAB>else:\<CR>XXX\<CR>' }
375      it "a 'finally', it lines up with the 'else'" do
376         vim.feedkeys 'finally:'
377         indent.should == shiftwidth * 2
378      end
379   end
380
381
382   describe "when a 'try' is followed by" do
383      before { vim.feedkeys 'i\<TAB>\<TAB>try:\<CR>' }
384      it "an 'except', it lines up with the 'try'" do
385         vim.feedkeys 'except:'
386         indent.should == shiftwidth * 2
387      end
388
389      it "an 'else', it lines up with the 'try'" do
390         vim.feedkeys 'else:'
391         indent.should == shiftwidth * 2
392      end
393
394      it "a 'finally', it lines up with the 'try'" do
395         vim.feedkeys 'finally:'
396         indent.should == shiftwidth * 2
397      end
398   end
399
400   describe "when an 'except' is followed by" do
401      before { vim.feedkeys 'i\<TAB>\<TAB>except:\<CR>' }
402      it "an 'else', it lines up with the 'except'" do
403         vim.feedkeys 'else:'
404         indent.should == shiftwidth * 2
405      end
406
407      it "another 'except', it lines up with the previous 'except'" do
408         vim.feedkeys 'except:'
409         indent.should == shiftwidth * 2
410      end
411
412      it "a 'finally', it lines up with the 'except'" do
413         vim.feedkeys 'finally:'
414         indent.should == shiftwidth * 2
415      end
416   end
417
418   describe "when an else is used inside of a nested if" do
419     before { vim.feedkeys 'iif foo:\<CR>if bar:\<CR>pass\<CR>' }
420     it "indents the else to the inner if" do
421       vim.feedkeys 'else:'
422       indent.should == shiftwidth
423     end
424   end
425
426   describe "when an else is used outside of a nested if" do
427     before { vim.feedkeys 'iif True:\<CR>if True:\<CR>pass\<CR>\<Esc>0' }
428     it "indents the else to the outer if" do
429       indent.should == 0
430       proposed_indent.should == shiftwidth
431
432       vim.feedkeys 'ielse:'
433       indent.should == 0
434       proposed_indent.should == 0
435     end
436   end
437
438   describe "when jedi-vim call signatures are used" do
439     before { vim.command 'syn match jediFunction "JEDI_CALL_SIGNATURE" keepend extend' }
440
441     it "ignores the call signature after a colon" do
442       vim.feedkeys 'iif True:  JEDI_CALL_SIGNATURE\<CR>'
443       indent.should == shiftwidth
444     end
445
446     it "ignores the call signature after a function" do
447       vim.feedkeys 'idef f(  JEDI_CALL_SIGNATURE\<CR>'
448       indent.should == shiftwidth
449     end
450   end
451 end
452
453 shared_examples_for "multiline strings" do
454   before(:each) {
455     # clear buffer
456     vim.normal 'gg"_dG'
457
458     # Insert two blank lines.
459     # The first line is a corner case in this plugin that would shadow the
460     # correct behaviour of other tests. Thus we explicitly jump to the first
461     # line when we require so.
462     vim.feedkeys 'i\<CR>\<CR>\<ESC>'
463   }
464
465   describe "when after an '(' that is followed by an unfinished string" do
466     before { vim.feedkeys 'itest("""' }
467
468     it "it indents the next line" do
469       vim.feedkeys '\<CR>'
470       expected_proposed, expected_indent = multiline_indent(0, shiftwidth)
471       proposed_indent.should == expected_proposed
472       indent.should == expected_indent
473     end
474
475     it "with contents it indents the second line to the parenthesis" do
476       vim.feedkeys 'second line\<CR>'
477       expected_proposed, expected_indent = multiline_indent(0, 5)
478       proposed_indent.should == expected_proposed
479       indent.should == expected_indent
480     end
481   end
482
483   describe "when after assigning an unfinished string" do
484     before { vim.feedkeys 'itest = """' }
485
486     it "it indents the next line" do
487       vim.feedkeys '\<CR>'
488       expected_proposed, expected_indent = multiline_indent(0, shiftwidth)
489       proposed_indent.should == expected_proposed
490       indent.should == expected_indent
491     end
492   end
493
494   describe "when after assigning an indented unfinished string" do
495     before { vim.feedkeys 'i    test = """' }
496
497     it "it indents the next line" do
498       vim.feedkeys '\<CR>'
499       expected_proposed, expected_indent = multiline_indent(4, shiftwidth + 4)
500       proposed_indent.should == expected_proposed
501       indent.should == expected_indent
502     end
503   end
504
505   describe "when after assigning an indented finished string" do
506     before { vim.feedkeys 'i    test = ""' }
507
508     it "it does indent the next line" do
509       vim.feedkeys '\<CR>'
510       indent.should == 4
511     end
512
513     it "and writing a new string, it does indent the next line" do
514       vim.feedkeys '\<CR>""'
515       indent.should == 4
516     end
517   end
518
519   describe "when after a docstring" do
520     it "it does indent the next line to the docstring" do
521       vim.feedkeys 'i    """\<CR>'
522       indent.should == 4
523       proposed_indent.should == 4
524     end
525
526     it "indents the closing docstring quotes" do
527       vim.feedkeys 'i    """\<CR>\<CR>"""'
528       indent.should == 4
529       proposed_indent.should == 4
530       vim.echo('getline(3)').should == '    """'
531     end
532
533     it "indents non-matching docstring quotes" do
534       vim.feedkeys 'i    """\<CR>\<Esc>'
535       vim.feedkeys "0C'''"
536       vim.echo('line(".")').should == "4"
537       vim.echo('getline(".")').should == "'''"
538       indent.should == 0
539       proposed_indent.should == -1
540     end
541   end
542
543   describe "when after a docstring with contents" do
544     before { vim.feedkeys 'i    """First line' }
545     it "it does indent the next line to the docstring" do
546       vim.feedkeys '\<CR>'
547       indent.should == 4
548       proposed_indent.should == 4
549     end
550   end
551
552   describe "when breaking a string after opening parenthesis" do
553     before { vim.feedkeys 'i    foo("""bar\<Left>\<Left>\<Left>' }
554     it "it does indent the next line as after an opening multistring" do
555       vim.feedkeys '\<CR>'
556       _, expected_indent = multiline_indent(4, 4 + shiftwidth)
557       indent.should == expected_indent
558       proposed_indent.should == -1
559
560       # it keeps the indent after an empty line
561       vim.feedkeys '\<CR>'
562       proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth)
563       indent.should == expected_indent
564       proposed_indent.should == proposed_indent
565
566       # it keeps the indent of nonblank above
567       vim.feedkeys '\<End>\<CR>'
568       proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth)
569       indent.should == expected_indent
570       proposed_indent.should == proposed_indent
571
572       # it keeps the indent of nonblank above before an empty line
573       vim.feedkeys '\<CR>'
574       proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth)
575       indent.should == expected_indent
576       proposed_indent.should == proposed_indent
577     end
578   end
579 end
580
581 SUITE_SHIFTWIDTHS = [4, 3]
582 SUITE_HANG_CLOSINGS = [false, true]
583
584 SUITE_SHIFTWIDTHS.each do |sw|
585   describe "vim when using width of #{sw}" do
586     before {
587       vim.command("set sw=#{sw} ts=#{sw} sts=#{sw} et")
588     }
589     it "sets shiftwidth to #{sw}" do
590       shiftwidth.should == sw
591     end
592
593     SUITE_HANG_CLOSINGS.each do |hc|
594       describe "vim when hang_closing is set to #{hc}" do
595         before {
596           set_hang_closing hc
597         }
598         it "sets hang_closing to #{hc}" do
599           hang_closing.should == !!hc
600         end
601
602         it_behaves_like "vim"
603       end
604     end
605   end
606 end
607
608 describe "vim when not using python_pep8_indent_multiline_string" do
609   before {
610     vim.command("set sw=4 ts=4 sts=4 et")
611     vim.command("unlet! g:python_pep8_indent_multiline_string")
612   }
613   it_behaves_like "multiline strings"
614 end
615
616 describe "vim when using python_pep8_indent_multiline_first=0" do
617   before {
618     vim.command("set sw=4 ts=4 sts=4 et")
619     vim.command("let g:python_pep8_indent_multiline_string=0")
620   }
621   it_behaves_like "multiline strings"
622 end
623
624 describe "vim when using python_pep8_indent_multiline_string=-1" do
625   before {
626     vim.command("set sw=4 ts=4 sts=4 et")
627     vim.command("let g:python_pep8_indent_multiline_string=-1")
628   }
629   it_behaves_like "multiline strings"
630 end
631
632 describe "vim when using python_pep8_indent_multiline_string=-2" do
633   before {
634     vim.command("set sw=4 ts=4 sts=4 et")
635     vim.command("let g:python_pep8_indent_multiline_string=-2")
636   }
637   it_behaves_like "multiline strings"
638 end
639
640 describe "Handles far away opening parens" do
641   before { vim.feedkeys '\<ESC>ggdGifrom foo import (' }
642
643   it "indents by one level" do
644     vim.feedkeys '\<CR>'
645     proposed_indent.should == shiftwidth
646   end
647
648   it "indents by one level for 10 lines" do
649     vim.command('set paste | exe "norm 9o" | set nopaste')
650     vim.feedkeys '\<Esc>o'
651     indent.should == shiftwidth
652   end
653
654   it "indents by one level for 50 lines" do
655     vim.command('set paste | exe "norm 49o" | set nopaste')
656     vim.feedkeys '\<Esc>o'
657     indent.should == shiftwidth
658   end
659 end
660
661 describe "Handles far away opening square brackets" do
662   before { vim.feedkeys '\<ESC>ggdGibar = [' }
663
664   it "indents by one level" do
665     vim.feedkeys '\<CR>'
666     proposed_indent.should == shiftwidth
667   end
668
669   it "indents by one level for 10 lines" do
670     vim.command('set paste | exe "norm 9o" | set nopaste')
671     vim.feedkeys '\<Esc>o'
672     indent.should == shiftwidth
673   end
674
675   it "indents by one level for 100 lines" do
676     vim.command('set paste | exe "norm 99o" | set nopaste')
677     vim.feedkeys '\<Esc>o'
678     indent.should == shiftwidth
679   end
680 end
681
682 describe "Handles far away opening curly brackets" do
683   before { vim.feedkeys '\<ESC>ggdGijson = {' }
684
685   it "indents by one level" do
686     vim.feedkeys '\<CR>'
687     vim.feedkeys '\<Esc>o'
688     proposed_indent.should == shiftwidth
689   end
690
691   it "indents by one level for 10 lines" do
692     vim.command('set paste | exe "norm 9o" | set nopaste')
693     vim.feedkeys '\<Esc>o'
694     indent.should == shiftwidth
695   end
696
697   it "indents by one level for 1000 lines" do
698     vim.command('set paste | exe "norm 999o" | set nopaste')
699     vim.feedkeys '\<Esc>o'
700     indent.should == shiftwidth
701   end
702 end
703
704 describe "Compact multiline dict" do
705   before { vim.feedkeys '\<ESC>ggdGid = {"one": 1,' }
706
707   it "gets indented correctly" do
708     vim.feedkeys '\<CR>'
709     proposed_indent.should == 5
710
711     vim.feedkeys '"two": 2}'
712     proposed_indent.should == 5
713
714     vim.feedkeys '\<CR>'
715     proposed_indent.should == 0
716   end
717 end
718
719 describe "Using O" do
720   before {
721     vim.feedkeys '\<ESC>ggdG'
722     vim.feedkeys 'iif foo:\<CR>'
723   }
724
725   it "respects autoindent" do
726     vim.feedkeys '1\<CR>\<CR>'
727     indent.should == shiftwidth
728     vim.feedkeys '\<Esc>ko'
729     indent.should == shiftwidth
730     vim.feedkeys '\<Esc>kO'
731     indent.should == shiftwidth
732     # Uses/keeps indent from line above
733     vim.feedkeys '\<Esc>i2\<Esc>O'
734     indent.should == shiftwidth
735     # Uses/keeps indent from line above
736     vim.feedkeys '\<Esc>j\<Esc>O'
737     indent.should == 0
738   end
739 end
740
741 describe "searchpairpos" do
742   before { vim.feedkeys '\<ESC>ggdG' }
743   it "handles nested parenthesis" do
744     vim.feedkeys 'iif foo.startswith("("):\<CR>'
745     indent.should == shiftwidth
746   end
747 end
748
749 describe "o within TODO" do
750   before {
751     vim.feedkeys '\<ESC>ggdG'
752     vim.feedkeys 'iif 1:  # TODO\<Esc>'
753     # Assertion that we have a pythonTodo here.
754     vim.echo('synIDattr(synID(line("."), col("."), 0), "name")').should match 'pythonTodo'
755   }
756
757   it "respects autoindent" do
758     vim.feedkeys 'o'
759     indent.should == shiftwidth
760   end
761 end
762
763 describe "elif after else" do
764   before {
765     vim.feedkeys '\<ESC>ggdG'
766   }
767
768   it "is indented to the outer if" do
769     vim.feedkeys 'iif 1:\<CR>if 2:\<CR>pass\<CR>else:\<CR>pass\<CR>elif 3:\<Esc>'
770     indent.should == 0
771
772     vim.feedkeys '\<ESC>ggdG'
773     vim.feedkeys 'i    if 1:\<CR>if 2:\<CR>pass\<CR>else:\<CR>pass\<CR>elif 3:\<Esc>'
774     indent.should == 4
775   end
776 end