@@ -24,10 +24,10 @@ if !exists('g:pydocstring_ignore_args_pattern')
2424endif
2525
2626let s: regexs = {
27- \ ' def' : ' ^def\s\|^\s*def\s' ,
28- \ ' class' : ' ^class\s\|^\s*class\s' ,
29- \ ' async' : ' ^async\s*def\s\|^\s*async\sdef\s'
30- \ }
27+ \ ' def' : ' ^def\s\|^\s*def\s' ,
28+ \ ' class' : ' ^class\s\|^\s*class\s' ,
29+ \ ' async' : ' ^async\s*def\s\|^\s*async\sdef\s'
30+ \ }
3131
3232function ! s: readtmpl (type )
3333 let tmpldir = g: pydocstring_templates_dir
@@ -44,33 +44,54 @@ function! s:readtmpl(type)
4444 return tmpl
4545endfunction
4646
47+ function ! s: parseClass (line )
48+ " For class definition, we just simply need to extract the class name. We can
49+ " do that by just delete every white spaces and the whole parenthesics if
50+ " existed.
51+ let header = substitute (a: line , ' \s\|(.*\|:' , ' ' , ' g' )
52+ let parse = {' type' : ' class' , ' header' : header, ' args' : ' ' , ' returnType' : ' ' }
53+ return parse
54+ endfunction
55+
56+ function ! s: parseFunc (type , line )
57+ let header = substitute (a: line , ' \s\|(.*\|:' , ' ' , ' g' )
58+
59+ let argsStr = substitute (a: line , ' \s\|.*(\|).*' , ' ' , ' g' )
60+ let args = split (argsStr, ' ,' )
61+
62+ let arrowIndex = match (a: line , " ->" )
63+ if arrowIndex != -1
64+ let substring = strpart (a: line , arrowIndex+ 2 )
65+ let returnType = substitute (substring, ' \W*' , ' ' , ' g' )
66+ else
67+ let returnType = ' '
68+ endif
69+
70+ let parse = {' type' : a: type , ' header' : header, ' args' : args , ' returnType' : returnType}
71+ return parse
72+ endfunction
73+
4774function ! s: parse (line )
4875 let str = substitute (a: line , ' \\' , ' ' , ' g' )
76+ let str = substitute (a: line , ' #.*$' , ' ' , ' g' )
4977 let type = ' '
78+
79+ if str = ~ s: regexs [' class' ]
80+ let str = substitute (str, s: regexs [' class' ], ' ' , ' ' )
81+ return s: parseClass (str)
82+ endif
83+
5084 if str = ~ s: regexs [' def' ]
5185 let str = substitute (str, s: regexs [' def' ], ' ' , ' ' )
5286 let type = ' def'
5387 elseif str = ~ s: regexs [' async' ]
5488 let str = substitute (str, s: regexs [' async' ], ' ' , ' ' )
5589 let type = ' def'
56- elseif str = ~ s: regexs [' class' ]
57- let str = substitute (str, s: regexs [' class' ], ' ' , ' ' )
58- let type = ' class'
5990 else
6091 return 0
6192 endif
62- let str = substitute (str, ' \s\|):\|)\s:' , ' ' , ' g' )
6393
64- let strs = split (str, ' (' )
65- let header = strs[0 ]
66- let args = []
67- if len (strs) > 1
68- let args = split (strs[1 ], ' ,' )
69- end
70-
71- let parse = {' type' : type , ' header' : header, ' args' : args }
72-
73- return parse
94+ return s: parseFunc (type , str)
7495endfunction
7596
7697" Vim Script does not support lambda function...
@@ -81,74 +102,101 @@ function! s:readoneline(indent, prefix)
81102 return tmpl
82103endfunction
83104
105+ " Check if we should show args in the docstring. We won't do that in case:
106+ " - There's no args.
107+ " - There's only one arg that match with g:pydocstring_ignore_args_pattern
108+ function ! s: shouldIncludeArgs (args )
109+ if len (a: args ) == 0
110+ return 0
111+ endif
112+
113+ if len (a: args ) == 1 && a: args [0 ] = ~ g: pydocstring_ignore_args_pattern
114+ return 0
115+ endif
116+
117+ return 1
118+ endfunction
119+
120+ " Check if we should use one line docstring.
121+ " There's several cases:
122+ " - Type is `class`
123+ " - No return type and no args.
124+ " - No return type and the only one args is `self` or `cls` (defined by
125+ " g:pydocstring_ignore_args_pattern
126+ "
127+ " Return 1 for True, and 0 for False
128+ function ! s: shouldUseOneLineDocString (type , args , returnType)
129+ if a: type != ' def'
130+ return 1
131+ endif
132+
133+ if a: returnType != ' '
134+ return 0
135+ endif
136+
137+ return ! s: shouldIncludeArgs (a: args )
138+ endfunction
139+
84140function ! s: builddocstring (strs, indent , nested_indent)
85141 let type = a: strs [' type' ]
86142 let prefix = a: strs [' header' ]
87143 let args = a: strs [' args' ]
144+ let returnType = a: strs [' returnType' ]
145+
146+ if s: shouldUseOneLineDocString (type , args , returnType)
147+ return s: readoneline (a: indent , prefix)
148+ endif
149+
88150 let tmpl = ' '
89- if len (args ) > 0 && type == ' def'
90- let docstrings = []
91- let lines = s: readtmpl (' multi' )
92- for line in lines
93- if line = ~ ' {{_header_}}'
94- let header = substitute (line , ' {{_header_}}' , prefix, ' ' )
95- call add (docstrings, a: indent . header)
96- elseif line = ~ ' {{_arg_}}'
97- if len (args ) == 0
98- let tmpl = s: readoneline (a: indent , prefix)
99- return tmpl
100- endif
101-
102- if args [0 ] = ~ g: pydocstring_ignore_args_pattern && len (args ) == 1
103- let tmpl = s: readoneline (a: indent , prefix)
104- return tmpl
105- endif
106-
107- let arglist = []
151+ let docstrings = []
152+ let lines = s: readtmpl (' multi' )
153+ for line in lines
154+ if line = ~ ' {{_header_}}'
155+ let header = substitute (line , ' {{_header_}}' , prefix, ' ' )
156+ call add (docstrings, a: indent . header)
157+ call add (docstrings, ' ' )
158+ elseif line = ~ ' {{_args_}}'
159+ if len (args ) != 0
108160 for arg in args
109161 let arg = substitute (arg, ' =.*$' , ' ' , ' ' )
110162 if arg = ~ g: pydocstring_ignore_args_pattern
111163 continue
112164 endif
113- let arg = substitute (line , ' {{_arg_}}' , arg, ' g' )
114- let arg = substitute (arg, ' {{_lf_}}' , " \n " , ' ' )
115- let arg = substitute (arg, ' {{_indent_}}' , a: indent , ' g' )
116- let arg = substitute (arg, ' {{_nested_indent_}}' , a: nested_indent , ' g' )
117- call add (docstrings, a: indent . arg)
118- endfor
119- elseif line = ~ ' {{_indent_}}'
120- let arg = substitute (line , ' {{_indent_}}' , a: indent , ' g' )
121- call add (docstrings, arg)
122- elseif line = ~ ' {{_args_}}'
123- if len (args ) == 0
124- let tmpl = s: readoneline (a: indent , prefix)
125- return tmpl
126- endif
127-
128- if args [0 ] = ~ g: pydocstring_ignore_args_pattern && len (args ) == 1
129- let tmpl = s: readoneline (a: indent , prefix)
130- return tmpl
131- endif
132-
133- let arglist = []
134- for arg in args
135- let arg = substitute (arg, ' =.*$' , ' ' , ' ' )
136- if arg = ~ g: pydocstring_ignore_args_pattern
137- continue
165+ let template = line
166+
167+ if match (arg, ' :' ) != -1
168+ let argTemplate = s: readtmpl (' arg' )
169+ let argTemplate = join (s: readtmpl (' arg' ), ' ' )
170+ let argParts = split (arg, ' :' )
171+ let argTemplate = substitute (argTemplate, ' {{_name_}}' , argParts[0 ], ' ' )
172+ let arg = substitute (argTemplate, ' {{_type_}}' , argParts[1 ], ' ' )
138173 endif
139- let arg = substitute (line , ' {{_args_}}' , arg, ' ' )
140- call add (docstrings, a: indent . arg)
174+
175+ let template = substitute (template, ' {{_args_}}' , arg, ' g' )
176+ let template = substitute (template, ' {{_lf_}}' , ' \n' , ' ' )
177+ let template = substitute (template, ' {{_indent_}}' , a: indent , ' g' )
178+ let template = substitute (template, ' {{_nested_indent_}}' , a: nested_indent , ' g' )
179+ call add (docstrings, a: indent . template)
141180 endfor
142- elseif line == ' """'
143- call add (docstrings, a: indent . line )
181+ call add (docstrings, ' ' )
182+ endif
183+ elseif line = ~ ' {{_indent_}}'
184+ let arg = substitute (line , ' {{_indent_}}' , a: indent , ' g' )
185+ call add (docstrings, arg)
186+ elseif line = ~ ' {{_returnType_}}'
187+ if strlen (returnType) != 0
188+ let rt = substitute (line , ' {{_returnType_}}' , returnType, ' ' )
189+ call add (docstrings, a: indent . rt)
144190 else
145- call add (docstrings, line )
191+ call remove (docstrings, -1 )
146192 endif
147- endfor
148- let tmpl = substitute (join (docstrings, " \n " ), " \n $" , ' ' , ' ' )
149- else
150- let tmpl = s: readoneline (a: indent , prefix)
151- endif
193+ elseif line == ' """'
194+ call add (docstrings, a: indent . line )
195+ else
196+ call add (docstrings, line )
197+ endif
198+ endfor
199+ let tmpl = substitute (join (docstrings, " \n " ), " \n $" , ' ' , ' ' )
152200
153201 return tmpl
154202endfunction
@@ -159,7 +207,7 @@ function! pydocstring#insert()
159207 let indent = matchstr (line , ' ^\(\s*\)' )
160208
161209 let startpos = line (' .' )
162- let insertpos = search (' \:\+ $' )
210+ let insertpos = search (' \:\(\s*#.*\)* $' )
163211 let lines = join (getline (startpos, insertpos))
164212
165213 let docstring = s: parse (lines )
0 commit comments