Skip to content

Commit

Permalink
Provide completion after << to reference IDs of same document
Browse files Browse the repository at this point in the history
part of asciidoctor#648

Signed-off-by: Aurélien Pupier <apupier@redhat.com>
  • Loading branch information
apupier committed Dec 23, 2022
1 parent e81db59 commit 495b4fc
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 8 deletions.
46 changes: 38 additions & 8 deletions src/providers/xref.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,33 @@ export async function provideCompletionItems (
position: vscode.Position
): Promise<vscode.CompletionItem[]> {
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
)
return occurence === context.position.character - keyword.length
}

async function getLabels (): Promise<string[]> {
async function getLabelsFromAllWorkspaceFiles (): Promise<string[]> {
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)
Expand Down Expand Up @@ -71,7 +78,7 @@ async function getLabelsFromLegacyBlock (content: string): Promise<string[]> {
/**
* Provide Completion Items
*/
async function provide (context: Context): Promise<vscode.CompletionItem[]> {
async function provideCrossRef (context: Context): Promise<vscode.CompletionItem[]> {
const { textFullLine, position } = context
const indexOfNextWhiteSpace = textFullLine.includes(' ', position.character)
? textFullLine.indexOf(' ', position.character)
Expand All @@ -81,7 +88,7 @@ async function provide (context: Context): Promise<vscode.CompletionItem[]> {
textFullLine.lastIndexOf(':', position.character + 1) + 1,
indexOfNextWhiteSpace
)
const xrefLabels = await getLabels()
const xrefLabels = await getLabelsFromAllWorkspaceFiles()

return xrefLabels
.filter((label) => label.match(search))
Expand All @@ -90,3 +97,26 @@ async function provide (context: Context): Promise<vscode.CompletionItem[]> {
kind: vscode.CompletionItemKind.Reference,
}))
}

async function provideInternalRef (context: Context): Promise<vscode.CompletionItem[]> {
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}>>`,
}))
}
22 changes: 22 additions & 0 deletions src/test/xrefCompletionProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<<AutoComplete.adoc`)
await vscode.workspace.fs.writeFile(fileToAutoComplete, Buffer.from(`[#anIDFromSameFile]
<<`))
createdFiles.push(fileToAutoComplete)

const fileThatShouldntAppearInAutoComplete = vscode.Uri.file(`${root}/fileToNotAppearInAutoComplete.adoc`)
await vscode.workspace.fs.writeFile(fileThatShouldntAppearInAutoComplete, Buffer.from('[#shouldNotAppear]'))
createdFiles.push(fileThatShouldntAppearInAutoComplete)

const file = await vscode.workspace.openTextDocument(fileToAutoComplete)
const completionsItems = await xrefProvider.provideCompletionItems(file, new Position(2, 2))
const filteredCompletionItems = completionsItems.filter((completionItem) => 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)
})
})

0 comments on commit 495b4fc

Please sign in to comment.