@@ -106,6 +106,7 @@ endfunction
106106function s: PythonCompiler .__init__ ()
107107 let self .indent = [' ' ]
108108 let self .lines = []
109+ let self .in_class = 0
109110endfunction
110111
111112function s: PythonCompiler .out (... )
@@ -324,31 +325,66 @@ function s:PythonCompiler.compile_excmd(node)
324325 throw ' NotImplemented: excmd'
325326endfunction
326327
328+ function s: PythonCompiler .insert_empty_lines_before_comment (count )
329+ " Find start of preceding comment (block).
330+ let comment_start = 0
331+ let len_lines = len (self .lines )
332+ if len_lines
333+ while 1
334+ let line = get (self .lines , comment_start - 1 , ' ' )
335+ if line !~# ' ^\s*#'
336+ break
337+ endif
338+ let comment_start -= 1
339+ " Adjust indentation to current level.
340+ let self .lines [comment_start] = substitute (line , ' ^\s\+' , self .indent [0 ], ' ' )
341+ endwhile
342+
343+ if comment_start != 0
344+ let comment_start = len_lines + comment_start
345+ endif
346+ endif
347+
348+ if comment_start
349+ for c in range (a: count )
350+ call insert (self .lines , ' ' , comment_start)
351+ endfor
352+ else
353+ for c in range (a: count )
354+ call self .emptyline ()
355+ endfor
356+ endif
357+ endfunction
358+
327359function s: PythonCompiler .compile_function (node)
328360 let left = self .compile (a: node .left )
329361 let rlist = map (a: node .rlist, ' self.compile(v:val)' )
330362 if ! empty (rlist) && rlist[-1 ] == ' ...'
331363 let rlist[-1 ] = ' *a000'
332364 endif
365+
333366 if left = ~ ' ^\(VimLParser\|ExprTokenizer\|ExprParser\|LvalueParser\|StringReader\|Compiler\|RegexpParser\)\.'
334367 let left = matchstr (left , ' \.\zs.*' )
335368 if left == ' new'
336369 return
337370 endif
371+ call self .insert_empty_lines_before_comment (1 )
338372 call insert (rlist, ' self' )
339- call self .incindent (' ' )
340373 call self .out (' def %s(%s):' , left , join (rlist, ' , ' ))
341374 call self .incindent (' ' )
342375 call self .compile_body (a: node .body)
343376 call self .decindent ()
344- call self .decindent ()
345377 else
378+ if self .in_class
379+ let self .in_class = 0
380+ call self .decindent ()
381+ endif
382+ call self .insert_empty_lines_before_comment (2 )
346383 call self .out (' def %s(%s):' , left , join (rlist, ' , ' ))
347384 call self .incindent (' ' )
348385 call self .compile_body (a: node .body)
349386 call self .decindent ()
350387 endif
351- call self .emptyline ()
352388endfunction
353389
354390function s: PythonCompiler .compile_delfunction (node)
@@ -375,20 +411,26 @@ function s:PythonCompiler.compile_let(node)
375411 let right = self .compile (a: node .right )
376412 if a: node .left isnot s: NIL
377413 let left = self .compile (a: node .left )
378- if left == ' LvalueParser'
379- call self .out (' class LvalueParser(ExprParser):' )
380- return
381- elseif left = ~ ' ^\(VimLParser\|ExprTokenizer\|ExprParser\|LvalueParser\|StringReader\|Compiler\|RegexpParser\)$'
382- call self .out (' class %s:' , left )
383- return
384- elseif left = ~ ' ^\(VimLParser\|ExprTokenizer\|ExprParser\|LvalueParser\|StringReader\|Compiler\|RegexpParser\)\.'
414+ if left == # ' LvalueParser'
415+ let class_def = ' LvalueParser(ExprParser)'
416+ elseif left = ~# ' ^\(VimLParser\|ExprTokenizer\|ExprParser\|LvalueParser\|StringReader\|Compiler\|RegexpParser\)$'
417+ let class_def = left
418+ elseif left = ~# ' ^\(VimLParser\|ExprTokenizer\|ExprParser\|LvalueParser\|StringReader\|Compiler\|RegexpParser\)\.'
385419 let left = matchstr (left , ' \.\zs.*' )
386- call self .incindent (' ' )
387420 call self .out (' %s %s %s' , left , op , right )
388- call self .decindent ()
421+ return
422+ else
423+ call self .out (' %s %s %s' , left , op , right )
389424 return
390425 endif
391- call self .out (' %s %s %s' , left , op , right )
426+
427+ if self .in_class
428+ call self .decindent ()
429+ endif
430+ call self .insert_empty_lines_before_comment (2 )
431+ call self .out (' class %s:' , class_def)
432+ let self .in_class = 1
433+ call self .incindent (' ' )
392434 else
393435 let list = map (a: node .list , ' self.compile(v:val)' )
394436 if a: node .rest isnot s: NIL
@@ -763,7 +805,7 @@ function s:PythonCompiler.compile_list(node)
763805endfunction
764806
765807function s: PythonCompiler .compile_dict (node)
766- let value = map (a: node .value, ' self.compile(v:val[0]) . ":" . self.compile(v:val[1])' )
808+ let value = map (a: node .value, ' self.compile(v:val[0]) . ": " . self.compile(v:val[1])' )
767809 if empty (value)
768810 return ' AttributeDict({})'
769811 else
@@ -828,14 +870,16 @@ let s:viml_builtin_functions = map(copy(s:VimLParser.builtin_functions), 'v:val.
828870let s: script_dir = expand (' <sfile>:h' )
829871function ! s: convert (in , out)
830872 let vimlfunc = fnamemodify (s: script_dir . ' /vimlfunc.py' , ' :p' )
831- let head = readfile (vimlfunc)
873+ let head = readfile (vimlfunc) + [ ' ' , ' ' ]
832874 try
833875 let r = s: StringReader .new (readfile (a: in ))
834876 let p = s: VimLParser .new ()
835877 let c = s: PythonCompiler .new ()
836878 let lines = c .compile (p .parse (r ))
837879 unlet lines [0 : index (lines , ' NIL = []' ) - 1 ]
838880 let tail = [
881+ \ ' ' ,
882+ \ ' ' ,
839883 \ ' if __name__ == '' __main__'' :' ,
840884 \ ' main()' ,
841885 \ ]
0 commit comments