Skip to content

Commit 0a6f16f

Browse files
committed
WIP: use b:_jedi_callsig_orig to get original line contents
Adds s:getline() and s:prevnonblank() wrappers.
1 parent c294334 commit 0a6f16f

File tree

2 files changed

+62
-34
lines changed

2 files changed

+62
-34
lines changed

indent/python.vim

+50-32
Original file line numberDiff line numberDiff line change
@@ -58,23 +58,11 @@ endif
5858
let s:stop_statement = '^\s*\(break\|continue\|raise\|return\|pass\)\>'
5959

6060
" Skip strings and comments. Return 1 for chars to skip.
61-
" jedi* refers to syntax definitions from jedi-vim for call signatures, which
62-
" are inserted temporarily into the buffer.
6361
let s:skip_special_chars = 'synIDattr(synID(line("."), col("."), 0), "name") ' .
64-
\ '=~? "\\vstring|comment|jedi\\S"'
62+
\ '=~? "\\vstring|comment"'
6563

6664
let s:skip_after_opening_paren = 'synIDattr(synID(line("."), col("."), 0), "name") ' .
67-
\ '=~? "\\vcomment|jedi\\S"'
68-
69-
" Also ignore anything concealed.
70-
" Wrapper around synconcealed for older Vim (7.3.429, used on Travis CI).
71-
function! s:is_concealed(line, col)
72-
let concealed = synconcealed(a:line, a:col)
73-
return len(concealed) && concealed[0]
74-
endfunction
75-
if has('conceal')
76-
let s:skip_special_chars .= '|| s:is_concealed(line("."), col("."))'
77-
endif
65+
\ '=~? "\\vcomment"'
7866

7967

8068
let s:skip_search = 'synIDattr(synID(line("."), col("."), 0), "name") ' .
@@ -130,8 +118,8 @@ endfunction
130118
function! s:find_start_of_multiline_statement(lnum)
131119
let lnum = a:lnum
132120
while lnum > 0
133-
if getline(lnum - 1) =~# '\\$'
134-
let lnum = prevnonblank(lnum - 1)
121+
if s:getline(lnum - 1) =~# '\\$'
122+
let lnum = s:prevnonblank(lnum - 1)
135123
else
136124
let [paren_lnum, _] = s:find_opening_paren(lnum)
137125
if paren_lnum < 1
@@ -155,7 +143,7 @@ function! s:find_start_of_block(lnum, types, multiple)
155143
if indent < last_indent
156144
for type in types
157145
let re = '\v^\s*'.type.'>'
158-
if getline(lnum) =~# re
146+
if s:getline(lnum) =~# re
159147
if !a:multiple
160148
return [indent]
161149
endif
@@ -168,15 +156,15 @@ function! s:find_start_of_block(lnum, types, multiple)
168156
endfor
169157
let last_indent = indent(lnum)
170158
endif
171-
let lnum = prevnonblank(lnum - 1)
159+
let lnum = s:prevnonblank(lnum - 1)
172160
endwhile
173161
return r
174162
endfunction
175163

176164
" Is "expr" true for every position in "lnum", beginning at "start"?
177165
" (optionally up to a:1 / 4th argument)
178166
function! s:match_expr_on_line(expr, lnum, start, ...)
179-
let text = getline(a:lnum)
167+
let text = s:getline(a:lnum)
180168
let end = a:0 ? a:1 : len(text)
181169
if a:start > end
182170
return 1
@@ -200,12 +188,12 @@ function! s:indent_like_opening_paren(lnum)
200188
if paren_lnum <= 0
201189
return -2
202190
endif
203-
let text = getline(paren_lnum)
191+
let text = s:getline(paren_lnum)
204192
let base = indent(paren_lnum)
205193

206194
let nothing_after_opening_paren = s:match_expr_on_line(
207195
\ s:skip_after_opening_paren, paren_lnum, paren_col+1)
208-
let starts_with_closing_paren = getline(a:lnum) =~# '^\s*[])}]'
196+
let starts_with_closing_paren = s:getline(a:lnum) =~# '^\s*[])}]'
209197

210198
let hang_closing = get(b:, 'python_pep8_indent_hang_closing',
211199
\ get(g:, 'python_pep8_indent_hang_closing', 0))
@@ -233,7 +221,7 @@ endfunction
233221

234222
" Match indent of first block of this type.
235223
function! s:indent_like_block(lnum)
236-
let text = getline(a:lnum)
224+
let text = s:getline(a:lnum)
237225
for [multiple, block_rules] in [
238226
\ [0, s:block_rules],
239227
\ [1, s:block_rules_multiple]]
@@ -263,15 +251,45 @@ function! s:indent_like_block(lnum)
263251
return -2
264252
endfunction
265253

