Skip to content

Commit 446bfd0

Browse files
committed
Fix indenting of strings, especially after opening paren
Fixes #36 Closes #37
1 parent 5a4f78c commit 446bfd0

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

indent/python.vim

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,48 @@ function! s:indent_like_previous_line(lnum)
246246
return base
247247
endfunction
248248

249+
" Is the syntax at lnum (and optionally cnum) a python string?
250+
function! s:is_python_string(lnum, ...)
251+
let line = getline(a:lnum)
252+
let linelen = len(line)
253+
if linelen < 1
254+
let linelen = 1
255+
endif
256+
let cols = a:0 ? type(a:1) != type([]) ? [a:1] : a:1 : range(1, linelen)
257+
for cnum in cols
258+
if match(map(synstack(a:lnum, cnum),
259+
\ 'synIDattr(v:val,"name")'), 'python\S*String') == -1
260+
return 0
261+
end
262+
endfor
263+
return 1
264+
endfunction
265+
249266
function! GetPythonPEPIndent(lnum)
250267

251268
" First line has indent 0
252269
if a:lnum == 1
253270
return 0
254271
endif
255272

273+
" Multilinestrings: continous, docstring or starting.
274+
if s:is_python_string(a:lnum)
275+
if s:is_python_string(a:lnum-1)
276+
" Previous line is (completely) a string.
277+
return s:indent_like_previous_line(a:lnum)
278+
endif
279+
280+
if match(getline(a:lnum-1), '^\s*\%("""\|''''''\)') != -1
281+
" docstring.
282+
return s:indent_like_previous_line(a:lnum)
283+
endif
284+
285+
if s:is_python_string(a:lnum-1, len(getline(a:lnum-1)))
286+
" String started in previous line.
287+
return 0
288+
endif
289+
endif
290+
256291
" Parens: If we can find an open parenthesis/bracket/brace, line up with it.
257292
let indent = s:indent_like_opening_paren(a:lnum)
258293
if indent >= -1

spec/indent/indent_spec.rb

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,68 @@
129129
end
130130
end
131131

132+
describe "when after an '(' that is followed by an unfinished string" do
133+
before { vim.feedkeys 'itest("""' }
134+
135+
it "it does not indent the next line" do
136+
vim.feedkeys '\<CR>'
137+
proposed_indent.should == 0
138+
indent.should == 0
139+
end
140+
141+
it "with contents it does not indent the next line" do
142+
vim.feedkeys 'string_contents\<CR>'
143+
proposed_indent.should == 0
144+
indent.should == 0
145+
end
146+
end
147+
148+
describe "when after assigning an unfinished string" do
149+
before { vim.feedkeys 'itest = """' }
150+
151+
it "it does not indent the next line" do
152+
vim.feedkeys '\<CR>'
153+
proposed_indent.should == 0
154+
indent.should == 0
155+
end
156+
end
157+
158+
describe "when after assigning an unfinished string" do
159+
before { vim.feedkeys 'i test = """' }
160+
161+
it "it does not indent the next line" do
162+
vim.feedkeys '\<CR>'
163+
proposed_indent.should == 0
164+
indent.should == 0
165+
end
166+
end
167+
168+
describe "when after assigning a finished string" do
169+
before { vim.feedkeys 'i test = ""' }
170+
171+
it "it does indent the next line" do
172+
vim.feedkeys '\<CR>'
173+
proposed_indent.should == 4
174+
indent.should == 4
175+
end
176+
177+
it "and writing a new string, it does indent the next line" do
178+
vim.feedkeys '\<CR>""'
179+
proposed_indent.should == 4
180+
indent.should == 4
181+
end
182+
end
183+
184+
describe "when after a docstring" do
185+
before { vim.feedkeys 'i """' }
186+
187+
it "it does indent the next line" do
188+
vim.feedkeys '\<CR>'
189+
proposed_indent.should == 4
190+
indent.should == 4
191+
end
192+
end
193+
132194
describe "when using simple control structures" do
133195
it "indents shiftwidth spaces" do
134196
vim.feedkeys 'iwhile True:\<CR>pass'

0 commit comments

Comments
 (0)