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

Commit fcc89db

Browse files
committed
More refactoring
- pulls logic that converts haml/jade completions out into its own module - adds simple test that can be ran against haml/jade completion conversions
1 parent c320de8 commit fcc89db

File tree

5 files changed

+175
-100
lines changed

5 files changed

+175
-100
lines changed

‎AngularJS-sublime-package.py

+4-100
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
import jscompletions
77
import viewlocation
88
import message
9+
import convert
910
else:
1011
from . import jscompletions
1112
from . import viewlocation
1213
from . import message
14+
from . import convert
1315

1416

1517
class AngularJS():
@@ -92,109 +94,11 @@ def isSource(self, sourceSelector):
9294
view = self.active_view()
9395
return view.score_selector(view.sel()[0].begin(), sourceSelector) > 0
9496

95-
# TODO: DRY this up where possible
9697
def convertElementToSourceType(self, elems):
97-
'''
98-
Adds support for markup outside of HTML
99-
Currently just Jade and HAML
100-
'''
101-
getAttrsRegex = re.compile(r'(([A-z-].-?\w+[ >])|(\w+=)|(>[\$0-9]+))')
102-
def convertToJadeElement(completion):
103-
#list of tag partials, tag start, attrs, tag end
104-
pieces = [item[0] for item in getAttrsRegex.findall(completion)]
105-
for tagStart in pieces[:1]:
106-
completion = completion.replace(tagStart, "%s(" % tagStart[:-1])
107-
has_tab_in_body = False
108-
for attr in pieces[2:-1]:
109-
# right now tab stops are picked up in the regex so check to
110-
# make sure it's not a tap stop that we're at
111-
if not '>$' in attr: completion = completion.replace(attr, ", " + attr)
112-
else:
113-
completion = completion.replace(attr, attr.replace('>',')'))
114-
has_tab_in_body = True
115-
for tagEnd in pieces[-1:]:
116-
# if the tag has no atts and no tab stops
117-
# it got mutated, so fix it here
118-
if len(pieces) == 2: completion = completion.replace('</'+tagEnd.replace('>','('), ')')
119-
# there was no tab stop in the body
120-
# so clean up the end angle from the start tag
121-
elif not has_tab_in_body: completion = completion.replace('></'+tagEnd, ')')
122-
# there was a tab stop in the body
123-
# so just clean out the end tag
124-
else: completion = completion.replace('</'+tagEnd, '')
125-
return completion
126-
127-
def convertToHamlElement(completion):
128-
#list of tag partials, tag start, attrs, tag end
129-
pieces = [item[0] for item in getAttrsRegex.findall(completion)]
130-
for tagStart in pieces[:1]:
131-
completion = '%' + completion.replace(tagStart, '%s{' % tagStart[:-1])
132-
has_tab_in_body = False
133-
for attr in pieces[2:-1]:
134-
# right now tab stops are picked up in the regex so check to
135-
# make sure it's not a tap stop that we're at
136-
if not '>$' in attr:
137-
completion = completion.replace(attr, ", " + attr)
138-
else:
139-
completion = completion.replace(attr, attr.replace('>','}'))
140-
has_tab_in_body = True
141-
for tagEnd in pieces[-1:]:
142-
# if the tag has no atts and no tab stops
143-
# it got mutated, so fix it here
144-
if len(pieces) == 2: completion = completion.replace('</'+tagEnd.replace('>','{'), '}')
145-
# there was no tab stop in the body
146-
# so clean up the end angle from the start tag
147-
elif not has_tab_in_body: completion = completion.replace('></'+tagEnd, '}')
148-
# there was a tab stop in the body
149-
# so just clean out the end tag
150-
else: completion = completion.replace('</'+tagEnd, '')
151-
return completion
152-
153-
if self.isSource('text.html'): return elems
154-
if self.isSource('source.jade'):
155-
return [(elem[0], convertToJadeElement(elem[1])) for elem in elems]
156-
if self.isSource('text.haml'):
157-
return [(elem[0], convertToHamlElement(elem[1])) for elem in elems]
98+
return convert.elements(elems)
15899

