export function provideCompletionItems()

in experimental/adaptive-tool/server/lg/src/providers/completion.ts [19:131]


export function provideCompletionItems(_textDocumentPosition: TextDocumentPositionParams, documents: TextDocuments<TextDocument>): CompletionItem[] {
	const document = documents.get(_textDocumentPosition.textDocument.uri)!;
	const fspath = URI.parse(document.uri).fsPath;
	const position = _textDocumentPosition.position;
	const lineTextBefore = document?.getText({
		start: {
			line: position.line,
			character: 0
		},
		end: position
	}).toString();

	if (!util.isLgFile(path.basename(document.uri))) {
		return [];
	}

	if (/\[[^\]]*\]\([^)]*$/.test(lineTextBefore!) && !util.isInFencedCodeBlock(document!, position) && isExpression(lineTextBefore!)) {
		// []() import suggestion
		const paths = Array.from(new Set(TemplatesStatus.lgFilesOfWorkspace));

		return paths.filter(u => fspath !== u).reduce((prev : CompletionItem[], curr: string) => {
			const relativePath = path.relative(path.dirname(fspath!), curr);
			const item = {
				label: relativePath, 
				kind: CompletionItemKind.Reference,
				detail: curr
			};
			prev.push(item);
			return prev;
		}, []);
	} else if (/\$\{[^}]*$/.test(lineTextBefore!) && isExpression(lineTextBefore!)) {
		// buildin function prompt in expression
		const items: CompletionItem[] = [];
		const functions = util.getAllFunctions(document!.uri);
		functions.forEach((value, key) => {
			const completionItem = CompletionItem.create(key);
			const returnType = util.getreturnTypeStrFromReturnType(value.returntype);
			completionItem.detail = `${key}(${value.params.join(", ")}): ${returnType}`;
			completionItem.documentation = value.introduction;
			completionItem.insertText = `${key}(${value.params.map(u => u.split(':')[0].trim()).join(", ")})`;
			items.push(completionItem);
		});

		return items;
	} else if (isStartStructure(document!, position)) {
		// structure name and key suggestion
		const items: CompletionItem[] = [];
		util.cardTypes.forEach(value => {
			const completionItem = CompletionItem.create(value);
			completionItem.detail = `create ${value} structure`;
			let insertTextArray = util.cardPropDict.Others;
			// if (value === 'CardAction' || value === 'Suggestions' || value === 'Attachment' || value === 'Activity') {
			if (value === 'CardAction' || value === 'Attachment' || value === 'Activity') {
				insertTextArray = util.cardPropDict[value];
			} else if (value.endsWith('Card')){
				insertTextArray = util.cardPropDict.Cards;
			}
			completionItem.insertText = value + '\r\n' + insertTextArray.map(u => `\t${u.name} = ${u.placeHolder}`).join('\r\n') + '\r\n';
			items.push(completionItem);
		});

		return items;
	} else if (isInStructure(document!, position).isInStruct && /^\s*$/.test(lineTextBefore!)) {
		const structureName = isInStructure(document!, position).struType;
		const items: CompletionItem[] = []; 

		const nameToPropertiesMapping = Object.entries(util.cardPropDictFull);
		const propertiesMapping = nameToPropertiesMapping.find(u => u[0].toLowerCase() === structureName!.toLowerCase());
		if (propertiesMapping !== undefined) {
			const properties = propertiesMapping[1];
			properties.forEach(propertyItem => {
				const completionItem = CompletionItem.create(propertyItem.name);
				completionItem.detail = `create property ${propertyItem.name}`;
				const placeHolder = 'placeHolder' in propertyItem ? propertyItem['placeHolder'] : `${propertyItem.name}`;
				completionItem.insertText = propertyItem.name + ' = ' + placeHolder;
				items.push(completionItem);
			});
			return items;
		}
	}  else if (/^>\s!#/.test(lineTextBefore!)) {
		// options suggestion following "> !#"
		const items: CompletionItem[] = [];
		const optionDefinitionRegex = />\s!#\s*$/;
		if (optionDefinitionRegex.test(lineTextBefore!)) {
			AddToCompletion(util.optionsMap.options, items);
		} else {
			const strictRegex = />\s!#\s*@strict\s*=$/;
			const replaceNullRegex = />\s!#\s*@replaceNull\s*=$/;
			const lineBreakStyleRegex = />\s!#\s*@lineBreakStyle\s*=$/;
			const exportsFirstRegex = />\s!#\s*@Exports\s*=$/;
			const exportsMidRegex = />\s!#\s*@Exports\s*=/;
			if (strictRegex.test(lineTextBefore!)) {
				AddToCompletion(util.optionsMap.strictOptions, items);
			} else if (replaceNullRegex.test(lineTextBefore!)) {
				AddToCompletion(util.optionsMap.replaceNullOptions, items);
			} else if (lineBreakStyleRegex.test(lineTextBefore!)) {
				AddToCompletion(util.optionsMap.lineBreakStyleOptions, items);
			} else if (exportsFirstRegex.test(lineTextBefore!) || (exportsMidRegex.test(lineTextBefore!) && /,\s*$/.test(lineTextBefore!))) {
				const templatesOptions = TemplatesStatus.templatesMap.get(fspath!)!.templates.toArray();
				// const templatesOptions = Templates.parseFile(fspath!).toArray();
				for (let i=0;i<templatesOptions!.length;++i) {
					const templateName = templatesOptions![i].name;
					const completionItem = CompletionItem.create(" " + templateName);
					completionItem.detail = " " + templateName;
					completionItem.insertText = " " + templateName;
					items.push(completionItem);
				}
			}
		}
		return items;
	}
	return [];
}