From 59a2f630b0fe12418fb4d086139ed28b791faa4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Pupier?= Date: Fri, 25 Nov 2022 16:24:54 +0100 Subject: [PATCH] Provide completion after << to reference IDs of same document MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit part of #648 Signed-off-by: Aurélien Pupier --- src/providers/xref.provider.ts | 46 ++++++++++++++++++++----- src/test/xrefCompletionProvider.test.ts | 22 ++++++++++++ 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/src/providers/xref.provider.ts b/src/providers/xref.provider.ts index c4243568..5940ba42 100644 --- a/src/providers/xref.provider.ts +++ b/src/providers/xref.provider.ts @@ -10,17 +10,20 @@ export async function provideCompletionItems ( position: vscode.Position ): Promise { const context = createContext(document, position) - - return shouldProvide(context) ? provide(context) : Promise.resolve([]) + if (shouldProvide(context, 'xref:')) { + return provideCrossRef(context) + } else if (shouldProvide(context, '<<')) { + return provideInternalRef(context) + } else { + return Promise.resolve([]) + } } /** * Checks if we should provide any CompletionItems * @param context */ -function shouldProvide (context: Context): boolean { - const keyword = 'xref:' - // Check if cursor is after citenp: +function shouldProvide (context: Context, keyword :string): boolean { const occurence = context.textFullLine.indexOf( keyword, context.position.character - keyword.length @@ -28,8 +31,12 @@ function shouldProvide (context: Context): boolean { return occurence === context.position.character - keyword.length } -async function getLabels (): Promise { +async function getLabelsFromAllWorkspaceFiles (): Promise { const files = await vscode.workspace.findFiles('**/*.adoc') + return await getLabelsFromFiles(files) +} + +async function getLabelsFromFiles (files: vscode.Uri[]) { let contentOfFilesConcatenated = '' for (const uri of files) { const data = await vscode.workspace.fs.readFile(uri) @@ -71,7 +78,7 @@ async function getLabelsFromLegacyBlock (content: string): Promise { /** * Provide Completion Items */ -async function provide (context: Context): Promise { +async function provideCrossRef (context: Context): Promise { const { textFullLine, position } = context const indexOfNextWhiteSpace = textFullLine.includes(' ', position.character) ? textFullLine.indexOf(' ', position.character) @@ -81,7 +88,7 @@ async function provide (context: Context): Promise { textFullLine.lastIndexOf(':', position.character + 1) + 1, indexOfNextWhiteSpace ) - const xrefLabels = await getLabels() + const xrefLabels = await getLabelsFromAllWorkspaceFiles() return xrefLabels .filter((label) => label.match(search)) @@ -90,3 +97,26 @@ async function provide (context: Context): Promise { kind: vscode.CompletionItemKind.Reference, })) } + +async function provideInternalRef (context: Context): Promise { + const { textFullLine, position, document } = context + const indexOfNextWhiteSpace = textFullLine.includes(' ', position.character) + ? textFullLine.indexOf(' ', position.character) + : textFullLine.length + const search = textFullLine.substring( + textFullLine.lastIndexOf('<', position.character + 1) + 1, + indexOfNextWhiteSpace + ) + + const files :vscode.Uri[] = [] + files.push(document.uri) + const internalRefLabels = await getLabelsFromFiles(files) + + return internalRefLabels + .filter((label) => label.match(search)) + .map((label) => ({ + label: `${label}`, + kind: vscode.CompletionItemKind.Reference, + insertText: `${label}>>`, + })) +} diff --git a/src/test/xrefCompletionProvider.test.ts b/src/test/xrefCompletionProvider.test.ts index 5ea973b9..a4cc3137 100644 --- a/src/test/xrefCompletionProvider.test.ts +++ b/src/test/xrefCompletionProvider.test.ts @@ -83,4 +83,26 @@ xref:`)) label: 'anInlinedAnchor[]', }) }) + test('Should return id for element in same document after <<', async () => { + const fileToAutoComplete = vscode.Uri.file(`${root}/fileToTest< completionItem.label === 'anIDFromSameFile') + assert.deepStrictEqual(filteredCompletionItems[0], { + kind: vscode.CompletionItemKind.Reference, + label: 'anIDFromSameFile', + insertText: 'anIDFromSameFile>>', + }) + + assert.strictEqual(completionsItems.filter((completionItem) => completionItem.label === 'shouldNotAppear').length, 0) + }) })