Skip to content

Commit eb338b8

Browse files
authored
Fix/default params (#53)
* Fix default parameter problem * Fix signature arguments parser
1 parent 9e5ffb2 commit eb338b8

File tree

1 file changed

+72
-67
lines changed

1 file changed

+72
-67
lines changed

autoload/pydocstring.vim

+72-67
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ let s:regexs = {
2727
\ 'class': '^class\s\|^\s*class\s',
2828
\ 'async': '^async\s*def\s\|^\s*async\sdef\s',
2929
\ 'typed_args': '\([0-9A-Za-z_.]\+:[0-9A-Za-z_.]\+\|[0-9A-Za-z_.]\+\)\(,\|$\)',
30+
\ 'typed_bracket': '\(\w\+\s*:\s*\w\+\[.*\],\|\w\+\s*:\s*\w\+\[.*\]\)',
31+
\ 'typed_primitive': '\(\w\+:\s*\w\+,\|\w\+:\s*\w\+\)',
32+
\ 'none_typed': '\w\+,',
3033
\ }
3134

3235
function! s:readtmpl(type)
@@ -58,93 +61,95 @@ function! s:compare(lhs, rhs)
5861
endfunction
5962

6063
function! s:parse_args(args_str)
61-
let primitive_pos = 0
62-
let nested = 0
63-
let start_pos = 0
64-
let end_pos = 0
64+
" FIXME Very very work around.
65+
" If Python2 is dead, consider to use Python interface
66+
let args_str = copy(a:args_str)
6567
let args = []
66-
let primitives = []
68+
let pos = len(args_str)
6769

68-
" Extract none typed arguments or primitive arguments first.
70+
" If last argument is none-typed or bracket typed(e.g. List[int]),
71+
" Add to args first.
6972
while 1
70-
let primitives = matchstrpos(a:args_str, s:regexs['typed_args'], primitive_pos)
71-
if primitives[1] == -1
73+
let comma_idx = strridx(args_str, ',', pos)
74+
if comma_idx == -1
75+
" No multipul args left.
7276
break
73-
endif
74-
75-
if match(primitives[0], '[0-9A-Za-z_.]\+:[0-9A-Za-z_.]\+') == -1
76-
let separator_pos = strridx(a:args_str, ':', primitives[1])
77-
if a:args_str[primitives[1] - 1 : primitives[1] - 1] == '['
78-
" If `[` exist right before argument, current argument is inner of
79-
" braket. So this argument is not standalone argument.
80-
let primitive_pos = primitives[2]
81-
continue
82-
endif
83-
let braket_start_pos = stridx(a:args_str, '[', separator_pos)
84-
let next_separator_pos = stridx(a:args_str, ':', primitives[2])
85-
let braket_end_pos = strridx(a:args_str, ']', next_separator_pos)
86-
if next_separator_pos == -1
87-
if braket_start_pos == -1 && braket_end_pos == -1
88-
\ && a:args_str[primitives[1] : ] == primitives[0]
89-
" Current argument is last argument.
90-
else
91-
" Arguments are still remains.
92-
let primitive_pos = primitives[2]
93-
continue
77+
end
78+
let idx = stridx(args_str, ':', comma_idx)
79+
if idx == -1
80+
let last_arg = args_str[comma_idx + 1 :]
81+
if last_arg =~ ']'
82+
let sep_pos = strridx(args_str, ':', pos)
83+
let comma_idx = strridx(args_str, ',', sep_pos)
84+
if comma_idx == -1
85+
" One argument left
86+
break
9487
endif
95-
endif
88+
" Last argument is typed and have `[]`.
89+
let last_arg = args_str[comma_idx + 1 :]
90+
let last_arg = substitute(last_arg, ',\s*$', '', '')
9691

97-
if braket_start_pos < primitives[1] && primitives[1] < braket_end_pos
98-
" Current argument is inner of braket,
99-
" such as `List[str, str, str]`'s second `str`.
100-
let primitive_pos = primitives[2]
101-
continue
92+
call add(args, {'val': last_arg, 'start': comma_idx})
93+
let args_str = args_str[ : comma_idx]
94+
95+
break
96+
else
97+
" Last argument is not none-typed.
98+
let last_arg = substitute(last_arg, ',\s*$', '', '')
99+
call add(args, {'val': last_arg, 'start': comma_idx})
100+
let arg_length = len(last_arg)
101+
let args_str = args_str[ : comma_idx]
102102
endif
103+
let pos = comma_idx - 1
104+
else
105+
break
103106
endif
104-
105-
" `[: -1] trims `,`.
106-
let arg = primitives[0][: -1]
107-
let arg = substitute(arg, ',$', '', '')
108-
109-
call add(args, {'val': arg, 'start': primitives[1]})
110-
" Move current position.
111-
let primitive_pos = primitives[2]
112107
endwhile
113108

114-
" Parse nested typed args.
115109
while 1
116-
let start_idx = match(a:args_str, '\[', start_pos)
117-
let end_idx = match(a:args_str, '\]', end_pos)
110+
"" Parse like `arg: List[str]`
111+
let bracket_match = match(args_str, s:regexs['typed_bracket'])
112+
if bracket_match != -1
113+
let ret = matchstrpos(args_str, s:regexs['typed_bracket'])
114+
let arg_length = len(ret[0])
115+
let pos = printf('@%s%s,', ret[1], repeat(' ', arg_length - len(arg_length) - 1))
116+
117+
let args_str = substitute(args_str, s:regexs['typed_bracket'], pos, '')
118+
let arg = substitute(ret[0], ',$', '', '')
119+
call add(args, {'val': arg, 'start': ret[1]})
120+
endif
118121

119-
if start_idx == -1 && end_idx == -1
120-
break
122+
" Parse like `arg1: str`
123+
let primitive_match = match(args_str, s:regexs['typed_primitive'])
124+
if primitive_match != -1
125+
let ret = matchstrpos(args_str, s:regexs['typed_primitive'])
126+
let arg_length = len(ret[0])
127+
let pos = printf('@%s%s,', ret[1], repeat(' ', arg_length - len(arg_length) - 2))
128+
let args_str = substitute(args_str, s:regexs['typed_primitive'], pos, '')
129+
let arg = substitute(ret[0], ',$', '', '')
130+
call add(args, {'val': arg, 'start': ret[1]})
121131
endif
122132

123-
if end_pos > start_idx
124-
" For nested. e.g. `arg: List[List[List[int, int], List[List[int, int]]]`.
125-
let idx = strridx(a:args_str, ',', nested)
126-
if idx == -1
127-
let idx = strridx(a:args_str, '(', nested)
128-
endif
129-
let arg = a:args_str[idx + 1 : end_idx]
130-
" Override previous arg by complete one.
131-
let args[-1] = {'val': arg, 'start': idx + 1}
132-
else
133-
let idx = strridx(a:args_str, ',', start_idx)
134-
if idx == -1
135-
let idx = strridx(a:args_str, '(', start_idx)
133+
" Parse like `arg`
134+
let none_typed_match = match(args_str, s:regexs['none_typed'])
135+
if none_typed_match != -1
136+
if match(args_str, '[A-Za-z]') == -1
137+
break
136138
endif
137139

138-
let arg = a:args_str[idx + 1 : end_idx]
139-
call add(args, {'val': arg, 'start': idx + 1})
140-
let nested = start_idx
140+
let ret = matchstrpos(args_str, s:regexs['none_typed'])
141+
let arg_length = len(ret[0])
142+
let pos = printf('@%s%s,', ret[1], repeat(' ', arg_length - len(arg_length) - 1))
143+
let args_str = substitute(args_str, s:regexs['none_typed'], pos, '')
144+
let arg = substitute(ret[0], ',$', '', '')
145+
call add(args, {'val': arg, 'start': ret[1]})
141146
endif
142147

143-
let start_pos = start_idx + 1
144-
let end_pos = end_idx + 1
148+
if bracket_match == -1 && primitive_match == -1 && none_typed_match == -1
149+
break
150+
endif
145151
endwhile
146152

147-
" Sort by argument start position.
148153
call sort(args, 's:compare')
149154
return map(args, {i, v -> substitute(v['val'], ',', ', ', 'g')})
150155
endfunction

0 commit comments

Comments
 (0)