@@ -3,8 +3,8 @@ import resources from '../../config/tips/tiat-resources.json';
33import * as _ from "lodash" ;
44import * as vscode from 'vscode' ;
55
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 => {
88 return {
99 type : o ,
1010 regex : new RegExp ( o + ' "[A-Za-z0-9\-_]+" "[A-Za-z0-9\-_]*" \{' )
@@ -19,17 +19,16 @@ export class TerraformTipsProvider implements CompletionItemProvider {
1919 document : TextDocument ;
2020 position : Position ;
2121 token : CancellationToken ;
22-
23-
22+ resourceType : string | null = null ;
2423
2524 public provideCompletionItems ( document : TextDocument , position : Position , token : CancellationToken , context : TerraformCompletionContext ) : CompletionItem [ ] {
2625 this . document = document ;
2726 this . position = position ;
2827 this . token = token ;
2928
3029 // 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 ) ;
3332
3433 // Are we trying to type a resource type?
3534 if ( this . isTopLevelType ( lineTillCurrentPosition ) ) {
@@ -39,16 +38,16 @@ export class TerraformTipsProvider implements CompletionItemProvider {
3938 // Are we trying to type a variable?
4039 if ( this . isTypingTfCode ( lineTillCurrentPosition ) ) {
4140 // 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 ( "." ) ;
4443
4544 if ( parts . length === 1 ) {
4645 // We're trying to type the resource type
47- var resourceTypePrefix = parts [ 1 ] ;
46+ let resourceTypePrefix = parts [ 1 ] ;
4847
4948 // 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 ) ) ;
5251 return _ . map ( finalResourceTypes , o => {
5352 return new CompletionItem ( o , CompletionItemKind . Field ) ;
5453 } ) ;
@@ -58,15 +57,15 @@ export class TerraformTipsProvider implements CompletionItemProvider {
5857 const resourceType = parts [ 0 ] ;
5958
6059 // 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 ) ;
6261 return _ . map ( names , o => new CompletionItem ( o , CompletionItemKind . Field ) ) ;
6362 }
6463 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
6665 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 => {
7069 let c = new CompletionItem ( `${ o . name } (${ resourceType } )` , CompletionItemKind . Property ) ;
7170 c . detail = o . description ;
7271 c . insertText = o . name ;
@@ -85,36 +84,39 @@ export class TerraformTipsProvider implements CompletionItemProvider {
8584 return this . getHintsForStrings ( possibleResources ) ;
8685 }
8786
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 ( ) ;
9894 // 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 : [ ] ;
102101 }
103102 return [ ] ;
104103 }
105104
106105 // 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+ }
118120 }
119121 }
120122
@@ -126,7 +128,7 @@ export class TerraformTipsProvider implements CompletionItemProvider {
126128
127129 for ( let i = position . line - 1 ; i >= 0 ; i -- ) {
128130 const line = document . lineAt ( i ) . text ;
129- const match = line . match ( resourceRegex ) ;
131+ const match = RegExp ( resourceRegex ) . exec ( line ) ;
130132
131133 if ( match ) {
132134 return match [ 1 ] ;
@@ -136,22 +138,25 @@ export class TerraformTipsProvider implements CompletionItemProvider {
136138 return undefined ;
137139 }
138140
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 ;
142146 } ) ;
143147 }
144148
145149 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 ;
147152 }
148153
149154 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 ) ;
155160 if ( result && result . length > 1 ) {
156161 found . push ( result [ 1 ] ) ;
157162 }
@@ -163,11 +168,11 @@ export class TerraformTipsProvider implements CompletionItemProvider {
163168 * Returns a list of resource type strings
164169 */
165170 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 ) ;
171176 if ( result && result . length > 1 ) {
172177 found . push ( result [ 1 ] ) ;
173178 }
@@ -176,33 +181,34 @@ export class TerraformTipsProvider implements CompletionItemProvider {
176181 }
177182
178183 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 ) ) {
182187 return true ;
183188 }
184189 }
185190 return false ;
186191 }
187192
188193 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 ) ) {
192197 return [ new CompletionItem ( resourceType , CompletionItemKind . Enum ) ] ;
193198 }
194199 }
195200 return [ ] ;
196201 }
197202
198203 isTypingTfCode ( line : string ) : boolean {
199- var r = / \$ \{ [ 0 - 9 a - z A - Z _ \. \- ] * $ / ;
204+ let r = / \$ \{ [ 0 - 9 a - z A - Z _ \. \- ] * $ / ;
200205 return r . test ( line ) ;
201206 }
202207
203208 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);
206212 if ( result . length > 1 ) {
207213 return result [ 1 ] ;
208214 }
@@ -214,7 +220,7 @@ export class TerraformTipsProvider implements CompletionItemProvider {
214220 if ( parts . length === 2 && parts [ 0 ] === "resource" ) {
215221 let r = parts [ 1 ] . replace ( / " / g, '' ) ;
216222 let regex = new RegExp ( "^" + r ) ;
217- var possibleResources = _ . filter ( _ . keys ( resources ) , k => {
223+ let possibleResources = _ . filter ( _ . keys ( resources ) , k => {
218224 if ( regex . test ( k ) ) {
219225 return true ;
220226 }
@@ -232,8 +238,8 @@ export class TerraformTipsProvider implements CompletionItemProvider {
232238 }
233239
234240 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 ;
237243 if ( tl . regex . test ( line ) ) {
238244 return tl ;
239245 }
@@ -242,28 +248,16 @@ export class TerraformTipsProvider implements CompletionItemProvider {
242248 }
243249
244250 getResourceTypeFromLine ( line : string ) : string {
245- var lineParts = line . split ( " " ) ;
246- var type = lineParts [ 1 ] ;
251+ let lineParts = line . split ( " " ) ;
252+ let type = lineParts [ 1 ] ;
247253 return type . replace ( / " / g, '' ) ;
248254 }
249255
250256 getItemsForArgs ( args , type ) {
251257 return _ . map ( args , o => {
252258 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 ;
267261 return c ;
268262 } ) ;
269263 }
@@ -281,19 +275,9 @@ export class TerraformTipsProvider implements CompletionItemProvider {
281275 const resourceType = this . findResourceType ( event . document , position ) ;
282276
283277 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' ) ;
294280 }
295281 }
296282 }
297-
298-
299283}
0 commit comments