aboutsummaryrefslogtreecommitdiff
path: root/runtime/autoload/python.vim
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2022-08-30 23:29:44 -0600
committerJosh Rahm <joshuarahm@gmail.com>2022-08-30 23:29:44 -0600
commit442d4e54c30b8e193e3f6e4d32b43e96815bccd7 (patch)
treeb52e341e7db3d2428d8762a7ecf9b58dd84ff6c4 /runtime/autoload/python.vim
parent8436383af96dc7afa3596fc22c012d68e76f47f8 (diff)
parentf4274d0f62625683486d3912dcd6e8e45877c6a4 (diff)
downloadrneovim-442d4e54c30b8e193e3f6e4d32b43e96815bccd7.tar.gz
rneovim-442d4e54c30b8e193e3f6e4d32b43e96815bccd7.tar.bz2
rneovim-442d4e54c30b8e193e3f6e4d32b43e96815bccd7.zip
Merge remote-tracking branch 'upstream/master' into usermarks
Diffstat (limited to 'runtime/autoload/python.vim')
-rw-r--r--runtime/autoload/python.vim94
1 files changed, 59 insertions, 35 deletions
diff --git a/runtime/autoload/python.vim b/runtime/autoload/python.vim
index 7e7bca6fb6..1eaad09ef5 100644
--- a/runtime/autoload/python.vim
+++ b/runtime/autoload/python.vim
@@ -3,13 +3,35 @@
let s:keepcpo= &cpo
set cpo&vim
+" need to inspect some old g:pyindent_* variables to be backward compatible
+let g:python_indent = extend(get(g:, 'python_indent', {}), #{
+ \ closed_paren_align_last_line: v:true,
+ \ open_paren: get(g:, 'pyindent_open_paren', 'shiftwidth() * 2'),
+ \ nested_paren: get(g:, 'pyindent_nested_paren', 'shiftwidth()'),
+ \ continue: get(g:, 'pyindent_continue', 'shiftwidth() * 2'),
+ "\ searchpair() can be slow, limit the time to 150 msec or what is put in
+ "\ g:python_indent.searchpair_timeout
+ \ searchpair_timeout: get(g:, 'pyindent_searchpair_timeout', 150),
+ "\ Identing inside parentheses can be very slow, regardless of the searchpair()
+ "\ timeout, so let the user disable this feature if he doesn't need it
+ \ disable_parentheses_indenting: get(g:, 'pyindent_disable_parentheses_indenting', v:false),
+ \ }, 'keep')
+
+let s:maxoff = 50 " maximum number of lines to look backwards for ()
+
+function s:SearchBracket(fromlnum, flags)
+ return searchpairpos('[[({]', '', '[])}]', a:flags,
+ \ {-> synstack('.', col('.'))
+ \ ->map({_, id -> id->synIDattr('name')})
+ \ ->match('\%(Comment\|Todo\|String\)$') >= 0},
+ \ [0, a:fromlnum - s:maxoff]->max(), g:python_indent.searchpair_timeout)
+endfunction
+
" See if the specified line is already user-dedented from the expected value.
function s:Dedented(lnum, expected)
return indent(a:lnum) <= a:expected - shiftwidth()
endfunction
-let s:maxoff = 50 " maximum number of lines to look backwards for ()
-
" Some other filetypes which embed Python have slightly different indent
" rules (e.g. bitbake). Those filetypes can pass an extra funcref to this
" function which is evaluated below.
@@ -22,7 +44,7 @@ function python#GetIndent(lnum, ...)
if a:lnum > 1 && getline(a:lnum - 2) =~ '\\$'
return indent(a:lnum - 1)
endif
- return indent(a:lnum - 1) + (exists("g:pyindent_continue") ? eval(g:pyindent_continue) : (shiftwidth() * 2))
+ return indent(a:lnum - 1) + get(g:, 'pyindent_continue', g:python_indent.continue)->eval()
endif
" If the start of the line is in a string don't change the indent.
@@ -39,30 +61,34 @@ function python#GetIndent(lnum, ...)
return 0
endif
- call cursor(plnum, 1)
-
- " Identing inside parentheses can be very slow, regardless of the searchpair()
- " timeout, so let the user disable this feature if he doesn't need it
- let disable_parentheses_indenting = get(g:, "pyindent_disable_parentheses_indenting", 0)
-
- if disable_parentheses_indenting == 1
+ if g:python_indent.disable_parentheses_indenting == 1
let plindent = indent(plnum)
let plnumstart = plnum
else
- " searchpair() can be slow sometimes, limit the time to 150 msec or what is
- " put in g:pyindent_searchpair_timeout
- let searchpair_stopline = 0
- let searchpair_timeout = get(g:, 'pyindent_searchpair_timeout', 150)
+ " Indent inside parens.
+ " Align with the open paren unless it is at the end of the line.
+ " E.g.
+ " open_paren_not_at_EOL(100,
+ " (200,
+ " 300),
+ " 400)
+ " open_paren_at_EOL(
+ " 100, 200, 300, 400)
+ call cursor(a:lnum, 1)
+ let [parlnum, parcol] = s:SearchBracket(a:lnum, 'nbW')
+ if parlnum > 0
+ if parcol != col([parlnum, '$']) - 1
+ return parcol
+ elseif getline(a:lnum) =~ '^\s*[])}]' && !g:python_indent.closed_paren_align_last_line
+ return indent(parlnum)
+ endif
+ endif
+
+ call cursor(plnum, 1)
" If the previous line is inside parenthesis, use the indent of the starting
" line.
- " Trick: use the non-existing "dummy" variable to break out of the loop when
- " going too far back.
- let parlnum = searchpair('(\|{\|\[', '', ')\|}\|\]', 'nbW',
- \ "line('.') < " . (plnum - s:maxoff) . " ? dummy :"
- \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
- \ . " =~ '\\(Comment\\|Todo\\|String\\)$'",
- \ searchpair_stopline, searchpair_timeout)
+ let [parlnum, _] = s:SearchBracket(plnum, 'nbW')
if parlnum > 0
if a:0 > 0 && ExtraFunc(parlnum)
" We may have found the opening brace of a bitbake Python task, e.g. 'python do_task {'
@@ -85,11 +111,7 @@ function python#GetIndent(lnum, ...)
" + b
" + c)
call cursor(a:lnum, 1)
- let p = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW',
- \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :"
- \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
- \ . " =~ '\\(Comment\\|Todo\\|String\\)$'",
- \ searchpair_stopline, searchpair_timeout)
+ let [p, _] = s:SearchBracket(a:lnum, 'bW')
if p > 0
if a:0 > 0 && ExtraFunc(p)
" Currently only used by bitbake
@@ -109,15 +131,13 @@ function python#GetIndent(lnum, ...)
else
if p == plnum
" When the start is inside parenthesis, only indent one 'shiftwidth'.
- let pp = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW',
- \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :"
- \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
- \ . " =~ '\\(Comment\\|Todo\\|String\\)$'",
- \ searchpair_stopline, searchpair_timeout)
+ let [pp, _] = s:SearchBracket(a:lnum, 'bW')
if pp > 0
- return indent(plnum) + (exists("g:pyindent_nested_paren") ? eval(g:pyindent_nested_paren) : shiftwidth())
+ return indent(plnum)
+ \ + get(g:, 'pyindent_nested_paren', g:python_indent.nested_paren)->eval()
endif
- return indent(plnum) + (exists("g:pyindent_open_paren") ? eval(g:pyindent_open_paren) : (shiftwidth() * 2))
+ return indent(plnum)
+ \ + get(g:, 'pyindent_open_paren', g:python_indent.open_paren)->eval()
endif
if plnumstart == p
return indent(plnum)
@@ -136,12 +156,16 @@ function python#GetIndent(lnum, ...)
" If the last character in the line is a comment, do a binary search for
" the start of the comment. synID() is slow, a linear search would take
" too long on a long line.
- if synIDattr(synID(plnum, pline_len, 1), "name") =~ "\\(Comment\\|Todo\\)$"
+ if synstack(plnum, pline_len)
+ \ ->map({_, id -> id->synIDattr('name')})
+ \ ->match('\%(Comment\|Todo\)$') >= 0
let min = 1
let max = pline_len
while min < max
let col = (min + max) / 2
- if synIDattr(synID(plnum, col, 1), "name") =~ "\\(Comment\\|Todo\\)$"
+ if synstack(plnum, col)
+ \ ->map({_, id -> id->synIDattr('name')})
+ \ ->match('\%(Comment\|Todo\)$') >= 0
let max = col
else
let min = col + 1