@@ -3,8 +3,8 @@ import resources from '../../config/tips/tiat-resources.json';
3
3
import * as _ from "lodash" ;
4
4
import * as vscode from 'vscode' ;
5
5
6
- var topLevelTypes = [ "output" , "provider" , "resource" , "variable" , "data" ] ;
7
- var topLevelRegexes = topLevelTypes . map ( o => {
6
+ let topLevelTypes = [ "output" , "provider" , "resource" , "variable" , "data" ] ;
7
+ let topLevelRegexes = topLevelTypes . map ( o => {
8
8
return {
9
9
type : o ,
10
10
regex : new RegExp ( o + ' "[A-Za-z0-9\-_]+" "[A-Za-z0-9\-_]*" \{' )
@@ -19,17 +19,16 @@ export class TerraformTipsProvider implements CompletionItemProvider {
19
19
document : TextDocument ;
20
20
position : Position ;
21
21
token : CancellationToken ;
22
-
23
-
22
+ resourceType : string | null = null ;
24
23
25
24
public provideCompletionItems ( document : TextDocument , position : Position , token : CancellationToken , context : TerraformCompletionContext ) : CompletionItem [ ] {
26
25
this . document = document ;
27
26
this . position = position ;
28
27
this . token = token ;
29
28
30
29
// Check if we're on the top level
31
- let lineText = document . lineAt ( position . line ) . text ;
32
- let lineTillCurrentPosition = lineText . substr ( 0 , position . character ) ;
30
+ const lineText = document . lineAt ( position . line ) . text ;
31
+ const lineTillCurrentPosition = lineText . substring ( 0 , position . character ) ;
33
32
34
33
// Are we trying to type a resource type?
35
34
if ( this . isTopLevelType ( lineTillCurrentPosition ) ) {
@@ -39,16 +38,16 @@ export class TerraformTipsProvider implements CompletionItemProvider {
39
38
// Are we trying to type a variable?
40
39
if ( this . isTypingTfCode ( lineTillCurrentPosition ) ) {
41
40
// These variables should always just have 3 parts, resource type, resource name, exported field
42
- var varString = this . getVariableString ( lineTillCurrentPosition ) ;
43
- var parts = varString . split ( "." ) ;
41
+ let varString = this . getVariableString ( lineTillCurrentPosition ) ;
42
+ let parts = varString . split ( "." ) ;
44
43
45
44
if ( parts . length === 1 ) {
46
45
// We're trying to type the resource type
47
- var resourceTypePrefix = parts [ 1 ] ;
46
+ let resourceTypePrefix = parts [ 1 ] ;
48
47
49
48
// Get a list of all the resource types we've defined in this file
50
- var definedResourceTypes = this . getDefinedResourceTypes ( document ) ;
51
- var finalResourceTypes = _ . filter ( definedResourceTypes , o => ( o . indexOf ( resourceTypePrefix ) === 0 ) ) ;
49
+ let definedResourceTypes = this . getDefinedResourceTypes ( document ) ;
50
+ let finalResourceTypes = _ . filter ( definedResourceTypes , o => ( o . indexOf ( resourceTypePrefix ) === 0 ) ) ;
52
51
return _ . map ( finalResourceTypes , o => {
53
52
return new CompletionItem ( o , CompletionItemKind . Field ) ;
54
53
} ) ;
@@ -58,15 +57,15 @@ export class TerraformTipsProvider implements CompletionItemProvider {
58
57
const resourceType = parts [ 0 ] ;
59
58
60
59
// Get a list of all the names for this resource type
61
- var names = this . getNamesForResourceType ( document , resourceType ) ;
60
+ let names = this . getNamesForResourceType ( document , resourceType ) ;
62
61
return _ . map ( names , o => new CompletionItem ( o , CompletionItemKind . Field ) ) ;
63
62
}
64
63
else if ( parts . length === 3 ) {
65
- // We're trying to type the exported field for the var
64
+ // We're trying to type the exported field for the let
66
65
const resourceType = parts [ 0 ] ;
67
- var resourceName = parts [ 1 ] ;
68
- var attrs = resources [ resourceType ] . attrs ;
69
- var result = _ . map ( attrs , o => {
66
+ let resourceName = parts [ 1 ] ;
67
+ let attrs = resources [ resourceType ] . attrs ;
68
+ let result = _ . map ( attrs , o => {
70
69
let c = new CompletionItem ( `${ o . name } (${ resourceType } )` , CompletionItemKind . Property ) ;
71
70
c . detail = o . description ;
72
71
c . insertText = o . name ;
@@ -85,36 +84,39 @@ export class TerraformTipsProvider implements CompletionItemProvider {
85
84
return this . getHintsForStrings ( possibleResources ) ;
86
85
}
87
86
88
- // type '='
89
- if ( lineTillCurrentPosition . endsWith ( '=' ) && context . resourceType ) {
90
-
91
- // const completionItems: CompletionItem[] = [
92
- // new CompletionItem('Option1', CompletionItemKind.Value),
93
- // new CompletionItem('Option2', CompletionItemKind.Value)
94
- // ];
95
-
96
- const match = lineTillCurrentPosition . match ( / ( \w + ) \s * = / ) ;
97
- if ( match ) {
87
+ const endwithEqual = lineTillCurrentPosition . endsWith ( '=' ) ;
88
+ const includeEqual = lineTillCurrentPosition . indexOf ( '=' ) ;
89
+ // handle options
90
+ if ( this . resourceType ) {
91
+ // when we typing a '=' character
92
+ if ( endwithEqual ) {
93
+ const lineBeforeEqualSign = lineTillCurrentPosition . substring ( 0 , includeEqual ) . trim ( ) ;
98
94
// load options
99
- const name = match [ 1 ] ;
100
- const strs = this . findArgByName ( resources [ context . resourceType ] . args , name ) ;
101
- return this . packOptionsFormStrings ( strs ) ;
95
+ const name = lineBeforeEqualSign ;
96
+ const argStrs = this . findArgByName ( resources [ this . resourceType ] . args , name ) ;
97
+ const options = this . getOptionsFormArg ( argStrs ) ;
98
+ // clear resource type
99
+ this . resourceType = "" ;
100
+ return ( options ) . length ? options : [ ] ;
102
101
}
103
102
return [ ] ;
104
103
}
105
104
106
105
// Check if we're in a resource definition
107
- for ( var i = position . line - 1 ; i >= 0 ; i -- ) {
108
- let line = document . lineAt ( i ) . text ;
109
- let parentType = this . getParentType ( line ) ;
110
- if ( parentType && parentType . type === "resource" ) {
111
- const resourceType = this . getResourceTypeFromLine ( line ) ;
112
- let ret = this . getItemsForArgs ( resources [ resourceType ] . args , resourceType ) ;
113
- return ret ;
114
- }
115
- else if ( parentType && parentType . type !== "resource" ) {
116
- // We don't want to accidentally include some other containers stuff
117
- return [ ] ;
106
+ if ( includeEqual < 0 && ! endwithEqual ) {
107
+ // we're not in options case
108
+ for ( let i = position . line - 1 ; i >= 0 ; i -- ) {
109
+ let line = document . lineAt ( i ) . text ;
110
+ let parentType = this . getParentType ( line ) ;
111
+ if ( parentType && parentType . type === "resource" ) {
112
+ const resourceType = this . getResourceTypeFromLine ( line ) ;
113
+ const ret = this . getItemsForArgs ( resources [ resourceType ] . args , resourceType ) ;
114
+ return ret ;
115
+ }
116
+ else if ( parentType && parentType . type !== "resource" ) {
117
+ // We don't want to accidentally include some other containers stuff
118
+ return [ ] ;
119
+ }
118
120
}
119
121
}
120
122
@@ -126,7 +128,7 @@ export class TerraformTipsProvider implements CompletionItemProvider {
126
128
127
129
for ( let i = position . line - 1 ; i >= 0 ; i -- ) {
128
130
const line = document . lineAt ( i ) . text ;
129
- const match = line . match ( resourceRegex ) ;
131
+ const match = RegExp ( resourceRegex ) . exec ( line ) ;
130
132
131
133
if ( match ) {
132
134
return match [ 1 ] ;
@@ -136,22 +138,25 @@ export class TerraformTipsProvider implements CompletionItemProvider {
136
138
return undefined ;
137
139
}
138
140
139
- packOptionsFormStrings ( strings : string [ ] ) : CompletionItem [ ] {
140
- return _ . map ( strings , s => {
141
- return new CompletionItem ( s , CompletionItemKind . Enum ) ;
141
+ getOptionsFormArg ( opts : string [ ] ) : CompletionItem [ ] {
142
+ return _ . map ( opts , opt => {
143
+ let c = new CompletionItem ( opt , CompletionItemKind . Value ) ;
144
+ c . insertText = "\"" + opt + "\"" ;
145
+ return c ;
142
146
} ) ;
143
147
}
144
148
145
149
findArgByName ( args : any , name : string ) : any {
146
- return args . find ( ( arg ) => arg . name === name ) ;
150
+ const arg = args . find ( ( arg ) => arg . name === name ) ;
151
+ return arg . options ;
147
152
}
148
153
149
154
getNamesForResourceType ( document : TextDocument , resourceType : string ) : string [ ] {
150
- var r = new RegExp ( 'resource "' + resourceType + '" "([a-zA-Z0-9\-_]+)"' ) ;
151
- var found = [ ] ;
152
- for ( var i = 0 ; i < document . lineCount ; i ++ ) {
153
- var line = document . lineAt ( i ) . text ;
154
- var result = line . match ( r ) ;
155
+ let r = new RegExp ( 'resource "' + resourceType + '" "([a-zA-Z0-9\-_]+)"' ) ;
156
+ let found = [ ] ;
157
+ for ( let i = 0 ; i < document . lineCount ; i ++ ) {
158
+ let line = document . lineAt ( i ) . text ;
159
+ let result = RegExp ( r ) . exec ( line ) ;
155
160
if ( result && result . length > 1 ) {
156
161
found . push ( result [ 1 ] ) ;
157
162
}
@@ -163,11 +168,11 @@ export class TerraformTipsProvider implements CompletionItemProvider {
163
168
* Returns a list of resource type strings
164
169
*/
165
170
getDefinedResourceTypes ( document : TextDocument ) {
166
- var r = / r e s o u r c e " ( [ a - z A - Z 0 - 9 \- _ ] + ) " / ;
167
- var found = [ ] ;
168
- for ( var i = 0 ; i < document . lineCount ; i ++ ) {
169
- var line = document . lineAt ( i ) . text ;
170
- var result = line . match ( r ) ;
171
+ let r = / r e s o u r c e " ( [ a - z A - Z 0 - 9 \- _ ] + ) " / ;
172
+ let found = [ ] ;
173
+ for ( let i = 0 ; i < document . lineCount ; i ++ ) {
174
+ let line = document . lineAt ( i ) . text ;
175
+ let result = line . match ( r ) ;
171
176
if ( result && result . length > 1 ) {
172
177
found . push ( result [ 1 ] ) ;
173
178
}
@@ -176,33 +181,34 @@ export class TerraformTipsProvider implements CompletionItemProvider {
176
181
}
177
182
178
183
isTopLevelType ( line : string ) : boolean {
179
- for ( var i = 0 ; i < topLevelTypes . length ; i ++ ) {
180
- let resourceType = topLevelTypes [ i ] ;
181
- if ( resourceType . indexOf ( line ) === 0 ) {
184
+ for ( const element of topLevelTypes ) {
185
+ let resourceType = element ;
186
+ if ( resourceType . startsWith ( line ) ) {
182
187
return true ;
183
188
}
184
189
}
185
190
return false ;
186
191
}
187
192
188
193
getTopLevelType ( line : string ) : CompletionItem [ ] {
189
- for ( var i = 0 ; i < topLevelTypes . length ; i ++ ) {
190
- let resourceType = topLevelTypes [ i ] ;
191
- if ( resourceType . indexOf ( line ) === 0 ) {
194
+ for ( const element of topLevelTypes ) {
195
+ let resourceType = element ;
196
+ if ( resourceType . startsWith ( line ) ) {
192
197
return [ new CompletionItem ( resourceType , CompletionItemKind . Enum ) ] ;
193
198
}
194
199
}
195
200
return [ ] ;
196
201
}
197
202
198
203
isTypingTfCode ( line : string ) : boolean {
199
- var r = / \$ \{ [ 0 - 9 a - z A - Z _ \. \- ] * $ / ;
204
+ let r = / \$ \{ [ 0 - 9 a - z A - Z _ \. \- ] * $ / ;
200
205
return r . test ( line ) ;
201
206
}
202
207
203
208
getVariableString ( line : string ) : string {
204
- var r = / \$ \{ ( [ 0 - 9 a - z A - Z _ \. \- ] * ) $ / ;
205
- var result = line . match ( r ) ;
209
+ let r = / \$ \{ ( [ 0 - 9 a - z A - Z _ \. \- ] * ) $ / ;
210
+ let result = RegExp ( r ) . exec ( line ) ;
211
+ // let result = line.match(r);
206
212
if ( result . length > 1 ) {
207
213
return result [ 1 ] ;
208
214
}
@@ -214,7 +220,7 @@ export class TerraformTipsProvider implements CompletionItemProvider {
214
220
if ( parts . length === 2 && parts [ 0 ] === "resource" ) {
215
221
let r = parts [ 1 ] . replace ( / " / g, '' ) ;
216
222
let regex = new RegExp ( "^" + r ) ;
217
- var possibleResources = _ . filter ( _ . keys ( resources ) , k => {
223
+ let possibleResources = _ . filter ( _ . keys ( resources ) , k => {
218
224
if ( regex . test ( k ) ) {
219
225
return true ;
220
226
}
@@ -232,8 +238,8 @@ export class TerraformTipsProvider implements CompletionItemProvider {
232
238
}
233
239
234
240
getParentType ( line : string ) : boolean | any {
235
- for ( var i = 0 ; i < topLevelRegexes . length ; i ++ ) {
236
- let tl = topLevelRegexes [ i ] ;
241
+ for ( const element of topLevelRegexes ) {
242
+ let tl = element ;
237
243
if ( tl . regex . test ( line ) ) {
238
244
return tl ;
239
245
}
@@ -242,28 +248,16 @@ export class TerraformTipsProvider implements CompletionItemProvider {
242
248
}
243
249
244
250
getResourceTypeFromLine ( line : string ) : string {
245
- var lineParts = line . split ( " " ) ;
246
- var type = lineParts [ 1 ] ;
251
+ let lineParts = line . split ( " " ) ;
252
+ let type = lineParts [ 1 ] ;
247
253
return type . replace ( / " / g, '' ) ;
248
254
}
249
255
250
256
getItemsForArgs ( args , type ) {
251
257
return _ . map ( args , o => {
252
258
let c = new CompletionItem ( `${ o . name } (${ type } )` , CompletionItemKind . Property ) ;
253
- let text = o . name ;
254
- if ( o . default ) {
255
- text = text + ' = ' + o . default ;
256
- }
257
- let desc = o . description ;
258
- if ( o . options && o . options . length > 0 ) {
259
- let options = "" ;
260
- o . options . prototype . forEach ( oo => {
261
- options = options + oo + ',' ;
262
- } ) ;
263
- desc = 'Optional Values: ' + options ;
264
- }
265
- c . insertText = text ;
266
- c . detail = desc ;
259
+ c . detail = o . description ;
260
+ c . insertText = o . name ;
267
261
return c ;
268
262
} ) ;
269
263
}
@@ -281,19 +275,9 @@ export class TerraformTipsProvider implements CompletionItemProvider {
281
275
const resourceType = this . findResourceType ( event . document , position ) ;
282
276
283
277
if ( resourceType ) {
284
- setTimeout ( ( ) => {
285
- const cancellationTokenSource = new vscode . CancellationTokenSource ( ) ;
286
- const context : TerraformCompletionContext = {
287
- triggerKind : vscode . CompletionTriggerKind . Invoke ,
288
- triggerCharacter : undefined ,
289
- resourceType,
290
- } ;
291
- this . provideCompletionItems ( event . document , position , cancellationTokenSource . token , context ) ;
292
- vscode . commands . executeCommand ( 'editor.action.triggerSuggest' ) ;
293
- } , 10 ) ;
278
+ this . resourceType = resourceType ;
279
+ vscode . commands . executeCommand ( 'editor.action.triggerSuggest' ) ;
294
280
}
295
281
}
296
282
}
297
-
298
-
299
283
}
0 commit comments