in src/yaml/aslYamlLanguageService.ts [75:279]
export const getLanguageService = function(params: LanguageServiceParams, schema: JSONSchema, aslLanguageService: LanguageService): LanguageService {
const builtInParams = {}
const languageService = getLanguageServiceVscode({
...params,
...builtInParams,
})
const requestServiceMock = async function(uri: string): Promise<string> {
return new Promise<string>(c => {
c(JSON.stringify(schema))
})
}
const schemaService = new YAMLSchemaService(requestServiceMock, params.workspaceContext)
// initialize schema
schemaService.registerExternalSchema(LANGUAGE_IDS.YAML, ['*'], schema)
schemaService.getOrAddSchemaHandle(LANGUAGE_IDS.YAML, schema)
const completer = new YAMLCompletion(schemaService)
languageService.doValidation = async function(
textDocument: TextDocument
) {
const yamlDocument: YAMLDocument = parseYAML(textDocument.getText())
const validationResult: Diagnostic[] = []
for (const currentYAMLDoc of yamlDocument.documents) {
const validation = await aslLanguageService.doValidation(textDocument, currentYAMLDoc)
validationResult.push(
...currentYAMLDoc.errors
.concat(currentYAMLDoc.warnings)
.map(err => convertYAMLDiagnostic(err, textDocument))
)
validationResult.push(...validation)
}
return validationResult
}
languageService.doComplete = async function(
document: TextDocument,
position: Position
): Promise<CompletionList> {
const {
modifiedDocText,
tempPositionForCompletions,
startPositionForInsertion,
endPositionForInsertion,
shouldPrependSpace
} = processYamlDocForCompletion(document, position)
const processedDocument = TextDocument.create(document.uri, document.languageId, document.version, modifiedDocText)
const offsetIntoOriginalDocument = document.offsetAt(position)
const offsetIntoProcessedDocument = processedDocument.offsetAt(tempPositionForCompletions)
const processedYamlDoc: YAMLDocument = parseYAML(modifiedDocText)
const currentDoc = matchOffsetToDocument(offsetIntoProcessedDocument, processedYamlDoc)
if (!currentDoc) {
return { items: [], isIncomplete: false }
}
const positionForDoComplete = {...tempPositionForCompletions} // Copy position to new object since doComplete modifies the position
const yamlCompletions = await completer.doComplete(processedDocument, positionForDoComplete, false)
// yaml-language-server does not output correct completions for retry/catch
// we need to overwrite the text
function updateCompletionText(item: CompletionItem, text: string) {
item.insertText = text
if (item.textEdit) {
item.textEdit.newText = text
}
}
yamlCompletions.items.forEach(item => {
if (item.label === 'Catch') {
updateCompletionText(item, CATCH_INSERT)
} else if (item.label === 'Retry') {
updateCompletionText(item, RETRY_INSERT)
}
})
const { isDirectChildOfStates, isWithinCatchRetryState, hasCatchPropSibling, hasRetryPropSibling } = getOffsetData(document, offsetIntoOriginalDocument)
const aslOptions: ASLOptions = {
ignoreColonOffset: true,
shouldShowStateSnippets: isDirectChildOfStates,
shouldShowErrorSnippets: {
retry: isWithinCatchRetryState && !hasRetryPropSibling,
catch: isWithinCatchRetryState && !hasCatchPropSibling
}
}
const aslCompletions: CompletionList = doCompleteAsl(processedDocument, tempPositionForCompletions, currentDoc, yamlCompletions, aslOptions)
const modifiedAslCompletionItems: CompletionItem[] = aslCompletions.items.map(completionItem => {
const completionItemCopy = {...completionItem} // Copy completion to new object to avoid overwriting any snippets
if (completionItemCopy.insertText && completionItemCopy.kind === CompletionItemKind.Snippet && document.languageId === LANGUAGE_IDS.YAML) {
completionItemCopy.insertText = convertJsonSnippetToYaml(completionItemCopy.insertText)
} else {
const currentTextEdit = completionItemCopy.textEdit
if (currentTextEdit) {
if (shouldPrependSpace) {
if (currentTextEdit.newText && currentTextEdit.newText.charAt(0) !== ' ') {
currentTextEdit.newText = ' ' + currentTextEdit.newText
}
if (completionItemCopy.insertText && completionItemCopy.insertText.charAt(0) !== ' ') {
completionItemCopy.insertText = ' ' + completionItemCopy.insertText
}
}
currentTextEdit.range.start = startPositionForInsertion
currentTextEdit.range.end = endPositionForInsertion
// Completions that include both a key and a value should replace everything right of the cursor.
if (completionItemCopy.kind === CompletionItemKind.Property) {
currentTextEdit.range.end = {
line: endPositionForInsertion.line,
character: document.getText().length
}
}
}
}
return completionItemCopy
})
const modifiedAslCompletions: CompletionList = {
isIncomplete: aslCompletions.isIncomplete,
items: modifiedAslCompletionItems
}
return Promise.resolve(modifiedAslCompletions)
}
languageService.doHover = function(
document: TextDocument,
position: Position
): Thenable<Hover | null> {
const doc = parseYAML(document.getText())
const offset = document.offsetAt(position)
const currentDoc = matchOffsetToDocument(offset, doc)
if (!currentDoc) {
// tslint:disable-next-line: no-null-keyword
return Promise.resolve(null)
}
const currentDocIndex = doc.documents.indexOf(currentDoc)
currentDoc.currentDocIndex = currentDocIndex
return aslLanguageService.doHover(document, position, currentDoc)
}
languageService.format = function(
document: TextDocument,
range: Range,
options: FormattingOptions
): TextEdit[] {
try {
const text = document.getText()
const formatted = safeDump(safeLoad(text), { indent: options.tabSize })
return [TextEdit.replace(Range.create(Position.create(0, 0), document.positionAt(text.length)), formatted)]
} catch (error) {
return []
}
}
languageService.findDocumentSymbols = function(document: TextDocument): SymbolInformation[] {
const doc = parseYAML(document.getText())
if (!doc || doc.documents.length === 0) {
return []
}
let results: any[] = []
for (const yamlDoc of doc.documents) {
if (yamlDoc.root) {
results = results.concat(aslLanguageService.findDocumentSymbols(document, yamlDoc))
}
}
return results
}
languageService.findDocumentSymbols2 = function(document: TextDocument): DocumentSymbol[] {
const doc = parseYAML(document.getText())
if (!doc || doc.documents.length === 0) {
return []
}
let results: any[] = []
for (const yamlDoc of doc.documents) {
if (yamlDoc.root) {
results = results.concat(aslLanguageService.findDocumentSymbols2(document, yamlDoc))
}
}
return results
}
return languageService
}