66# Uses context sensitive completions.
77#
88# TODO:
9- # -autocomplete classes after expand
10- # -variable read in error: var bool bOne, bTwo, bTrhee; doesn't work yet
11- # -problematic function declaration:
12- # native(548) noexport final function bool FastTrace
13- # (
14- # vector TraceEnd,
15- # optional vector TraceStart,
16- # optional vector BoxExtent,
17- # optional bool bTraceBullet
18- # );
9+ # -autocomplete classes after extends
1910# -load auto complete suggestions from current object before a '.'
2011# -same for goto definition
2112#
@@ -68,17 +59,11 @@ def run(self, edit):
6859 window = sublime .active_window ()
6960
7061 global last_location , current_location
71- if last_location != None :
72- if current_location == active_file :
73- window .open_file (last_location , sublime .ENCODED_POSITION )
74- window .open_file (last_location , sublime .ENCODED_POSITION )
75- last_location = None
76- return
77- last_location = None
7862
79- # Save current position so we can return to it
80- row , col = self .view .rowcol (self .view .sel ()[0 ].begin ())
81- last_location = "%s:%d" % (active_file , row + 1 )
63+ if last_location == None :
64+ # Save current position so we can return to it
65+ row , col = self .view .rowcol (self .view .sel ()[0 ].begin ())
66+ last_location = "%s:%d" % (active_file , row + 1 )
8267
8368 function = self .get_function (word )
8469 if function != None :
@@ -107,7 +92,18 @@ def run(self, edit):
10792 else :
10893 print _class [1 ] + 'does not exist'
10994 return
110- print_to_panel (self .view , word + " not found" )
95+
96+ row , col = self .view .rowcol (self .view .sel ()[0 ].begin ())
97+ if last_location != None and (word .strip () == "" or col == 0 ):
98+ if current_location == active_file :
99+ window .open_file (last_location , sublime .ENCODED_POSITION )
100+ window .open_file (last_location , sublime .ENCODED_POSITION )
101+ last_location = None
102+ return
103+ last_location = None
104+ else :
105+ print_to_panel (self .view , word + " not found" )
106+
111107 sublime .set_timeout (lambda : self .hide_panel (self .view ), OPEN_TIME * 1000 )
112108
113109 def get_function (self , name ):
@@ -151,7 +147,8 @@ def clear(self):
151147
152148 def add_func (self , function_modifiers , return_type , function_name , arguments , line_number , file_name , description = "" , is_funct = 1 ):
153149 if self .get_function (function_name ) == None :
154- self ._functions .append (Function (function_modifiers , return_type , function_name , arguments , line_number + 1 , file_name , description , is_funct ))
150+ if function_name != "" :
151+ self ._functions .append (Function (function_modifiers , return_type , function_name , arguments , line_number + 1 , file_name , description , is_funct ))
155152
156153 def add_var (self , var_modifiers , var_name , comment , line_number , file_name , description = "" ):
157154 if self .get_variable (var_name ) == None :
@@ -178,11 +175,11 @@ def save_functions_to_list(self, filename):
178175 def get_autocomplete_list (self , word , b_only_var = False ):
179176 autocomplete_list = []
180177 for variable in self ._variables :
181- if word in variable .name ():
178+ if word . lower () in variable .name (). lower ():
182179 autocomplete_list .append ((variable .name (), variable .name ()))
183180 if not b_only_var :
184181 for function in self ._functions :
185- if word in function .function_name ():
182+ if word . lower () in function .function_name (). lower ():
186183 function_str = function .function_name () + '\t (' + function .arguments () + ')' # add arguments
187184 autocomplete_list .append ((function_str , function .function_name ()))
188185
@@ -242,11 +239,12 @@ def on_query_completions(self, view, prefix, locations):
242239 if current_file != None and is_unrealscript_file (current_file ):
243240 # if is in defaultproperties, only get variables:
244241 line_number = 1000000
245- with open (current_file , 'rU' ) as file_lines :
246- for i , line in enumerate (file_lines ):
247- if "defaultproperties" in line .lower ():
248- line_number = i + 1
249- break
242+ defaultproperties_region = view .find ('defaultproperties' , 0 , sublime .IGNORECASE )
243+ if defaultproperties_region :
244+ (line_number , col ) = view .rowcol (defaultproperties_region .a )
245+ else :
246+ return self .get_autocomplete_list (prefix )
247+
250248 (row , col ) = view .rowcol (view .sel ()[0 ].begin ())
251249 if row > line_number :
252250 return self .get_autocomplete_list (prefix , True )
@@ -383,20 +381,76 @@ def search_file(self, path, file_name):
383381 def save_functions (self , file_name ):
384382 with open (file_name , 'rU' ) as file_lines :
385383 current_documentation = ""
386-
384+ long_line = ""
385+ b_function = True
386+ bBracesNotOnSameLine = False
387387 for i , line in enumerate (file_lines ):
388- if "/**" in line or "//" in line :
388+ if line == "" :
389+ continue
390+ if "/**" in line : # start capturing documentation
391+ current_documentation = line
392+ elif line .lstrip () != "" and "/" == line .lstrip ()[0 ] and current_documentation == "" :
389393 current_documentation = line
390394
391- if "function" in line .lower (): # get possible lines containing functions
392- function_matches = re .search (r'(.*)\bfunction \b(\b.*\b)(.+)\((.*)\)' , line ) # search for: 1: function modifiers, 2: return type, 3: function name, 4: arguments
393- if function_matches != None :
394- if function_matches .group (3 ) == None or function_matches .group (3 ) == " " :
395- pass
396- #print "not a real function!!! ", line # some wrong lines
395+ if line .lstrip () != "" and (line .lstrip ()[0 ] == '*' or line .lstrip ()[0 ] == '/' ): # add to documentation
396+ if current_documentation != line :
397+ current_documentation += line
398+ continue
399+
400+ if bBracesNotOnSameLine :
401+ if ')' in line :
402+ bBracesNotOnSameLine = False
403+ new_line = ' ' .join (long_line .split ())
404+ function_matches = self .extract_complicated_function (new_line , b_function )
405+ self .collector .add_func (function_matches [0 ], function_matches [1 ], function_matches [2 ], function_matches [3 ], i , file_name , current_documentation , b_function )
406+ current_documentation = ""
407+ continue
408+ else :
409+ long_line += line
410+
411+ if "function" in line .lower () or "event" in line .lower (): # get possible lines containing functions / events
412+ if "function" in line .lower ():
413+ b_function = True
414+ regex_str = r'(.*)\bfunction \b(\b.*\b)(.+)\((.*)\)'
415+ elif "event" in line .lower ():
416+ b_function = False
417+ regex_str = r'(.*)\bevent \b(\b.*\b)(.+)\((.*)\)'
418+
419+ matches = re .search (regex_str , line ) # search for: 1: modifiers, 2: return type, 3: name, 4: arguments
420+ if matches != None :
421+ if matches .group (3 ) == None or matches .group (3 ) == " " : # fail
422+ matches = self .extract_complicated_function (line , b_function ) # try again without regex
423+ self .collector .add_func (matches [0 ], matches [1 ], matches [2 ], matches [3 ], i , file_name , current_documentation , b_function )
424+ current_documentation = ""
425+ continue
397426 else :
398- self .collector .add_func (function_matches .group (1 ), function_matches .group (2 ), function_matches .group (3 ), function_matches .group (4 ), i , file_name , current_documentation )
427+ self .collector .add_func (matches .group (1 ), matches .group (2 ), matches .group (3 ), matches .group (4 ), i , file_name , current_documentation , b_function )
399428 current_documentation = ""
429+ continue
430+
431+ else : # epic fail of my regex, try with python:
432+ if b_function :
433+ if 'function' not in line .split ('//' )[0 ]: # the keyword was in the comments
434+ continue
435+ else :
436+ if 'event' not in line .split ('//' )[0 ]:
437+ continue
438+
439+ new_line = ' ' .join (line .split ())
440+ matches = re .search (regex_str , new_line ) # search for: 1: modifiers, 2: return type, 3: name, 4: arguments
441+ if matches != None :
442+ if matches .group (3 ) == None or matches .group (3 ) == " " :
443+ matches = self .extract_complicated_function (new_line , b_function )
444+ self .collector .add_func (matches [0 ], matches [1 ], matches [2 ], matches [3 ], i , file_name , current_documentation , b_function )
445+ current_documentation = ""
446+ continue
447+ else :
448+ self .collector .add_func (matches .group (1 ), matches .group (2 ), matches .group (3 ), matches .group (4 ), i , file_name , current_documentation , b_function )
449+ current_documentation = ""
450+ continue
451+ else :
452+ bBracesNotOnSameLine = True
453+ long_line = new_line
400454
401455 elif "var" in line .lower (): # get possible lines containing variables
402456 # 1: vartype, 2: name, 3: documentation
@@ -422,19 +476,31 @@ def save_functions(self, file_name):
422476 self .collector .add_var (var_line , name , doc_line , i , file_name , current_documentation )
423477 current_documentation = ""
424478
425- elif "event" in line .lower ():
426- event_matches = re .search (r'(.*)\bevent \b(\b.*\b)(.+)\((.*)\)' , line ) # search for: 1: event modifiers, 2: return type, 3: event name, 4: arguments
427- if event_matches != None :
428- if event_matches .group (3 ) == None or event_matches .group (3 ) == " " :
429- pass
430- # print "not a real event!!! ", line # some wrong lines
431- else :
432- self .collector .add_func (event_matches .group (1 ), event_matches .group (2 ), event_matches .group (3 ), event_matches .group (4 ), i , file_name , current_documentation , 0 )
433- current_documentation = ""
479+ # manual extraction, because I failed at regex :(
480+ def extract_complicated_function (self , line , b_function ):
481+ matches = []
482+ if b_function :
483+ function_split = line .split ('function' )
484+ else :
485+ function_split = line .split ('event' )
486+ if len (function_split ) > 1 :
487+ braces_split = function_split [1 ].split ('(' )
488+ else :
489+ return ["" , "" , "" , "" ]
434490
435- if "/**" in current_documentation :
436- if current_documentation != line :
437- current_documentation += line
491+ matches .append (function_split [0 ]) # function modifiers
492+ if len (braces_split [0 ].split ()) > 1 : # if name and return:
493+ matches .append (braces_split [0 ].split ()[0 ]) # return
494+ matches .append (braces_split [0 ].split ()[1 ]) # name
495+ else :
496+ matches .append ('' ) # no return
497+ matches .append (braces_split [0 ]) # name
498+ if len (braces_split ) > 1 :
499+ matches .append (braces_split [1 ].rstrip ('\n \r \t ;)' )) # parameters
500+ else :
501+ return ["" , "" , "" , "" ]
502+
503+ return matches
438504
439505 def stop (self ):
440506 if self .isAlive ():
0 commit comments