Skip to content

Commit dac9104

Browse files
committed
Support for jedi-vim's call signatures
Adds s:getline() and s:prevnonblank() wrappers to use b:_jedi_callsig_orig for the original line contents. Requires davidhalter/jedi-vim#652.
1 parent b3a7395 commit dac9104

File tree

2 files changed

+62
-23
lines changed

2 files changed

+62
-23
lines changed

indent/python.vim

+50-21
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ endif
6767
let s:stop_statement = '^\s*\(break\|continue\|raise\|return\|pass\)\>'
6868

6969
let s:skip_after_opening_paren = 'synIDattr(synID(line("."), col("."), 0), "name") ' .
70-
\ '=~? "\\vcomment|jedi\\S"'
70+
\ '=~? "\\vcomment"'
7171

72-
let s:special_chars_syn_pattern = "\\vstring|comment|^pythonbytes%(contents)=$|pythonTodo|jedi\\S"
72+
let s:special_chars_syn_pattern = "\\vstring|comment|^pythonbytes%(contents)=$|pythonTodo"
7373

7474
if !get(g:, 'python_pep8_indent_skip_concealed', 0) || !has('conceal')
7575
" Skip strings and comments. Return 1 for chars to skip.
@@ -136,8 +136,8 @@ endfunction
136136
function! s:find_start_of_multiline_statement(lnum)
137137
let lnum = a:lnum
138138
while lnum > 0
139-
if getline(lnum - 1) =~# '\\$'
140-
let lnum = prevnonblank(lnum - 1)
139+
if s:getline(lnum - 1) =~# '\\$'
140+
let lnum = s:prevnonblank(lnum - 1)
141141
else
142142
let [paren_lnum, _] = s:find_opening_paren(lnum, 1)
143143
if paren_lnum < 1
@@ -163,7 +163,7 @@ function! s:find_start_of_block(lnum, types, skip, multiple) abort
163163
while lnum > 0 && last_indent > 0
164164
let indent = indent(lnum)
165165
if indent < last_indent
166-
let line = getline(lnum)
166+
let line = s:getline(lnum)
167167
if !empty(re_skip) && line =~# re_skip
168168
let last_indent = indent
169169
elseif line =~# re
@@ -176,15 +176,15 @@ function! s:find_start_of_block(lnum, types, skip, multiple) abort
176176
let last_indent = indent
177177
endif
178178
endif
179-
let lnum = prevnonblank(lnum - 1)
179+
let lnum = s:prevnonblank(lnum - 1)
180180
endwhile
181181
return r
182182
endfunction
183183

184184
" Is "expr" true for every position in "lnum", beginning at "start"?
185185
" (optionally up to a:1 / 4th argument)
186186
function! s:match_expr_on_line(expr, lnum, start, ...)
187-
let text = getline(a:lnum)
187+
let text = s:getline(a:lnum)
188188
let end = a:0 ? a:1 : len(text)
189189
if a:start > end
190190
return 1
@@ -208,12 +208,12 @@ function! s:indent_like_opening_paren(lnum)
208208
if paren_lnum <= 0
209209
return -2
210210
endif
211-
let text = getline(paren_lnum)
211+
let text = s:getline(paren_lnum)
212212
let base = indent(paren_lnum)
213213

214214
let nothing_after_opening_paren = s:match_expr_on_line(
215215
\ s:skip_after_opening_paren, paren_lnum, paren_col+1)
216-
let starts_with_closing_paren = getline(a:lnum) =~# '^\s*[])}]'
216+
let starts_with_closing_paren = s:getline(a:lnum) =~# '^\s*[])}]'
217217

218218
let hang_closing = get(b:, 'python_pep8_indent_hang_closing',
219219
\ get(g:, 'python_pep8_indent_hang_closing', 0))
@@ -249,7 +249,7 @@ endfunction
249249

