" Python function call splitter " Maintainer: Sergey Matveev " License: GNU General Public License version 3 of the License or later " " This plugin splits Python function call on several lines. " " def foobar(self, foo: str, bar: Some[thing, too]) -> None: " to " def foobar( " self, " foo: str, " bar: Some[thing, too], " ) -> None: " " foo(bar, baz)[0] " to " foo( " bar, " baz, " )[0] " " You can un-split it using :Undefsplit command on the line where " splitting starts. " " :Defsplit has optional argument specifying how many opening round " parenthesis must be skipped. " :Defsplit 1 on foo(baz(baz(...))) produces " foo(baz( " baz(...), " )) " " Also there is :Brsplit command behaving similarly, but it splits other " types of brackets: "{}", "[]". function! s:bracket_find(brs_allowable, line, offset) let possible = [] for bracket in a:brs_allowable let found = stridx(a:line, bracket, a:offset) if found != -1 | let possible += [found] | endif endfor return min(possible) endfunction function! defsplit#do(brs_allowable, single_line_comma, ...) abort if a:0 == 0 | let skip = 0 | else | let skip = str2nr(a:1) | endif let shift = get(b:, "defsplit_shift", " ") let line = getline(".") for i in range(len(line)) if line[i] != shift[0] let prfx = strpart(line, 0, i) if line[i : i+3] ==# "def " || \line[i : i+5] ==# "class " || \line[i : i+9] ==# "async def " let shift .= shift endif break endif endfor let brs = {"(": ")", "[": "]", "{": "}"} let brfirst = s:bracket_find(a:brs_allowable, line, 0) let brlast = strridx(line, brs[line[brfirst]]) while skip > 0 let brfirst = s:bracket_find(a:brs_allowable, line, brfirst + 1) let brlast = strridx(line, brs[line[brfirst]], brlast - 1) let skip -= 1 endwhile let [curly, round, squar, outbuf] = [0, 0, 0, ""] let ready = [strpart(line, 0, brfirst + 1)] let trailing_comma = 1 for c in split(line[brfirst + 1 : brlast-1], '\zs') if c ==# "*" | let trailing_comma = 0 | endif if outbuf ==# "" && c ==# " " | continue | endif let outbuf .= c if c ==# "," && !curly && !round && !squar let ready = add(ready, prfx . shift . outbuf) let outbuf = "" elseif c ==# "[" | let squar += 1 elseif c ==# "]" | let squar -= 1 elseif c ==# "(" | let round += 1 elseif c ==# ")" | let round -= 1 elseif c ==# "{" | let curly += 1 elseif c ==# "}" | let curly -= 1 endif endfor if trailing_comma && !(a:single_line_comma == v:true && len(ready) == 1) let outbuf = outbuf . "," endif let ready = add(ready, prfx . shift . outbuf) let ready = add(ready, prfx . strpart(line, brlast)) call append(line("."), ready) normal "_dd endfunction