async provideCompletionItems()

in src/issues/issueCompletionProvider.ts [36:156]


	async provideCompletionItems(
		document: vscode.TextDocument,
		position: vscode.Position,
		token: vscode.CancellationToken,
		context: vscode.CompletionContext,
	): Promise<vscode.CompletionItem[]> {
		// If the suggest was not triggered by the trigger character, require that the previous character be the trigger character
		if (
			document.languageId !== 'scminput' &&
			document.uri.scheme !== 'comment' &&
			position.character > 0 &&
			context.triggerKind === vscode.CompletionTriggerKind.Invoke &&
			!document.getText(document.getWordRangeAtPosition(position)).match(/#[0-9]*$/)
		) {
			return [];
		}
		// It's common in markdown to start a line with #s and not want an completion
		if (
			position.character <= 6 &&
			document.languageId === 'markdown' &&
			(document.getText(new vscode.Range(position.with(undefined, 0), position)) ===
				new Array(position.character + 1).join('#')) &&
			document.uri.scheme !== 'comment' &&
			context.triggerKind === vscode.CompletionTriggerKind.TriggerCharacter
		) {
			return [];
		}

		if (
			context.triggerKind === vscode.CompletionTriggerKind.TriggerCharacter &&
			vscode.workspace
				.getConfiguration(ISSUES_CONFIGURATION)
				.get<string[]>('ignoreCompletionTrigger', [])
				.find(value => value === document.languageId)
		) {
			return [];
		}

		if (document.languageId !== 'scminput' && !(await isComment(document, position))) {
			return [];
		}

		let range: vscode.Range = new vscode.Range(position, position);
		if (position.character - 1 >= 0) {
			const wordAtPos = document.getText(new vscode.Range(position.translate(0, -1), position));
			if (wordAtPos === '#') {
				range = new vscode.Range(position.translate(0, -1), position);
			}
		}

		await this.stateManager.tryInitializeAndWait();

		const completionItems: Map<string, vscode.CompletionItem> = new Map();
		const now = new Date();
		let repo: PullRequestDefaults | undefined;
		let uri: vscode.Uri | undefined;
		if (document.languageId === 'scminput') {
			uri = getRootUriFromScmInputUri(document.uri);
		} else if ((document.uri.scheme === 'comment') && vscode.workspace.workspaceFolders?.length) {
			for (const visibleEditor of vscode.window.visibleTextEditors) {
				const testFolderUri = vscode.workspace.workspaceFolders[0].uri.with({ path: visibleEditor.document.uri.path });
				const workspace = vscode.workspace.getWorkspaceFolder(testFolderUri);
				if (workspace) {
					uri = workspace.uri;
					break;
				}
			}
		} else {
			uri = document.uri.scheme === NEW_ISSUE_SCHEME
				? extractIssueOriginFromQuery(document.uri) ?? document.uri
				: document.languageId === 'scminput'
					? getRootUriFromScmInputUri(document.uri)
					: document.uri;
		}
		if (!uri) {
			return [];
		}

		let folderManager: FolderRepositoryManager | undefined;
		try {
			folderManager = this.repositoriesManager.getManagerForFile(uri);
			repo = await folderManager?.getPullRequestDefaults();
		} catch (e) {
			// leave repo undefined
		}
		const issueData = this.stateManager.getIssueCollection(folderManager?.repository.rootUri ?? uri);
		for (const issueQuery of issueData) {
			const issuesOrMilestones: IssueModel[] | MilestoneModel[] = (await issueQuery[1]) ?? [];
			if (issuesOrMilestones.length === 0) {
				continue;
			}
			if (issuesOrMilestones[0] instanceof IssueModel) {
				let index = 0;
				for (const issue of issuesOrMilestones) {
					completionItems.set(
						getIssueNumberLabel(issue as IssueModel),
						await this.completionItemFromIssue(repo, issue as IssueModel, now, range, document, index++),
					);
				}
			} else {
				for (let index = 0; index < issuesOrMilestones.length; index++) {
					const value: MilestoneModel = issuesOrMilestones[index] as MilestoneModel;
					for (const issue of value.issues) {
						completionItems.set(
							getIssueNumberLabel(issue),
							await this.completionItemFromIssue(
								repo,
								issue,
								now,
								range,
								document,
								index,
								value.milestone,
							),
						);
					}
				}
			}
		}
		return [...completionItems.values()];
	}