6
6
# Uses context sensitive completions.
7
7
#
8
8
# 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
19
10
# -load auto complete suggestions from current object before a '.'
20
11
# -same for goto definition
21
12
#
@@ -68,17 +59,11 @@ def run(self, edit):
68
59
window = sublime .active_window ()
69
60
70
61
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
78
62
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 )
82
67
83
68
function = self .get_function (word )
84
69
if function != None :
@@ -107,7 +92,18 @@ def run(self, edit):
107
92
else :
108
93
print _class [1 ] + 'does not exist'
109
94
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
+
111
107
sublime .set_timeout (lambda : self .hide_panel (self .view ), OPEN_TIME * 1000 )
112
108
113
109
def get_function (self , name ):
@@ -151,7 +147,8 @@ def clear(self):
151
147
152
148
def add_func (self , function_modifiers , return_type , function_name , arguments , line_number , file_name , description = "" , is_funct = 1 ):
153
149
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 ))
155
152
156
153
def add_var (self , var_modifiers , var_name , comment , line_number , file_name , description = "" ):
157
154
if self .get_variable (var_name ) == None :
@@ -178,11 +175,11 @@ def save_functions_to_list(self, filename):
178
175
def get_autocomplete_list (self , word , b_only_var = False ):
179
176
autocomplete_list = []
180
177
for variable in self ._variables :
181
- if word in variable .name ():
178
+ if word . lower () in variable .name (). lower ():
182
179
autocomplete_list .append ((variable .name (), variable .name ()))
183
180
if not b_only_var :
184
181
for function in self ._functions :
185
- if word in function .function_name ():
182
+ if word . lower () in function .function_name (). lower ():
186
183
function_str = function .function_name () + '\t (' + function .arguments () + ')' # add arguments
187
184
autocomplete_list .append ((function_str , function .function_name ()))
188
185
@@ -242,11 +239,12 @@ def on_query_completions(self, view, prefix, locations):
242
239
if current_file != None and is_unrealscript_file (current_file ):
243
240
# if is in defaultproperties, only get variables:
244
241
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
+
250
248
(row , col ) = view .rowcol (view .sel ()[0 ].begin ())
251
249
if row > line_number :
252
250
return self .get_autocomplete_list (prefix , True )
@@ -383,20 +381,76 @@ def search_file(self, path, file_name):
383
381
def save_functions (self , file_name ):
384
382
with open (file_name , 'rU' ) as file_lines :
385
383
current_documentation = ""
386
-
384
+ long_line = ""
385
+ b_function = True
386
+ bBracesNotOnSameLine = False
387
387
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 == "" :
389
393
current_documentation = line
390
394
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
397
426
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 )
399
428
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
400
454
401
455
elif "var" in line .lower (): # get possible lines containing variables
402
456
# 1: vartype, 2: name, 3: documentation
@@ -422,19 +476,31 @@ def save_functions(self, file_name):
422
476
self .collector .add_var (var_line , name , doc_line , i , file_name , current_documentation )
423
477
current_documentation = ""
424
478
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 ["" , "" , "" , "" ]
434
490
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
438
504
439
505
def stop (self ):
440
506
if self .isAlive ():
0 commit comments