Skip to content

Commit 68e4d50

Browse files
committed
refactor(scriptCompletion, scriptProperties): enhance completion logic by introducing break symbol handling and updating processText method signature, to be prepared to improve it
1 parent 1a2d412 commit 68e4d50

2 files changed

Lines changed: 38 additions & 23 deletions

File tree

extensions/scripts/src/scripts/scriptCompletion.ts

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export class ScriptCompletion implements vscode.CompletionItemProvider {
2222
['value', vscode.CompletionItemKind.Value],
2323
]);
2424

25+
private static readonly breakSymbols: string[] = [' ', '.', '[', ']', '{', '}', '(', ')', "'", '"', '=', ':', ';', ',', '&', '|', '/', '!', '*', '+', '-', '?', '%', '^', '~', '`'];
26+
2527
private xsdReference: XsdReference;
2628
private xmlTracker: XmlStructureTracker;
2729
private scriptProperties: ScriptProperties;
@@ -166,6 +168,16 @@ export class ScriptCompletion implements vscode.CompletionItemProvider {
166168
return this.emptyCompletion;
167169
}
168170

171+
private static getNearestBreakSymbolIndex(text: string, before: boolean, exceptDot: boolean = false): number {
172+
const searchRange = before ? text.length - 1 : 0;
173+
for (let i = searchRange; i >= 0 && i < text.length; i += before ? -1 : 1) {
174+
if (this.breakSymbols.includes(text[i]) && (!exceptDot || text[i] !== '.')) {
175+
return i;
176+
}
177+
}
178+
return -1;
179+
}
180+
169181
public prepareCompletion(document: vscode.TextDocument, position: vscode.Position, checkOnly: boolean, token?: vscode.CancellationToken, context?: vscode.CompletionContext): vscode.CompletionItem[] | vscode.CompletionList | undefined {
170182
const schema = getDocumentScriptType(document);
171183
if (schema == '') {
@@ -233,6 +245,8 @@ export class ScriptCompletion implements vscode.CompletionItemProvider {
233245
return []; // Return empty list if only checking
234246
}
235247

248+
const attributeInfo = elementAttributes.find(attr => attr.name === attribute.name);
249+
236250
const attributeValue = document.getText(attribute.valueRange);
237251

238252
// If we're in an attribute value, we need to check for possible values
@@ -307,30 +321,31 @@ export class ScriptCompletion implements vscode.CompletionItemProvider {
307321
}
308322
textToProcessBefore = textToProcessBefore.substring(0, position.character);
309323
}
324+
325+
let lastBreakIndex = ScriptCompletion.getNearestBreakSymbolIndex(textToProcessBefore, true);
326+
let firstBreakIndex = ScriptCompletion.getNearestBreakSymbolIndex(textToProcessAfter, false);
327+
310328
const lastDollarIndex = textToProcessBefore.lastIndexOf('$');
311-
if (lastDollarIndex >= 0) {
312-
const prefix = lastDollarIndex < textToProcessBefore.length ? textToProcessBefore.substring(lastDollarIndex + 1) : '';
313-
if (prefix === '' || /^[a-zA-Z0-9_]*$/.test(prefix)) {
314-
let suffixLength = textToProcessAfter.length;
315-
for (const breakSymbol of [' ', '.', '[', ']', '{', '}', '(', ')']) {
316-
const breakIndex = textToProcessAfter.indexOf(breakSymbol);
317-
if (breakIndex >= 0 && breakIndex < suffixLength) {
318-
suffixLength = breakIndex;
319-
break;
320-
}
321-
}
322-
const variableRange = new vscode.Range(
323-
position.translate(0, -textToProcessBefore.length + lastDollarIndex + 1),
324-
position.translate(0, suffixLength)
325-
);
326-
const variableCompletion = this.variablesTracker.getAllVariablesForDocumentMap(document, position, prefix);
327-
for (const [variableName, info] of variableCompletion.entries()) {
328-
ScriptCompletion.addItem(items, 'variable', variableName, info, variableRange);
329-
}
330-
return ScriptCompletion.makeCompletionList(items, prefix);
329+
const prefix = lastDollarIndex < textToProcessBefore.length ? textToProcessBefore.substring(lastDollarIndex + 1) : '';
330+
if (lastDollarIndex >= 0 && lastDollarIndex > lastBreakIndex && (prefix === '' || /^[a-zA-Z0-9_]*$/.test(prefix))) {
331+
if (firstBreakIndex >= 0) {
332+
textToProcessAfter = textToProcessAfter.substring(0, firstBreakIndex);
331333
}
334+
const variableRange = new vscode.Range(
335+
position.translate(0, -textToProcessBefore.length + lastDollarIndex + 1),
336+
position.translate(0, textToProcessAfter.length)
337+
);
338+
const variableCompletion = this.variablesTracker.getAllVariablesForDocumentMap(document, position, prefix);
339+
for (const [variableName, info] of variableCompletion.entries()) {
340+
ScriptCompletion.addItem(items, 'variable', variableName, info, variableRange);
341+
}
342+
return ScriptCompletion.makeCompletionList(items, prefix);
343+
} else {
344+
lastBreakIndex = ScriptCompletion.getNearestBreakSymbolIndex(textToProcessBefore, true, true);
345+
firstBreakIndex = ScriptCompletion.getNearestBreakSymbolIndex(textToProcessAfter, false, true);
346+
return this.scriptProperties.processText(textToProcessBefore, textToProcessAfter, attributeInfo?.type || 'undefined') || ScriptCompletion.emptyCompletion;
332347
}
333-
return this.scriptProperties.processText(textToProcessBefore);
348+
return ScriptCompletion.emptyCompletion; // Skip if no valid prefix found
334349
} else {
335350
if (checkOnly) {
336351
return undefined; // Return empty list if only checking

extensions/scripts/src/scripts/scriptProperties.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -526,9 +526,9 @@ export class ScriptProperties {
526526
return updated ? hoverText : '';
527527
}
528528

529-
public processText(textToProcess: string): vscode.CompletionItem[] | vscode.CompletionList | undefined {
529+
public processText(textToProcessBefore: string, textToProcessAfter: string, type: string): vscode.CompletionItem[] | vscode.CompletionList | undefined {
530530
const items = new Map<string, vscode.CompletionItem>();
531-
const interesting = ScriptProperties.findRelevantPortion(textToProcess);
531+
const interesting = ScriptProperties.findRelevantPortion(textToProcessBefore);
532532
if (interesting === null) {
533533
logger.debug('no relevant portion detected');
534534
return this.keywordItems;

0 commit comments

Comments
 (0)