159-
# TODO: DRY this up where possible
160100
def convertAttributesToSourceType(self, attrs):
161-
'''
162-
Adds support for markup outside of HTML
163-
Currently just Jade and HAML
164-
'''
165-
# pattern to find multiple attributes within the completion
166-
jadeAttrRegex = re.compile(r'([A-z-]+-\w+|\w+=)')
167-
hamlAttrRegex = re.compile(r'([A-z-]+-\w+.|\w+=)')
168-
169-
def convertToHamlCompletion(attr):
170-
attrList = hamlAttrRegex.findall(attr)
171-
if attrList:
172-
for item in attrList[:1]:
173-
last_char = item[-1:]
174-
if last_char == ' ':
175-
attr = attr.replace(item, '"%s" ' % item.strip())
176-
elif last_char == '$':
177-
attr = attr.replace(item, '"%s"$' % item)
178-
elif last_char == '=':
179-
attr = attr.replace(item, '"%s" => ' % item.replace('=',''))
180-
for item in attrList[1:]:
181-
attr = attr.replace(item, ', "%s" => ' % item.replace('=',''))
182-
183-
return attr
184-
185-
def convertMultipleAttrExpantionToJade(attr):
186-
# remove the first attr from the list
187-
attrList = jadeAttrRegex.findall(attr)[1:]
188-
if attrList:
189-
for item in attrList:
190-
attr = attr.replace(item, ", " + item)
191-
return attr
192-
193-
if self.isSource('text.html'): return attrs
194-
if self.isSource('source.jade'):
195-
return [(attr[0], convertMultipleAttrExpantionToJade(attr[1])) for attr in attrs]
196-
if self.isSource('text.haml'): return [(attr[0], convertToHamlCompletion(attr[1])) for attr in attrs]
197-
return attrs
101+
return convert.attributes(attrs)
198102

