Skip to content
This repository was archived by the owner on May 25, 2019. It is now read-only.

Commit 2317315

Browse files
committed
Some refactoring, JS Completions Updates
- use 'verbose' prefix instead of suffix in JS Completions - begin pulling code out into modules
1 parent bf2042b commit 2317315

5 files changed

+159
-92
lines changed

‎AngularJS-js-completions.sublime-settings

+10-22
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
["$sceDelegate\tAngularJS", "\\$sceDelegate"],
3535
["$sceDelegateProvider\tAngularJS", "\\$sceDelegateProvider"],
3636
["$sceProvider\tAngularJS", "\\$sceProvider"],
37+
["$scope\tAngularJS", "\\$scope"],
3738
["$templateCache\tAngularJS", "\\$templateCache"],
3839
["$timeout\tAngularJS", "\\$timeout"],
3940
["$window\tAngularJS", "\\$window"],
@@ -51,27 +52,12 @@
5152

5253
["$swipe\tAngularJS", "\\$swipe"],
5354

54-
["$http_verbose\tAngularJS", "\\$http('${1:GET|POST|PUT|DELETE}', ${2:url}${3:, ${4:post}}, ${5:function(status, response){\n\t${6:// success}\n}}${7:, function(status, response){\n\t${8:// error}\n}});"],
55-
["$filter_verbose\tAngularJS", "\\$filter('${1:currency|date|filter|json|limitTo|linky|lowercase|number|orderBy|uppercase}')(${2:array}${3:, ${4:expression}});"],
56-
["$interval_verbose\tAngularJS", "\\$interval(${1:fn}${2:, ${3:delay}${4:, ${5:count}}${6:, ${7:invokeApply}}})"],
57-
["$timeout\tAngularJS", "\\$timeout(${1:function()\\{\n\t$2\n\\}}, ${3:delay});"],
58-
59-
// ["$apply\tAngularJS", "\\$apply($0);"],
60-
// ["$broadcast\tAngularJS", "\\$broadcast('${1:name}', ${2:arguments});"],
61-
// ["$destroy\tAngularJS", "\\$destroy();"],
62-
// ["$digest\tAngularJS", "\\$digest();"],
63-
// ["$emit\tAngularJS", "\\$emit('${1:name}', ${2:arguments});"],
64-
// ["$eval\tAngularJS", "\\$eval($0);"],
65-
// ["$evalAsync\tAngularJS", "\\$evalAsync($0);"],
66-
// ["$new\tAngularJS", "\\$new(${1:isolate});"],
67-
// ["$on\tAngularJS", "\\$on('${1:name}', ${2:function(){$3}});"],
68-
// ["$parent\tAngularJS", "\\$parent."],
69-
// ["$root\tAngularJS", "\\$root."],
70-
// ["$timeout\tAngularJS", "\\$timeout(${1:function()\\{\n\t$2\n\\}}, ${3:delay});"],
71-
// ["$watch\tAngularJS", "\\$watch('${1:name}', function(newValue, oldValue, scope) {\n\t$0\n});"],
72-
73-
["module\tAngularJS", "/**\n* $1 Module\n*\n* ${2:Description}\n*/\nangular.module('$1', [$3]).$0"],
74-
["directive\tAngularJS", "directive('$1', [${3:'$4', }function($4){\n\t${5:// Runs during compile}\n\treturn {\n\t\t// name: '',\n\t\t// priority: 1,\n\t\t// terminal: true,\n\t\t// scope: {}, // {} = isolate, true = child, false/undefined = no change\n\t\t// controller: function(\\$scope, \\$element, \\$attrs, \\$transclude) {},\n\t\t// require: 'ngModel', // Array = multiple requires, ? = optional, ^ = check parent elements\n\t\t// restrict: 'A', // E = Element, A = Attribute, C = Class, M = Comment\n\t\t// template: '',\n\t\t// templateUrl: '',\n\t\t// replace: true,\n\t\t// transclude: true,\n\t\t// compile: function(tElement, tAttrs, function transclude(function(scope, cloneLinkingFn){ return function linking(scope, elm, attrs){}})),\n\t\tlink: function(\\$scope, iElm, iAttrs, controller) {\n\t\t\t$0\n\t\t}\n\t};\n}]);"]
55+
["verbose_$http\tAngularJS", "\\$http('${1:GET|POST|PUT|DELETE}', ${2:url}${3:, ${4:post}}, ${5:function(status, response){\n\t${6:// success}\n}}${7:, function(status, response){\n\t${8:// error}\n}});"],
56+
["verbose_$filter\tAngularJS", "\\$filter('${1:currency|date|filter|json|limitTo|linky|lowercase|number|orderBy|uppercase}')(${2:array}${3:, ${4:expression}});"],
57+
["verbose_$interval\tAngularJS", "\\$interval(${1:fn}${2:, ${3:delay}${4:, ${5:count}}${6:, ${7:invokeApply}}})"],
58+
["verbose_$timeout\tAngularJS", "\\$timeout(${1:function()\\{\n\t$2\n\\}}, ${3:delay});"],
59+
["verbose_directive\tAngularJS", "directive('$1', [${3:'$4', }function($4){\n\t${5:// Runs during compile}\n\treturn {\n\t\t// name: '',\n\t\t// priority: 1,\n\t\t// terminal: true,\n\t\t// scope: {}, // {} = isolate, true = child, false/undefined = no change\n\t\t// controller: function(\\$scope, \\$element, \\$attrs, \\$transclude) {},\n\t\t// require: 'ngModel', // Array = multiple requires, ? = optional, ^ = check parent elements\n\t\t// restrict: 'A', // E = Element, A = Attribute, C = Class, M = Comment\n\t\t// template: '',\n\t\t// templateUrl: '',\n\t\t// replace: true,\n\t\t// transclude: true,\n\t\t// compile: function(tElement, tAttrs, function transclude(function(scope, cloneLinkingFn){ return function linking(scope, elm, attrs){}})),\n\t\tlink: function(\\$scope, iElm, iAttrs, controller) {\n\t\t\t$0\n\t\t}\n\t};\n}]);"],
60+
["verbose_module\tAngularJS", "/**\n* $1 Module\n*\n* ${2:Description}\n*/\nangular.module('$1', [$3]).$0"]
7561
],
7662
"angular": [
7763
["bind\tAngularJS", "bind(${1:self}, ${2:fn}, ${3:args})"],
@@ -220,7 +206,9 @@
220206
["reject\tAngularJS", "reject(${1:reason})"],
221207
["when\tAngularJS", "when(${1:value})"]
222208
],
223-
"$rootScope": [
209+
"$rootScope": "_scopes",
210+
"$scope": "_scopes",
211+
"_scopes": [
224212
["$apply\tAngularJS", "\\$apply(${1:exp})"],
225213
["$broadcast\tAngularJS", "\\$broadcast(${1:name}, ${2:args})"],
226214
["$destroy\tAngularJS", "\\$destroy()"],

‎AngularJS-sublime-package.py

+46-70
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
import sublime, sublime_plugin, os, re, codecs, threading, json, time, glob, itertools
22

3+
isST2 = int(sublime.version()) < 3000
4+
5+
if isST2:
6+
import jscompletions
7+
import viewlocation
8+
import message
9+
else:
10+
from . import jscompletions
11+
from . import viewlocation
12+
from . import message
13+
14+
315
class AngularJS():
416
def init(self, isST2):
517
self.isST2 = isST2
@@ -56,8 +68,8 @@ def get_current_project_indexes(self):
5668
return self.projects_index_cache[self.get_index_key()]
5769
else:
5870
return {'definitions':[], 'attributes': {}}
59-
def add_indexes_to_cache(self, indexes):
6071

72+
def add_indexes_to_cache(self, indexes):
6173
self.projects_index_cache[self.get_index_key()] = {
6274
'definitions': indexes[0],
6375
'attributes': indexes[1]
@@ -67,48 +79,12 @@ def add_indexes_to_cache(self, indexes):
6779
j_data.write(json.dumps(self.projects_index_cache))
6880
j_data.close()
6981

70-
def at_html_attribute(self, attribute, locations):
71-
view = self.active_view()
72-
selector = view.match_selector(locations[0], 'text.html string')
73-
if not selector: return False
74-
check_attribute = ''
75-
view_point = locations[0]
76-
char = ''
77-
while(char != ' ' and view_point > -1):
78-
char = view.substr(view_point)
79-
if(char != ' '): check_attribute += char
80-
view_point -= 1
81-
check_attribute = check_attribute[::-1]
82-
if check_attribute.startswith(attribute):
83-
return True
84-
return False
85-
86-
def find_word(self, region):
87-
non_char = re.compile(self.settings.get('non_word_chars'))
88-
look_up_found = ""
89-
start_point = region.end()
90-
begin_point = start_point-1
91-
end_point = start_point+1
92-
93-
while (not non_char.search(self.active_view().substr(sublime.Region(start_point, end_point)))
94-
and end_point):
95-
end_point += 1
96-
while (not non_char.search(self.active_view().substr(sublime.Region(begin_point, start_point)))):
97-
begin_point -= 1
98-
99-
look_up_found = self.active_view().substr(sublime.Region(begin_point+1, end_point-1))
100-
self.alert('Looking up: ' + look_up_found)
101-
return look_up_found
102-
10382
def handle_file_open_go_to(self, line):
10483
if not self.active_view().is_loading():
10584
self.active_view().run_command('goto_line', {'line': line} )
10685
else:
10786
sublime.set_timeout(lambda: self.handle_file_open_go_to(line), 100)
10887

109-
def alert(self, status_message):
110-
sublime.status_message('AngularJS: %s' % status_message)
111-
11288
#
11389
# completions definitions/logic
11490
#
@@ -188,6 +164,7 @@ def convertAttributesToSourceType(self, attrs):
188164
# pattern to find multiple attributes within the completion
189165
jadeAttrRegex = re.compile(r'([A-z-]+-\w+|\w+=)')
190166
hamlAttrRegex = re.compile(r'([A-z-]+-\w+.|\w+=)')
167+
191168
def convertToHamlCompletion(attr):
192169
attrList = hamlAttrRegex.findall(attr)
193170
if attrList:
@@ -216,7 +193,7 @@ def convertMultipleAttrExpantionToJade(attr):
216193
if self.isSource('source.jade'):
217194
return [(attr[0], convertMultipleAttrExpantionToJade(attr[1])) for attr in attrs]
218195
if self.isSource('text.haml'): return [(attr[0], convertToHamlCompletion(attr[1])) for attr in attrs]
219-
return attrs;
196+
return attrs
220197

221198
def convertIndexedDirectiveToTag(self, directive):
222199
'''
@@ -227,17 +204,22 @@ def convertIndexedDirectiveToTag(self, directive):
227204
return directive.replace('="$1"$0','')+'${1:($2)}$0'
228205
elif self.isSource('text.haml'):
229206
return '%' + directive.replace('="$1"$0','')+'${1:\\{$2\\}}$0'
230-
else: #assume HTML
207+
else:
208+
#assume HTML
231209
return directive.replace('="$1"$0','')+'$1>$0</'+directive.replace('="$1"$0','')+'>'
232210

233211
def completions(self, view, prefix, locations, is_inside_tag):
234212
if is_inside_tag:
235213
pt = locations[0] - len(prefix) - 1
236214
ch = view.substr(sublime.Region(pt, pt + 1))
237215

238-
if(ch != '<'
239-
and not self.settings.get('disable_default_directive_completions')): attrs = self.attributes[:]
240-
else: attrs = []
216+
if(
217+
ch != '<'
218+
and not self.settings.get('disable_default_directive_completions')
219+
):
220+
attrs = self.attributes[:]
221+
else:
222+
attrs = []
241223
attrs += self.get_isolate_completions(view, prefix, locations, pt)
242224
attrs += self.add_indexed_directives()
243225

@@ -271,7 +253,8 @@ def completions(self, view, prefix, locations, is_inside_tag):
271253
return []
272254

273255
def get_isolate_completions(self, view, prefix, locations, pt):
274-
if self.settings.get('disable_indexed_isolate_completions'): return []
256+
if self.settings.get('disable_indexed_isolate_completions'):
257+
return []
275258

276259
# pulled lots from html_completions.py
277260
SEARCH_LIMIT = 500
@@ -320,16 +303,10 @@ def filter_completions(self):
320303
return []
321304

322305
def js_completions(self, word=None):
323-
if self.settings.get('disable_default_js_completions'): return []
324-
if word:
325-
return [tuple(completion) for completion in list(self.settings_js_completions.get(word, []))]
326-
else:
327-
return [tuple(completion) for completion in list(self.settings_js_completions.get('js_completions', []))]
306+
return jscompletions.global_completions(word)
328307

329-
def js_event_completions(self, prefix):
330-
if self.settings.get('disable_default_js_completions'): return []
331-
if prefix == '$':
332-
return [tuple(completion) for completion in list(self.settings_js_completions.get('events', []))]
308+
def js_in_string_completions(self, prefix):
309+
return jscompletions.in_string_completions(prefix)
333310

334311
def add_indexed_directives(self):
335312
if self.settings.get('disable_indexed_directive_completions'): return []
@@ -379,10 +356,12 @@ def process_attributes(self):
379356
if int(sublime.version()) < 3000:
380357
ng.init(isST2=True)
381358

359+
382360
def plugin_loaded():
383361
global ng
384362
ng.init(isST2=False)
385363

364+
386365
class AngularJSEventListener(sublime_plugin.EventListener):
387366
global ng
388367

@@ -411,12 +390,10 @@ def on_query_completions(self, view, prefix, locations):
411390
word = '$rootScope'
412391
return ng.js_completions(word)
413392
if(view.score_selector(_scope, 'source.js string.quoted')):
414-
return ng.js_event_completions(prefix)
393+
return ng.js_in_string_completions(prefix)
415394

416-
if(ng.at_html_attribute('ng-controller', locations)):
417-
all_defs = ng.get_current_project_indexes().get('definitions')
418-
controllers = [(completion[0].split(': ')[1] + '\tAngularJS', completion[0].split(': ')[1]) for completion in all_defs if completion[0].startswith('controller')]
419-
return list(set(controllers))
395+
if(viewlocation.at_html_attribute(view, 'ng-controller', locations)):
396+
return jscompletions.controllers(ng.get_current_project_indexes())
420397
if(view.score_selector(_scope, ng.settings.get('filter_scope'))):
421398
return ng.filter_completions()
422399
for selector in ng.settings.get('attribute_avoided_scopes'):
@@ -452,24 +429,26 @@ def on_post_save(self, view):
452429
)
453430
thread.start()
454431

432+
455433
class AngularjsDeleteCacheCommand(sublime_plugin.WindowCommand):
456434
global ng
457435

458436
def run(self):
459-
ng.alert('Deleting Cache')
437+
message.alert('Deleting Cache')
460438
try:
461439
os.remove(ng.index_cache_location)
462440
except:
463-
ng.alert('Deleting Cache: No cache file found.')
441+
message.alert('Deleting Cache: No cache file found.')
464442
ng.projects_index_cache = {}
465443

444+
466445
class AngularjsFileIndexCommand(sublime_plugin.WindowCommand):
467446

468447
global ng
469448

470449
def run(self):
471450
if not ng.active_view():
472-
ng.alert('There was no active view found to process this command')
451+
message.alert('There was no active view found to process this command')
473452
return
474453

475454
ng.is_indexing = True
@@ -487,13 +466,13 @@ def run(self):
487466
self.track_walk_thread(thread)
488467

489468
def track_walk_thread(self, thread):
490-
ng.alert('indexing definitions')
469+
message.alert('indexing definitions')
491470

492471
if thread.is_alive():
493472
sublime.set_timeout(lambda: self.track_walk_thread(thread), 1000)
494473
else:
495474
ng.add_indexes_to_cache(thread.result)
496-
ng.alert('indexing completed in ' + str(thread.time_taken))
475+
message.alert('indexing completed in ' + str(thread.time_taken))
497476
ng.is_indexing = False
498477

499478

@@ -553,14 +532,13 @@ def handle_file_open_go_to(self, line):
553532

554533

555534
class AngularjsGoToDefinitionCommand(sublime_plugin.WindowCommand):
556-
557535
global ng
558536

559537
def run(self):
560538
self.active_view = ng.active_view()
561539

562540
if not ng.get_current_project_indexes().get('definitions'):
563-
ng.alert('No indexing found for project')
541+
message.alert('No indexing found for project')
564542
return
565543

566544
# grab first region
@@ -569,7 +547,7 @@ def run(self):
569547
# no selection has been made
570548
# so begin expanding to find word
571549
if not region.size():
572-
definition = ng.find_word(region)
550+
definition = viewlocation.find_word(self.active_view, region)
573551
else:
574552
definition = self.active_view.substr(region)
575553

@@ -585,11 +563,10 @@ def run(self):
585563
self.active_view = ng.active_window().open_file(item[1])
586564
ng.handle_file_open_go_to(int(item[2]))
587565
return
588-
ng.alert('definition "%s" could not be found' % definition)
566+
message.alert('definition "%s" could not be found' % definition)
589567

590568

591569
class AngularjsGoToDocumentationCommand(sublime_plugin.WindowCommand):
592-
593570
global ng
594571

595572
def run(self):
@@ -603,7 +580,7 @@ def run(self):
603580
# no selection has been made
604581
# so begin expanding to find word
605582
if not region.size():
606-
definition = ng.find_word(region)
583+
definition = viewlocation.find_word(ng.active_view(), region)
607584
else:
608585
definition = self.active_view.substr(region)
609586

@@ -619,7 +596,6 @@ def run(self):
619596

620597

621598
class AngularJSThread(threading.Thread):
622-
623599
global ng
624600

625601
def __init__(self, **kwargs):
@@ -699,7 +675,7 @@ def reindex_file(self, index_key):
699675
if (not file_path.endswith(tuple(self.kwargs['exclude_file_suffixes']))
700676
and index_key in ng.projects_index_cache
701677
and not [skip for skip in self.kwargs['exclude_dirs'] if os.path.normpath(skip) in file_path]):
702-
ng.alert('Reindexing ' + self.kwargs['file_path'])
678+
message.alert('Reindexing ' + self.kwargs['file_path'])
703679
project_index = ng.get_project_indexes_at(index_key)
704680

705681
project_index[:] = [

‎jscompletions.py

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import sublime
2+
3+
4+
def js_disabled():
5+
package_settings = sublime.load_settings('AngularJS-sublime-package.sublime-settings')
6+
return package_settings.get('disable_default_js_completions', False)
7+
8+
9+
def global_completions(word=None):
10+
js_completions = sublime.load_settings('AngularJS-js-completions.sublime-settings')
11+
if js_disabled():
12+
return []
13+
if word:
14+
symbol = js_completions.get(word, [])
15+
# in the settings we have strings, instead of a list of completions
16+
# since multiple symbols can have the same set of completions
17+
# which we prefix with '_'
18+
if len(symbol) and symbol[0] == '_':
19+
symbol = js_completions.get(symbol, [])
20+
return [tuple(completion) for completion in list(symbol)]
21+
else:
22+
return [tuple(completion) for completion in list(js_completions.get('js_completions', []))]
23+
24+
25+
def in_string_completions(prefix):
26+
js_completions = sublime.load_settings('AngularJS-js-completions.sublime-settings')
27+
if js_disabled():
28+
return []
29+
events = []
30+
injectables = []
31+
if prefix == '$':
32+
events = list(js_completions.get('events', []))
33+
events = [tuple(event) for event in events]
34+
injectables = list(js_completions.get('js_completions', []))
35+
# filter out the js_completions list so that we only include
36+
# items prefixed with '$' and use their simple form for the completion
37+
# Also, suffix them with (DI) to signify that they're a Dependency Injection
38+
injectables = [(injectable[0] + '(DI)', '\\'+injectable[0].split('\t')[0]) for injectable in injectables if injectable[0][0] == '$']
39+
return events + injectables
40+
41+
42+
def controllers(project_index):
43+
all_defs = project_index.get('definitions')
44+
controllers = [(completion[0].split(': ')[1] + '\tAngularJS', completion[0].split(': ')[1]) for completion in all_defs if completion[0].startswith('controller')]
45+
return list(set(controllers))

‎message.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import sublime
2+
3+
4+
def alert(msg):
5+
sublime.status_message('AngularJS: %s' % msg)

0 commit comments

Comments
 (0)