Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: use b:_jedi_callsig_orig to get original line contents #98

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 50 additions & 21 deletions indent/python.vim
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ endif
let s:stop_statement = '^\s*\(break\|continue\|raise\|return\|pass\)\>'

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

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

if !get(g:, 'python_pep8_indent_skip_concealed', 0) || !has('conceal')
" Skip strings and comments. Return 1 for chars to skip.
Expand Down Expand Up @@ -136,8 +136,8 @@ endfunction
function! s:find_start_of_multiline_statement(lnum)
let lnum = a:lnum
while lnum > 0
if getline(lnum - 1) =~# '\\$'
let lnum = prevnonblank(lnum - 1)
if s:getline(lnum - 1) =~# '\\$'
let lnum = s:prevnonblank(lnum - 1)
else
let [paren_lnum, _] = s:find_opening_paren(lnum, 1)
if paren_lnum < 1
Expand All @@ -163,7 +163,7 @@ function! s:find_start_of_block(lnum, types, skip, multiple) abort
while lnum > 0 && last_indent > 0
let indent = indent(lnum)
if indent < last_indent
let line = getline(lnum)
let line = s:getline(lnum)
if !empty(re_skip) && line =~# re_skip
let last_indent = indent
elseif line =~# re
Expand All @@ -176,15 +176,15 @@ function! s:find_start_of_block(lnum, types, skip, multiple) abort
let last_indent = indent
endif
endif
let lnum = prevnonblank(lnum - 1)
let lnum = s:prevnonblank(lnum - 1)
endwhile
return r
endfunction

" Is "expr" true for every position in "lnum", beginning at "start"?
" (optionally up to a:1 / 4th argument)
function! s:match_expr_on_line(expr, lnum, start, ...)
let text = getline(a:lnum)
let text = s:getline(a:lnum)
let end = a:0 ? a:1 : len(text)
if a:start > end
return 1
Expand All @@ -208,12 +208,12 @@ function! s:indent_like_opening_paren(lnum)
if paren_lnum <= 0
return -2
endif
let text = getline(paren_lnum)
let text = s:getline(paren_lnum)
let base = indent(paren_lnum)

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

let hang_closing = get(b:, 'python_pep8_indent_hang_closing',
\ get(g:, 'python_pep8_indent_hang_closing', 0))
Expand Down Expand Up @@ -249,7 +249,7 @@ endfunction

" Match indent of first block of this type.
function! s:indent_like_block(lnum)
let text = getline(a:lnum)
let text = s:getline(a:lnum)
for [multiple, block_rules] in [
\ [0, s:block_rules],
\ [1, s:block_rules_multiple],
Expand Down Expand Up @@ -281,15 +281,45 @@ function! s:indent_like_block(lnum)
return -2
endfunction

" Wrapper around getline that looks up jedi-vim's b:_jedi_callsig_orig to get
" the original line.
function! s:getline(lnum) abort
let line = get(get(b:, '_jedi_callsig_orig', {}), a:lnum, 0)
if line is 0
return getline(a:lnum)
endif
return line
endfunction

" Wrapper around prevnonblank that looks up jedi-vim's b:_jedi_callsig_orig to
" check the original line's contents additionally.
function! s:prevnonblank(lnum) abort
let lnum = a:lnum
while 1
let lnum = prevnonblank(lnum)
if lnum < 1
return lnum
endif
let orig_line = get(get(b:, '_jedi_callsig_orig', {}), lnum, 0)
if orig_line is 0
return lnum
endif
if !empty(orig_line)
return lnum
endif
let lnum -= 1
endwhile
endfunction

function! s:indent_like_previous_line(lnum)
let lnum = prevnonblank(a:lnum - 1)
let lnum = s:prevnonblank(a:lnum - 1)

" No previous line, keep current indent.
if lnum < 1
return -1
endif

let text = getline(lnum)
let text = s:getline(lnum)
let start = s:find_start_of_multiline_statement(lnum)
let base = indent(start)
let current = indent(a:lnum)
Expand All @@ -314,25 +344,25 @@ function! s:indent_like_previous_line(lnum)
" If this line is the continuation of a control statement
" indent further to distinguish the continuation line
" from the next logical line.
if getline(start) =~# b:control_statement
if s:getline(start) =~# b:control_statement
return base + s:sw() * 2
endif

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

let empty = getline(a:lnum) =~# '^\s*$'
let empty = s:getline(a:lnum) =~# '^\s*$'

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

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

" Is the syntax at lnum (and optionally cnum) a python string?
function! s:is_python_string(lnum, ...)
let line = getline(a:lnum)
if a:0
let cols = type(a:1) != type([]) ? [a:1] : a:1
else
let cols = range(1, max([1, len(line)]))
let cols = range(1, max([1, len(s:getline(a:lnum))]))
endif
for cnum in cols
if match(map(synstack(a:lnum, cnum),
Expand All @@ -379,8 +408,8 @@ function! GetPythonPEPIndent(lnum)
return 0
endif

let line = getline(a:lnum)
let prevline = getline(a:lnum-1)
let line = s:getline(a:lnum)
let prevline = s:getline(a:lnum-1)

" Multilinestrings: continous, docstring or starting.
if s:is_python_string(a:lnum-1, max([1, len(prevline)]))
Expand Down
14 changes: 12 additions & 2 deletions spec/indent/indent_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -436,15 +436,25 @@
end

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

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

it "ignores the call signature after a function" do
vim.feedkeys 'idef f( JEDI_CALL_SIGNATURE\<CR>'
vim.echo("getcurpos()[1]").to_i.should == 3
vim.feedkeys 'odef f( JEDI_CALL_SIGNATURE\<CR>'
indent.should == shiftwidth
end
end
Expand Down