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()];
}