]> Sergey Matveev's repositories - dotfiles.git/blob - vim/.vim/pack/stargrave/start/defsplit/autoload/defsplit.vim
Move to vim9script
[dotfiles.git] / vim / .vim / pack / stargrave / start / defsplit / autoload / defsplit.vim
1 vim9script
2
3 # Python function call splitter
4 # Maintainer: Sergey Matveev <stargrave@stargrave.org>
5 # License: GNU General Public License version 3 of the License or later
6 #
7 # This plugin splits Python function call on several lines.
8 #
9 #   def foobar(self, foo: str, bar: Some[thing, too]) -> None:
10 # to
11 #   def foobar(
12 #           self,
13 #           foo: str,
14 #           bar: Some[thing, too],
15 #   ) -> None:
16 #
17 #   foo(bar, baz)[0]
18 # to
19 #   foo(
20 #       bar,
21 #       baz,
22 #   )[0]
23 #
24 # You can un-split it using :Undefsplit command on the line where
25 # splitting starts.
26 #
27 # :Defsplit has optional argument specifying how many opening round
28 # parenthesis must be skipped.
29 # :Defsplit 1 on foo(baz(baz(...))) produces
30 #    foo(baz(
31 #        baz(...),
32 #    ))
33 #
34 # Also there is :Brsplit command behaving similarly, but it splits other
35 # types of brackets: "{}", "[]".
36
37 def BracketFind(brsAllowable: list<string>, line: string, offset: number): number
38     var possible: list<number>
39     var found: number
40     for bracket in brsAllowable
41         found = stridx(line, bracket, offset)
42         if found != -1 | possible += [found] | endif
43     endfor
44     return min(possible)
45 enddef
46
47 const Brs = {"(": ")", "[": "]", "{": "}"}
48
49 export def Do(brsAllowable: list<string>, singleLineComma: bool, ...args: list<number>)
50     var skip = len(args) == 0 ? 0 : args[1]
51     var shift = get(b:, "defsplit_shift", "    ")
52     var line = getline(".")
53     var prfx: string
54     for i in range(len(line))
55         if line[i] != shift[0]
56             prfx = strpart(line, 0, i)
57             if line[i : i + 3] ==# "def " ||
58                 line[i : i + 5] ==# "class " ||
59                 line[i : i + 9] ==# "async def "
60                 shift ..= shift
61             endif
62             break
63         endif
64     endfor
65     var brfirst = BracketFind(brsAllowable, line, 0)
66     var brlast = strridx(line, Brs[line[brfirst]])
67     while skip > 0
68         brfirst = BracketFind(brsAllowable, line, brfirst + 1)
69         brlast = strridx(line, Brs[line[brfirst]], brlast - 1)
70         skip -= 1
71     endwhile
72     var [curly, round, squar, outbuf] = [0, 0, 0, ""]
73     var ready = [strpart(line, 0, brfirst + 1)]
74     var trailingComma = v:true
75     for c in split(line[brfirst + 1 : brlast - 1], '\zs')
76         if c ==# "*" | trailingComma = v:false | endif
77         if outbuf ==# "" && c ==# " " | continue | endif
78         outbuf ..= c
79         if c ==# "," && !curly && !round && !squar
80             ready = add(ready, prfx .. shift .. outbuf)
81             outbuf = ""
82         elseif c ==# "[" | squar += 1
83         elseif c ==# "]" | squar -= 1
84         elseif c ==# "(" | round += 1
85         elseif c ==# ")" | round -= 1
86         elseif c ==# "{" | curly += 1
87         elseif c ==# "}" | curly -= 1
88         endif
89     endfor
90     if trailingComma && !(singleLineComma == v:true && len(ready) == 1)
91         outbuf = outbuf .. ","
92     endif
93     ready = add(ready, prfx .. shift .. outbuf)
94     ready = add(ready, prfx .. strpart(line, brlast))
95     append(line("."), ready)
96     normal "_dd
97 enddef