@@ -82,21 +82,14 @@ export class OutputPortEditUIMouseListener extends MouseListener {
8282}
8383
8484// More information and playground website for testing: https://microsoft.github.io/monaco-editor/monarch.html
85- const statementKeywords = [ "Forwarding({})" , "Assignment({})" ] ;
85+ const startOfLineKeywords = [ "forward" , "assign" , "set" , "unset" ] ;
86+ const statementKeywords = [ "forward" , "assign" , "set" , "unset" , "if" , "from" ] ;
8687const constantsKeywords = [ "TRUE" , "FALSE" ] ;
8788const dfdBehaviorLanguageMonarchDefinition : monaco . languages . IMonarchLanguage = {
8889 keywords : [ ...statementKeywords , ...constantsKeywords ] ,
8990
9091 operators : [ "=" , "||" , "&&" , "!" ] ,
9192
92- brackets : [
93- {
94- open : "(" ,
95- close : ")" ,
96- token : "delimiter.parenthesis" ,
97- } ,
98- ] ,
99-
10093 symbols : / [ = > < ! ~ ? : & | + \- * \/ \^ % ] + / ,
10194
10295 tokenizer : {
@@ -117,8 +110,6 @@ const dfdBehaviorLanguageMonarchDefinition: monaco.languages.IMonarchLanguage =
117110 [ / \/ \/ .* $ / , "comment" ] ,
118111 [ / # .* $ / , "comment" ] ,
119112
120- // delimiters and operators
121- [ / [ ( ) ] / , "@brackets" ] ,
122113 [
123114 / @ s y m b o l s / ,
124115 {
@@ -140,7 +131,7 @@ class MonacoEditorDfdBehaviorCompletionProvider implements monaco.languages.Comp
140131
141132 // Auto open completions after typing a dot. Useful for the set statement where
142133 // components are delimited by dots.
143- triggerCharacters = [ "." , ";" , "{ " ] ;
134+ triggerCharacters = [ "." , ";" , " " , ", "] ;
144135
145136 provideCompletionItems (
146137 model : monaco . editor . ITextModel ,
@@ -156,19 +147,7 @@ class MonacoEditorDfdBehaviorCompletionProvider implements monaco.languages.Comp
156147 if ( isAtFirstWord ) {
157148 // Start of line: suggest statement start keywords
158149 return {
159- suggestions : statementKeywords . map ( ( keyword ) => ( {
160- label : keyword ,
161- kind : monaco . languages . CompletionItemKind . Keyword ,
162- insertText : keyword . slice ( 0 , - 2 ) + "$0" + keyword . slice ( - 2 ) ,
163- insertTextRules : monaco . languages . CompletionItemInsertTextRule . InsertAsSnippet , // Treat insertText as a snippet
164- // Replace full line with new statement start keyword
165- range : new monaco . Range (
166- position . lineNumber ,
167- 1 ,
168- position . lineNumber ,
169- model . getLineMaxColumn ( position . lineNumber ) ,
170- ) ,
171- } ) ) ,
150+ suggestions : this . getKeywordCompletions ( model , position , startOfLineKeywords , true ) ,
172151 } ;
173152 }
174153
@@ -179,40 +158,46 @@ class MonacoEditorDfdBehaviorCompletionProvider implements monaco.languages.Comp
179158 } ;
180159 }
181160
161+ const lastWord = model . getLineContent ( position . lineNumber ) . trimEnd ( ) . split ( " " ) . pop ( ) || "" ;
182162 const availableInputs = parent . getAvailableInputs ( ) . filter ( ( input ) => input !== undefined ) as string [ ] ;
183-
184- const curlyBracketCompletion = {
185- label : "{" ,
186- kind : monaco . languages . CompletionItemKind . Snippet ,
187- insertText : "$0}" , // Automatically add closing curly bracket and position cursor inside
188- insertTextRules : monaco . languages . CompletionItemInsertTextRule . InsertAsSnippet ,
189- range : new monaco . Range ( position . lineNumber , position . column , position . lineNumber , position . column ) ,
190- } ;
191-
192- // Add the curly bracket completion when the user types a curly bracket
193- if (
194- model . getValueInRange (
195- new monaco . Range ( position . lineNumber , position . column - 1 , position . lineNumber , position . column ) ,
196- ) === "{" &&
197- model . getValueInRange (
198- new monaco . Range ( position . lineNumber , position . column , position . lineNumber , position . column + 1 ) ,
199- ) !== "}"
200- ) {
201- return {
202- suggestions : [ curlyBracketCompletion ] ,
203- } ;
204- }
205-
206- // Suggestions per statement type
207- switch ( statementType ?. word ) {
208- case "Assignment" :
163+ console . log ( "lastWord" , lastWord ) ;
164+ if ( lastWord . endsWith ( "," ) || lastWord . endsWith ( "." ) || lastWord == statementType ?. word ) {
165+ // Suggestions per statement type
166+ switch ( statementType ?. word ) {
167+ case "assign" :
168+ return {
169+ suggestions : this . getAssignmentCompletions ( model , position , availableInputs ) ,
170+ } ;
171+ case "forward" :
172+ return {
173+ suggestions : this . getInputCompletions ( model , position , availableInputs ) ,
174+ } ;
175+ case "set" :
176+ return {
177+ suggestions : this . getOutLabelCompletions ( model , position ) ,
178+ } ;
179+ case "unset" :
180+ return {
181+ suggestions : this . getOutLabelCompletions ( model , position ) ,
182+ } ;
183+ }
184+ } else if ( statementType ?. word === "assign" ) {
185+ if ( lastWord == "from" ) {
186+ console . log ( 1 ) ;
209187 return {
210- suggestions : this . getAssignmentCompletions ( model , position , availableInputs ) ,
188+ suggestions : this . getInputCompletions ( model , position , availableInputs ) ,
211189 } ;
212- case "Forwarding" :
190+ } else if ( lastWord == "if" ) {
191+ console . log ( 2 ) ;
213192 return {
214- suggestions : this . getForwardingCompletions ( model , position , availableInputs ) ,
193+ suggestions : this . getConstantsCompletions ( model , position ) ,
215194 } ;
195+ } else {
196+ console . log ( 3 ) ;
197+ return {
198+ suggestions : this . getKeywordCompletions ( model , position , [ "from" , "if" ] ) ,
199+ } ;
200+ }
216201 }
217202
218203 // Unknown statement type, cannot suggest anything
@@ -221,6 +206,24 @@ class MonacoEditorDfdBehaviorCompletionProvider implements monaco.languages.Comp
221206 } ;
222207 }
223208
209+ private getKeywordCompletions (
210+ model : monaco . editor . ITextModel ,
211+ position : monaco . Position ,
212+ keywords : string [ ] ,
213+ replaceLine : boolean = false ,
214+ ) : monaco . languages . CompletionItem [ ] {
215+ const range = replaceLine
216+ ? new monaco . Range ( position . lineNumber , 1 , position . lineNumber , model . getLineMaxColumn ( position . lineNumber ) )
217+ : new monaco . Range ( position . lineNumber , position . column , position . lineNumber , position . column ) ;
218+ return keywords . map ( ( keyword ) => ( {
219+ label : keyword ,
220+ kind : monaco . languages . CompletionItemKind . Keyword ,
221+ insertText : keyword ,
222+ insertTextRules : monaco . languages . CompletionItemInsertTextRule . InsertAsSnippet , // Treat insertText as a snippet
223+ range : range ,
224+ } ) ) ;
225+ }
226+
224227 private getAssignmentCompletions (
225228 model : monaco . editor . ITextModel ,
226229 position : monaco . Position ,
@@ -279,26 +282,6 @@ class MonacoEditorDfdBehaviorCompletionProvider implements monaco.languages.Comp
279282 return [ ...constantsCompletions , ...outLabelCompletions ] ;
280283 }
281284
282- private getForwardingCompletions (
283- model : monaco . editor . ITextModel ,
284- position : monaco . Position ,
285- availableInputs : string [ ] ,
286- ) : monaco . languages . CompletionItem [ ] {
287- const line = model . getLineContent ( position . lineNumber ) ;
288- const column = position . column ;
289-
290- // Check if we're inside the input list (i.e., inside first curly braces `{}`)
291- const openBraceIndex = line . indexOf ( "{" ) ;
292-
293- // If the first semicolon hasn't been typed yet, assume we're inside the input list
294- if ( openBraceIndex !== - 1 && column > openBraceIndex ) {
295- // Inside `{List of available inputs}` section
296- return this . getInputCompletions ( model , position , availableInputs ) ;
297- } else {
298- return [ ] ;
299- }
300- }
301-
302285 private getOutLabelCompletions (
303286 model : monaco . editor . ITextModel ,
304287 position : monaco . Position ,
0 commit comments