Skip to content

Commit

Permalink
Feat: Add completion for Yocto tasks in embedded languages
Browse files Browse the repository at this point in the history
  • Loading branch information
idillon-sfl committed Feb 6, 2024
1 parent 5fa36d2 commit ac882ac
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 18 deletions.
21 changes: 12 additions & 9 deletions client/src/language/middlewareCompletion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,20 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

import { type CompletionList, commands, Range, workspace } from 'vscode'
import { CompletionList, commands, Range, workspace } from 'vscode'
import { type CompletionMiddleware } from 'vscode-languageclient/node'

import { requestsManager } from './RequestManager'
import { getEmbeddedLanguageDocPosition, getOriginalDocRange } from './utils'
import { embeddedLanguageDocsManager } from './EmbeddedLanguageDocsManager'
import { mergeArraysDistinctly } from '../lib/src/utils/arrays'

export const middlewareProvideCompletion: CompletionMiddleware['provideCompletionItem'] = async (document, position, context, token, next) => {
const nextResult = await next(document, position, context, token)
if (Array.isArray(nextResult) && nextResult.length > 0) {
return nextResult
}
const nextResult = await next(document, position, context, token) ?? []

const embeddedLanguageType = await requestsManager.getEmbeddedLanguageTypeOnPosition(document.uri.toString(), position)
if (embeddedLanguageType === undefined || embeddedLanguageType === null) {
return await next(document, position, context, token)
return nextResult
}
const embeddedLanguageDocInfos = embeddedLanguageDocsManager.getEmbeddedLanguageDocInfos(document.uri.toString(), embeddedLanguageType)
if (embeddedLanguageDocInfos === undefined || embeddedLanguageDocInfos === null) {
Expand All @@ -31,13 +30,13 @@ export const middlewareProvideCompletion: CompletionMiddleware['provideCompletio
position
)
const vdocUri = embeddedLanguageTextDocument.uri
const result = await commands.executeCommand<CompletionList>(
const pulledCompletionList = await commands.executeCommand<CompletionList>(
'vscode.executeCompletionItemProvider',
vdocUri,
adjustedPosition,
context.triggerCharacter
)
result.items.forEach((item) => {
pulledCompletionList.items.forEach((item) => {
if (item.range === undefined) {
// pass
} else if (item.range instanceof Range) {
Expand All @@ -51,5 +50,9 @@ export const middlewareProvideCompletion: CompletionMiddleware['provideCompletio
item.range = { inserting, replacing }
}
})
return result
return mergeArraysDistinctly(
pulledCompletionList.items,
nextResult instanceof CompletionList ? nextResult.items : nextResult,
(completionItem) => completionItem.label
)
}
26 changes: 26 additions & 0 deletions client/src/lib/src/utils/arrays.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) 2023 Savoir-faire Linux. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

export const mergeArraysDistinctly = <ElementType, KeyType>(
array1: ElementType[],
array2: ElementType[],
getKey: (a: ElementType) => KeyType // A key on which two elements are equal
): ElementType[] => {
const mergedArray: ElementType[] = []
const seenKeys = new Set<KeyType>()

array1.forEach((item) => {
mergedArray.push(item)
seenKeys.add(getKey(item))
})

array2.forEach((item) => {
if (!seenKeys.has(getKey(item))) {
mergedArray.push(item)
}
})

return mergedArray
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
python do_foo(){
pri
p
}

do_bar(){
ech
e
}

DESCRIP
22 changes: 17 additions & 5 deletions integration-tests/src/tests/completion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,33 @@ suite('Bitbake Completion Test Suite', () => {
})
}

test('Completion appears properly on bitbake variable', async () => {
test('Completion item for Yocto variable shows up in BitBake region', async () => {
const position = new vscode.Position(8, 7)
const expected = 'DESCRIPTION'
await testCompletion(position, expected)
}).timeout(BITBAKE_TIMEOUT)

test('Completion appears properly on embedded python', async () => {
const position = new vscode.Position(1, 7)
test('Completion item for Python built in function shows up Python region', async () => {
const position = new vscode.Position(1, 6)
const expected = 'print'
await testCompletion(position, expected)
}).timeout(BITBAKE_TIMEOUT)

test('Completion appears properly on embedded bash', async () => {
const position = new vscode.Position(5, 7)
test('Completion item for Yocto task shows up in Python region', async () => {
const position = new vscode.Position(1, 6)
const expected = 'do_package'
await testCompletion(position, expected)
}).timeout(BITBAKE_TIMEOUT)

test('Completion item for built in Bash function show up in Bash region', async () => {
const position = new vscode.Position(5, 6)
const expected = 'echo'
await testCompletion(position, expected)
}).timeout(BITBAKE_TIMEOUT)

test('Completion item for Yocto task show up in Bash region', async () => {
const position = new vscode.Position(5, 6)
const expected = 'do_populate_sdk_ext'
await testCompletion(position, expected)
}).timeout(BITBAKE_TIMEOUT)
})
7 changes: 5 additions & 2 deletions server/src/connectionHandlers/onCompletion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ function getBitBakeCompletionItems (textDocumentPositionParams: TextDocumentPosi
}

function getBashCompletionItems (): CompletionItem[] {
return []
return getBashCompletionItems()
}

function getPythonCompletionItems (documentUri: string, word: string | null, wordPosition: Position): CompletionItem[] {
Expand All @@ -163,7 +163,10 @@ function getPythonCompletionItems (documentUri: string, word: string | null, wor
...symbolCompletionItems
]
}
return []
if (analyzer.isStringContent(documentUri, wordPosition.line, wordPosition.character)) {
return []
}
return getYoctoTaskSnippets()
}

function getYoctoTaskSnippets (): CompletionItem[] {
Expand Down

0 comments on commit ac882ac

Please sign in to comment.