199103
def convertIndexedDirectiveToTag(self, directive):
200104
'''

‎convert.py

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import re, sublime
2+
3+
isST2 = int(sublime.version()) < 3000
4+
5+
if isST2:
6+
import scope
7+
else:
8+
from . import scope
9+
10+
11+
def elemAttrsRegEx():
12+
return re.compile(r'(([A-z-].-?\w+[ >])|(\w+=)|(>[\$0-9]+))')
13+
14+
15+
def completionToJadeElement(completion):
16+
#list of tag partials, tag start, attrs, tag end
17+
pieces = [item[0] for item in elemAttrsRegEx().findall(completion)]
18+
for tagStart in pieces[:1]:
19+
completion = completion.replace(tagStart, "%s(" % tagStart[:-1])
20+
has_tab_in_body = False
21+
for attr in pieces[2:-1]:
22+
# right now tab stops are picked up in the regex so check to
23+
# make sure it's not a tap stop that we're at
24+
if not '>$' in attr:
25+
completion = completion.replace(attr, ", " + attr)
26+
else:
27+
completion = completion.replace(attr, attr.replace('>', ')'))
28+
has_tab_in_body = True
29+
for tagEnd in pieces[-1:]:
30+
# if the tag has no atts and no tab stops
31+
# it got mutated, so fix it here
32+
if len(pieces) == 2:
33+
completion = completion.replace('</'+tagEnd.replace('>', '('), ')')
34+
# there was no tab stop in the body
35+
# so clean up the end angle from the start tag
36+
elif not has_tab_in_body:
37+
completion = completion.replace('></'+tagEnd, ')')
38+
# there was a tab stop in the body
39+
# so just clean out the end tag
40+
else:
41+
completion = completion.replace('</'+tagEnd, '')
42+
return completion
43+
44+
45+
def completionToHamlElement(completion):
46+
#list of tag partials, tag start, attrs, tag end
47+
pieces = [item[0] for item in elemAttrsRegEx().findall(completion)]
48+
for tagStart in pieces[:1]:
49+
completion = '%' + completion.replace(tagStart, '%s{' % tagStart[:-1])
50+
has_tab_in_body = False
51+
for attr in pieces[2:-1]:
52+
# right now tab stops are picked up in the regex so check to
53+
# make sure it's not a tap stop that we're at
54+
if not '>$' in attr:
55+
completion = completion.replace(attr, ", " + attr)
56+
else:
57+
completion = completion.replace(attr, attr.replace('>', '}'))
58+
has_tab_in_body = True
59+
for tagEnd in pieces[-1:]:
60+
# if the tag has no atts and no tab stops
61+
# it got mutated, so fix it here
62+
if len(pieces) == 2:
63+
completion = completion.replace('</'+tagEnd.replace('>', '{'), '}')
64+
# there was no tab stop in the body
65+
# so clean up the end angle from the start tag
66+
elif not has_tab_in_body:
67+
completion = completion.replace('></'+tagEnd, '}')
68+
# there was a tab stop in the body
69+
# so just clean out the end tag
70+
else:
71+
completion = completion.replace('</'+tagEnd, '')
72+
return completion
73+
74+
75+
def elements(elems):
76+
'''
77+
Adds support for markup outside of HTML
78+
Currently just Jade and HAML
79+
'''
80+
print(elems)
81+
if scope.matches('text.html'):
82+
return elems
83+
if scope.matches('source.jade'):
84+
return [(elem[0], completionToJadeElement(elem[1])) for elem in elems]
85+
if scope.matches('text.haml'):
86+
return [(elem[0], completionToHamlElement(elem[1])) for elem in elems]
87+
88+
89+
def completionToHamlAttr(attr):
90+
hamlAttrRegex = re.compile(r'([A-z-]+-\w+.|\w+=)')
91+
attrList = hamlAttrRegex.findall(attr)
92+
if attrList:
93+
for item in attrList[:1]:
94+
last_char = item[-1:]
95+
if last_char == ' ':
96+
attr = attr.replace(item, '"%s" ' % item.strip())
97+
elif last_char == '$':
98+
attr = attr.replace(item, '"%s"$' % item)
99+
elif last_char == '=':
100+
attr = attr.replace(item, '"%s" => ' % item.replace('=', ''))
101+
for item in attrList[1:]:
102+
attr = attr.replace(item, ', "%s" => ' % item.replace('=', ''))
103+
104+
return attr
105+
106+
107+
def completionToJadeAttr(attr):
108+
jadeAttrRegex = re.compile(r'([A-z-]+-\w+|\w+=)')
109+
# remove the first attr from the list
110+
attrList = jadeAttrRegex.findall(attr)[1:]
111+
if attrList:
112+
for item in attrList:
113+
attr = attr.replace(item, ", " + item)
114+
return attr
115+
116+
117+
def attributes(attrs):
118+
'''
119+
Adds support for markup outside of HTML
120+
Currently just Jade and HAML
121+
'''
122+
123+
if scope.matches('text.html'):
124+
return attrs
125+
if scope.matches('source.jade'):
126+
return [(attr[0], completionToJadeAttr(attr[1])) for attr in attrs]
127+
if scope.matches('text.haml'):
128+
return [(attr[0], completionToHamlAttr(attr[1])) for attr in attrs]
129+
return attrs

‎scope.py

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import sublime
2+
3+
4+
def matches(selector):
5+
view = sublime.active_window().active_view()
6+
region = view.sel()[0].begin()
7+
return view.score_selector(region, selector) > 0

‎test.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import sublime, sublime_plugin
2+
3+
isST2 = int(sublime.version()) < 3000
4+
5+
if isST2:
6+
import convert
7+
else:
8+
from . import convert
9+
10+
11+
class AngularjsTestPlugin(sublime_plugin.WindowCommand):
12+
13+
def run(self):
14+
print('\nAngularJS Plug-in Test Runner Results:\n')
15+
self.test_element_completions()
16+
17+
def test_element_completions(self):
18+
html_elems = [('ng-include\tAngularJS', 'ng-include src="$1"${2: scope="$3"}${4: onload="$5"}></ng-include>'), ('ng-pluralize\tAngularJS', 'ng-pluralize count="${1:string}" when="$2" offset="$4"></ng-pluralize>'), ('ng-select\tAngularJS', 'select ngModel="${1:string}"${2:${3: name="${4:string}"}${5: required}${6: ngRequired="${7:string}"}${8: ngOptions="${9:comprehension_expression}"}}>$10</select>$0'), ('ng-template\tAngularJS', 'script type="text/ng-template"${1: id="$2"}>$0</script>'), ('ng-textarea\tAngularJS', 'textarea ngModel="${1:string}"${2:${3: name="${4:string}"}${5: required}${6: ngRequired="${7:string}"}${8: ngMinlength="${9:number}"}${10: ngMaxlength="${11:number}"}${12: ngPattern="${13:string}"}${14: ngChange="${15:string}"}}>$16</textarea>$0'), ('ng-view\tAngularJS', 'ng-view></ng-view>')]
19+
expect_jade_elems = [('ng-include\tAngularJS', 'ng-include(src="$1"${2: , scope="$3"}${4: , onload="$5"})'), ('ng-pluralize\tAngularJS', 'ng-pluralize(count="${1:string}" , when="$2" , offset="$4")'), ('ng-select\tAngularJS', 'select(ngModel="${1:string}"${2:${3: , name="${4:string}"}${5: required}${6: , ngRequired="${7:string}"}${8: , ngOptions="${9:comprehension_expression}"}})$10$0'), ('ng-template\tAngularJS', 'script(type="text/ng-template"${1: , id="$2"})$0'), ('ng-textarea\tAngularJS', 'textarea(ngModel="${1:string}"${2:${3: , name="${4:string}"}${5: required}${6: , ngRequired="${7:string}"}${8: , ngMinlength="${9:number}"}${10: , ngMaxlength="${11:number}"}${12: , ngPattern="${13:string}"}${14: , ngChange="${15:string}"}})$16$0'), ('ng-view\tAngularJS', 'ng-view()')]
20+
expect_haml_elems = [('ng-include\tAngularJS', '%ng-include{src="$1"${2: , scope="$3"}${4: , onload="$5"}}'), ('ng-pluralize\tAngularJS', '%ng-pluralize{count="${1:string}" , when="$2" , offset="$4"}'), ('ng-select\tAngularJS', '%select{ngModel="${1:string}"${2:${3: , name="${4:string}"}${5: required}${6: , ngRequired="${7:string}"}${8: , ngOptions="${9:comprehension_expression}"}}}$10$0'), ('ng-template\tAngularJS', '%script{type="text/ng-template"${1: , id="$2"}}$0'), ('ng-textarea\tAngularJS', '%textarea{ngModel="${1:string}"${2:${3: , name="${4:string}"}${5: required}${6: , ngRequired="${7:string}"}${8: , ngMinlength="${9:number}"}${10: , ngMaxlength="${11:number}"}${12: , ngPattern="${13:string}"}${14: , ngChange="${15:string}"}}}$16$0'), ('ng-view\tAngularJS', '%ng-view{}')]
21+
22+
jade = [(elem[0], convert.completionToJadeElement(elem[1])) for elem in html_elems]
23+
haml = [(elem[0], convert.completionToHamlElement(elem[1])) for elem in html_elems]
24+
25+
print('[Element Completions - Jade]\tpassed: %s' % (jade == expect_jade_elems))
26+
print('[Element Completions - haml]\tpassed: %s' % (haml == expect_haml_elems))
27+
28+
def test_attribute_completions(self):
29+
html_attrs = [('ng-app\tAngularJS', 'ng-app="${1:string}"$0'), ('ng-bind\tAngularJS', 'ng-bind="${1:expression}"$0'), ('ng-bind-html\tAngularJS', 'ng-bind-html="${1:expression}"$0'), ('ng-bind-html-unsafe\tAngularJS', 'ng-bind-html-unsafe="${1:expression}"$0'), ('ng-bind-template\tAngularJS', 'ng-bind-template="${1:string}"$0'), ('ng-blur\tAngularJS', 'ng-blur="${1:expression}"$0'), ('ng-change\tAngularJS', 'ng-change="${1:function()}"$0'), ('ng-checked\tAngularJS', 'ng-checked="${1:expression}"$0'), ('ng-class\tAngularJS', 'ng-class="${1:expression}"$0'), ('ng-class-even\tAngularJS', 'ng-class-even="${1:expression}"$0'), ('ng-class-odd\tAngularJS', 'ng-class-odd="${1:expression}"$0'), ('ng-click\tAngularJS', 'ng-click="${1:expression}"$0'), ('ng-cloak\tAngularJS', 'ng-cloak$0'), ('ng-controller\tAngularJS', 'ng-controller="$1"$2'), ('ng-copy\tAngularJS', 'ng-copy="${1:expression}"$0'), ('ng-csp\tAngularJS', 'ng-csp$0'), ('ng-cut\tAngularJS', 'ng-cut="${1:expression}"$0'), ('ng-dblclick\tAngularJS', 'ng-dblclick="${1:expression}"$0'), ('ng-disabled\tAngularJS', 'ng-disabled="${1:expression}"$0'), ('ng-focus\tAngularJS', 'ng-focus="${1:expression}"$0'), ('ng-form\tAngularJS', 'ng-form name="${1:string}"$0'), ('ng-hide\tAngularJS', 'ng-hide="${1:expression}"$0'), ('ng-href\tAngularJS', 'ng-href="${1:template}"$0'), ('ng-if\tAngularJS', 'ng-if="${1:expression}"$0'), ('ng-include\tAngularJS', 'ng-include="${1:string}" ${2:scope="$3"} ${4:onload="$5"}'), ('ng-init\tAngularJS', 'ng-init="${1:expression}"$0'), ('ng-keydown\tAngularJS', 'ng-keydown="${1:expression}"$0'), ('ng-keypress\tAngularJS', 'ng-keypress="${1:expression}"$0'), ('ng-keyup\tAngularJS', 'ng-keyup="${1:expression}"$0'), ('ng-list\tAngularJS', 'ng-list="${1:string}"$0'), ('ng-model\tAngularJS', 'ng-model$0'), ('ng-mousedown\tAngularJS', 'ng-mousedown="${1:expression}"$0'), ('ng-mouseenter\tAngularJS', 'ng-mouseenter="${1:expression}"$0'), ('ng-mouseleave\tAngularJS', 'ng-mouseleave="${1:expression}"$0'), ('ng-mousemove\tAngularJS', 'ng-mousemove="${1:expression}"$0'), ('ng-mouseover\tAngularJS', 'ng-mouseover="${1:expression}"$0'), ('ng-mouseup\tAngularJS', 'ng-mouseup="${1:expression}"$0'), ('ng-multiple\tAngularJS', 'ng-multiple="${1:expression}"$0'), ('ng-non-bindable\tAngularJS', 'ng-non-bindable$0'), ('ng-open\tAngularJS', 'ng-open="${1:expression}"$0'), ('ng-paste\tAngularJS', 'ng-paste="${1:expression}"$0'), ('ng-options\tAngularJS', 'ng-options="${1:select} as ${2:label} for ${3:value} in ${4:array}"'), ('ng-pluralize\tAngularJS', 'ng-pluralize count="${1:string}" when="$2" offset="$4"$0'), ('ng-readonly\tAngularJS', 'ng-readonly="${1:expression}"$0'), ('ng-repeat\tAngularJS', 'ng-repeat="${1:(${2:key}, ${3:value})} in ${4:dataset}"$0'), ('ng-repeat-end\tAngularJS', 'ng-repeat-end$0'), ('ng-repeat-start\tAngularJS', 'ng-repeat-start="${1:(${2:key}, ${3:value})} in ${4:dataset}"$0'), ('ng-selected\tAngularJS', 'ng-selected="${1:string}"$0'), ('ng-show\tAngularJS', 'ng-show="${1:expression}"$0'), ('ng-src\tAngularJS', 'ng-src="${1:template}"$0'), ('ng-srcset\tAngularJS', 'ng-srcset="${1:template}"$0'), ('ng-style\tAngularJS', 'ng-style="${1:expression}"$0'), ('ng-submit\tAngularJS', 'ng-submit="${1:expression}"$0'), ('ng-swipe-left\tAngularJS', 'ng-swipe-left="${1:expression}"$0'), ('ng-swipe-right\tAngularJS', 'ng-swipe-right="${1:expression}"$0'), ('ng-switch\tAngularJS', 'ng-switch on="${1:expression}"$0'), ('ng-switch-when\tAngularJS', 'ng-switch-when="${1:string}"$0'), ('ng-switch-default\tAngularJS', 'ng-switch-default$0'), ('ng-transclude\tAngularJS', 'ng-transclude$0'), ('ng-trim\tAngularJS', 'ng-trim$0'), ('ng-value\tAngularJS', 'ng-value="${1:string}"$0'), ('ng-view\tAngularJS', 'ng-view$0')]

‎test.sublime-commands

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"caption": "AngularJS: Test Plug-in",
4+
"command": "angularjs_test_plugin"
5+
}
6+
]

0 commit comments

Comments
 (0)