254+
" Wrapper around getline that looks up jedi-vim's b:_jedi_callsig_orig to get
255+
" the original line.
256+
function! s:getline(lnum) abort
257+
let line = get(get(b:, '_jedi_callsig_orig', {}), a:lnum, 0)
258+
if line is 0
259+
return getline(a:lnum)
260+
endif
261+
return line
262+
endfunction
263+
264+
" Wrapper around prevnonblank that looks up jedi-vim's b:_jedi_callsig_orig to
265+
" check the original line's contents additionally.
266+
function! s:prevnonblank(lnum) abort
267+
let lnum = a:lnum
268+
while 1
269+
let lnum = prevnonblank(lnum)
270+
if lnum < 1
271+
return lnum
272+
endif
273+
let orig_line = get(get(b:, '_jedi_callsig_orig', {}), lnum, 0)
274+
if orig_line is 0
275+
return lnum
276+
endif
277+
if !empty(orig_line)
278+
return lnum
279+
endif
280+
let lnum -= 1
281+
endwhile
282+
endfunction
283+
266284
function! s:indent_like_previous_line(lnum)
267-
let lnum = prevnonblank(a:lnum - 1)
285+
let lnum = s:prevnonblank(a:lnum - 1)
268286

269287
" No previous line, keep current indent.
270288
if lnum < 1
271289
return -1
272290
endif
273291

274-
let text = getline(lnum)
292+
let text = s:getline(lnum)
275293
let start = s:find_start_of_multiline_statement(lnum)
276294
let base = indent(start)
277295
let current = indent(a:lnum)
@@ -297,25 +315,25 @@ function! s:indent_like_previous_line(lnum)
297315
" If this line is the continuation of a control statement
298316
" indent further to distinguish the continuation line
299317
" from the next logical line.
300-
if getline(start) =~# b:control_statement
318+
if s:getline(start) =~# b:control_statement
301319
return base + s:sw() * 2
302320
endif
303321

304322
" Nest (other) explicit continuations only one level deeper.
305323
return base + s:sw()
306324
endif
307325

308-
let empty = getline(a:lnum) =~# '^\s*$'
326+
let empty = s:getline(a:lnum) =~# '^\s*$'
309327

310328
" Current and prev line are empty, next is not -> indent like next.
311329
if empty && a:lnum > 1 &&
312-
\ (getline(a:lnum - 1) =~# '^\s*$') &&
313-
\ !(getline(a:lnum + 1) =~# '^\s*$')
330+
\ (s:getline(a:lnum - 1) =~# '^\s*$') &&
331+
\ !(s:getline(a:lnum + 1) =~# '^\s*$')
314332
return indent(a:lnum + 1)
315333
endif
316334

317335
" If the previous statement was a stop-execution statement or a pass
318-
if getline(start) =~# s:stop_statement
336+
if s:getline(start) =~# s:stop_statement
319337
" Remove one level of indentation if the user hasn't already dedented
320338
if empty || current > base - s:sw()
321339
return base - s:sw()
@@ -341,7 +359,7 @@ endfunction
341359

342360
" Is the syntax at lnum (and optionally cnum) a python string?
343361
function! s:is_python_string(lnum, ...)
344-
let line = getline(a:lnum)
362+
let line = s:getline(a:lnum)
345363
let linelen = len(line)
346364
if linelen < 1
347365
let linelen = 1
@@ -362,8 +380,8 @@ function! GetPythonPEPIndent(lnum)
362380
return 0
363381
endif
364382

365-
let line = getline(a:lnum)
366-
let prevline = getline(a:lnum-1)
383+
let line = s:getline(a:lnum)
384+
let prevline = s:getline(a:lnum-1)
367385

368386
" Multilinestrings: continous, docstring or starting.
369387
if s:is_python_string(a:lnum-1, len(prevline))

spec/indent/indent_spec.rb

+12-2
Original file line numberDiff line numberDiff line change
@@ -404,15 +404,25 @@
404404
end
405405

406406
describe "when jedi-vim call signatures are used" do
407-
before { vim.command 'syn match jediFunction "JEDI_CALL_SIGNATURE" keepend extend' }
407+
before {
408+
# jedi-vim uses a buffer variable that holds the original line contents
409+
# for concealed lines.
410+
vim.command 'let b:_jedi_callsig_orig = {3: "if True:", 4: "def f("}'
411+
}
412+
after {
413+
vim.command 'unlet b:_jedi_callsig_orig'
414+
}
408415

409416
it "ignores the call signature after a colon" do
417+
# Assert that we are in line 3.
418+
vim.echo("getcurpos()[1]").to_i.should == 3
410419
vim.feedkeys 'iif True: JEDI_CALL_SIGNATURE\<CR>'
411420
indent.should == shiftwidth
412421
end
413422

414423
it "ignores the call signature after a function" do
415-
vim.feedkeys 'idef f( JEDI_CALL_SIGNATURE\<CR>'
424+
vim.echo("getcurpos()[1]").to_i.should == 3
425+
vim.feedkeys 'odef f( JEDI_CALL_SIGNATURE\<CR>'
416426
indent.should == shiftwidth * 2
417427
end
418428
end

0 commit comments

Comments
 (0)