This repository was archived by the owner on Sep 8, 2020. It is now read-only.
- Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathprovider.coffee
127 lines (100 loc) · 5.29 KB
/
provider.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# ref https://github.com/atom/autocomplete-html/blob/master/lib/provider.coffee
COMPLETIONS=require'../completions.json'
attributePattern=/\s+([a-zA-Z][-a-zA-Z]*)\s*=\s*$/
module.exports=
selector:'.source.js, .text.html'
disableForSelector:'.source.js .comment, .text.html .comment'
filterSuggestions:true
completions: COMPLETIONS
getSuggestions: (request) ->
if@isJavaScript(request) andnot@isIgnoreInJavaScript(request)
@getJavascriptCompletions(request)
elseif@isHtml(request)
if@isAttributeStart(request)
@getAttributeNameCompletions(request)
elseif@isTagStart(request)
@getTagNameCompletions(request)
else
[]
isJavaScript: ({ scopeDescriptor }) ->
for scope inscopeDescriptor.getScopesArray()
returntrueifscope.startsWith('source') andscope.endsWith('.js')
returnfalse
isIgnoreInJavaScript: ({ scopeDescriptor, prefix }) ->
scopes=scopeDescriptor.getScopesArray()
returntrueifscopes.indexOf('punctuation.terminator.statement.js') isnt-1or
scopes.indexOf('keyword.operator.assignment.js') isnt-1or
scopes.indexOf('meta.delimiter.object.comma.js') isnt-1or
scopes.indexOf('keyword.operator.comparison.js') isnt-1or
scopes.indexOf('keyword.operator.ternary.js') isnt-1or
scopes.indexOf('keyword.operator.js') isnt-1or
scopes.indexOf('string.quoted.template.js') isnt-1or
prefix.trim() is''
returnfalse
isHtml: ({ scopeDescriptor }) ->
for scope inscopeDescriptor.getScopesArray()
returntrueifscope.endsWith('.html')
returnfalse
isAttributeStart: ({prefix, scopeDescriptor, bufferPosition, editor}) ->
scopes=scopeDescriptor.getScopesArray()
return@hasTagScope(scopes) ifnot@getPreviousAttribute(editor, bufferPosition) and prefix andnotprefix.trim()
previousBufferPosition= [bufferPosition.row, Math.max(0, bufferPosition.column-1)]
previousScopes=editor.scopeDescriptorForBufferPosition(previousBufferPosition)
previousScopesArray=previousScopes.getScopesArray()
returntrueifpreviousScopesArray.indexOf('entity.other.attribute-name.html') isnt-1
returnfalseunless@hasTagScope(scopes)
# autocomplete here: <tag |>
# not here: <tag >|
scopes.indexOf('punctuation.definition.tag.end.html') isnt-1and
previousScopesArray.indexOf('punctuation.definition.tag.end.html') is-1
isTagStart: ({ prefix, scopeDescriptor, bufferPosition, editor }) ->
return@hasTagScope(scopeDescriptor.getScopesArray()) ifprefix.trim() andprefix.indexOf('<') is-1
# autocomplete-plus's default prefix setting does not capture <. Manually check for it.
prefix=editor.getTextInRange([[bufferPosition.row, bufferPosition.column-1], bufferPosition])
scopes=scopeDescriptor.getScopesArray()
# Don't autocomplete in embedded languages
prefix is'<'and scopes[0] is'text.html.basic'andscopes.lengthis1
hasTagScope: (scopes) ->
for scope in scopes
returntrueifscope.startsWith('meta.tag.') andscope.endsWith('.html')
returnfalse
hasStringScope: (scopes) ->
scopes.indexOf('string.quoted.double.html') isnt-1or
scopes.indexOf('string.quoted.single.html') isnt-1
getAttributeNameCompletions: ({prefix, editor, bufferPosition}) ->
completions= []
cantidates=@completions.directives.concat@completions.attributes
for idx, attribute of cantidates whennotprefix.trim() orfirstCharsEqual(attribute, prefix)
completions.push({ text: attribute, type:'attribute' })
completions
getTagNameCompletions: ({ prefix, editor, bufferPosition }) ->
# autocomplete-plus's default prefix setting does not capture <. Manually check for it.
ignorePrefix=editor.getTextInRange([[bufferPosition.row, bufferPosition.column-1], bufferPosition]) is'<'
completions= []
for idx, tag of@completions.directiveswhen ignorePrefix orfirstCharsEqual(tag, prefix)
completions.push({ text: tag, type:'tag' })
completions
getJavascriptCompletions: ({ prefix, editor, bufferPosition }) ->
completions= []
prefix=@getPrefix(editor, bufferPosition)
for idx, tag of@completions.javascript
completions.push({ text: tag, type:'angularjs', replacementPrefix: prefix })
completions
getPreviousAttribute: (editor, bufferPosition) ->
# Remove everything until the opening quote (if we're in a string)
quoteIndex=bufferPosition.column-1# Don't start at the end of the line
while quoteIndex
scopes=editor.scopeDescriptorForBufferPosition([bufferPosition.row, quoteIndex])
scopesArray=scopes.getScopesArray()
breakifnot@hasStringScope(scopesArray) orscopesArray.indexOf('punctuation.definition.string.begin.html') isnt-1
quoteIndex--
attributePattern.exec(editor.getTextInRange([[bufferPosition.row, 0], [bufferPosition.row, quoteIndex]]))?[1]
getPrefix: (editor, bufferPosition) ->
# Whatever your prefix regex might be
regex=/\$?[\w0-9_-]+$/
# Get the text for the line up to the triggered buffer position
line=editor.getTextInRange([[bufferPosition.row, 0], bufferPosition])
# Match the regex to the line, and return the match
line.match(regex)?[0] or''
firstCharsEqual= (str1, str2) ->
str1[0].toLowerCase() is str2[0].toLowerCase()