250250
" Match indent of first block of this type.
251251
function! s:indent_like_block(lnum)
252-
let text = getline(a:lnum)
252+
let text = s:getline(a:lnum)
253253
for [multiple, block_rules] in [
254254
\ [0, s:block_rules],
255255
\ [1, s:block_rules_multiple],
@@ -281,15 +281,45 @@ function! s:indent_like_block(lnum)
281281
return -2
282282
endfunction
283283

284+
" Wrapper around getline that looks up jedi-vim's b:_jedi_callsig_orig to get
285+
" the original line.
286+
function! s:getline(lnum) abort
287+
let line = get(get(b:, '_jedi_callsig_orig', {}), a:lnum, 0)
288+
if line is 0
289+
return getline(a:lnum)
290+
endif
291+
return line
292+
endfunction
293+
294+
" Wrapper around prevnonblank that looks up jedi-vim's b:_jedi_callsig_orig to
295+
" check the original line's contents additionally.
296+
function! s:prevnonblank(lnum) abort
297+
let lnum = a:lnum
298+
while 1
299+
let lnum = prevnonblank(lnum)
300+
if lnum < 1
301+
return lnum
302+
endif
303+
let orig_line = get(get(b:, '_jedi_callsig_orig', {}), lnum, 0)
304+
if orig_line is 0
305+
return lnum
306+
endif
307+
if !empty(orig_line)
308+
return lnum
309+
endif
310+
let lnum -= 1
311+
endwhile
312+
endfunction
313+
284314
function! s:indent_like_previous_line(lnum)
285-
let lnum = prevnonblank(a:lnum - 1)
315+
let lnum = s:prevnonblank(a:lnum - 1)
286316

287317
" No previous line, keep current indent.
288318
if lnum < 1
289319
return -1
290320
endif
291321

292-
let text = getline(lnum)
322+
let text = s:getline(lnum)
293323
let start = s:find_start_of_multiline_statement(lnum)
294324
let base = indent(start)
295325
let current = indent(a:lnum)
@@ -314,25 +344,25 @@ function! s:indent_like_previous_line(lnum)
314344
" If this line is the continuation of a control statement
315345
" indent further to distinguish the continuation line
316346
" from the next logical line.
317-
if getline(start) =~# b:control_statement
347+
if s:getline(start) =~# b:control_statement
318348
return base + s:sw() * 2
319349
endif
320350

321351
" Nest (other) explicit continuations only one level deeper.
322352
return base + s:sw()
323353
endif
324354

325-
let empty = getline(a:lnum) =~# '^\s*$'
355+
let empty = s:getline(a:lnum) =~# '^\s*$'
326356

327357
" Current and prev line are empty, next is not -> indent like next.
328358
if empty && a:lnum > 1 &&
329-
\ (getline(a:lnum - 1) =~# '^\s*$') &&
330-
\ !(getline(a:lnum + 1) =~# '^\s*$')
359+
\ (s:getline(a:lnum - 1) =~# '^\s*$') &&
360+
\ !(s:getline(a:lnum + 1) =~# '^\s*$')
331361
return indent(a:lnum + 1)
332362
endif
333363

334364
" If the previous statement was a stop-execution statement or a pass
335-
if getline(start) =~# s:stop_statement
365+
if s:getline(start) =~# s:stop_statement
336366
" Remove one level of indentation if the user hasn't already dedented
337367
if empty || current > base - s:sw()
338368
return base - s:sw()
@@ -358,11 +388,10 @@ endfunction
358388

359389
" Is the syntax at lnum (and optionally cnum) a python string?
360390
function! s:is_python_string(lnum, ...)
361-
let line = getline(a:lnum)
362391
if a:0
363392
let cols = type(a:1) != type([]) ? [a:1] : a:1
364393
else
365-
let cols = range(1, max([1, len(line)]))
394+
let cols = range(1, max([1, len(s:getline(a:lnum))]))
366395
endif
367396
for cnum in cols
368397
if match(map(synstack(a:lnum, cnum),
@@ -379,8 +408,8 @@ function! GetPythonPEPIndent(lnum)
379408
return 0
380409
endif
381410

382-
let line = getline(a:lnum)
383-
let prevline = getline(a:lnum-1)
411+
let line = s:getline(a:lnum)
412+
let prevline = s:getline(a:lnum-1)
384413

385414
" Multilinestrings: continous, docstring or starting.
386415
if s:is_python_string(a:lnum-1, max([1, len(prevline)]))

spec/indent/indent_spec.rb

+12-2
Original file line numberDiff line numberDiff line change
@@ -436,15 +436,25 @@
436436
end
437437

438438
describe "when jedi-vim call signatures are used" do
439-
before { vim.command 'syn match jediFunction "JEDI_CALL_SIGNATURE" keepend extend' }
439+
before {
440+
# jedi-vim uses a buffer variable that holds the original line contents
441+
# for concealed lines.
442+
vim.command 'let b:_jedi_callsig_orig = {3: "if True:", 4: "def f("}'
443+
}
444+
after {
445+
vim.command 'unlet b:_jedi_callsig_orig'
446+
}
440447

441448
it "ignores the call signature after a colon" do
449+
# Assert that we are in line 3.
450+
vim.echo("getcurpos()[1]").to_i.should == 3
442451
vim.feedkeys 'iif True: JEDI_CALL_SIGNATURE\<CR>'
443452
indent.should == shiftwidth
444453
end
445454

446455
it "ignores the call signature after a function" do
447-
vim.feedkeys 'idef f( JEDI_CALL_SIGNATURE\<CR>'
456+
vim.echo("getcurpos()[1]").to_i.should == 3
457+
vim.feedkeys 'odef f( JEDI_CALL_SIGNATURE\<CR>'
448458
indent.should == shiftwidth
449459
end
450460
end

0 commit comments

Comments
 (0)