src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts/inlineCompletionToGhostText
export function inlineCompletionToGhostText(inlineCompletion: NormalizedInlineCompletion, textModel: ITextModel, mode: 'prefix' | 'subwordDiff', cursorPosition?: Position): GhostText | undefined {
	if (inlineCompletion.range.startLineNumber !== inlineCompletion.range.endLineNumber) {
		// Only single line replacements are supported.
		return undefined;
	}

	// This is a single line string
	const valueToBeReplaced = textModel.getValueInRange(inlineCompletion.range);

	const changes = stringDiff(valueToBeReplaced, inlineCompletion.text, false);

	const lineNumber = inlineCompletion.range.startLineNumber;

	const parts = new Array<GhostTextPart>();

	if (mode === 'prefix') {
		const filteredChanges = changes.filter(c => c.originalLength === 0);
		if (filteredChanges.length > 1 || filteredChanges.length === 1 && filteredChanges[0].originalStart !== valueToBeReplaced.length) {
			// Prefixes only have a single change.
			return undefined;
		}
	}
	for (const c of changes) {
		const insertColumn = inlineCompletion.range.startColumn + c.originalStart + c.originalLength;

		if (cursorPosition && cursorPosition.lineNumber === inlineCompletion.range.startLineNumber && insertColumn < cursorPosition.column) {
			// No ghost text before cursor
			return undefined;
		}

		if (c.originalLength > 0) {
			const originalText = valueToBeReplaced.substr(c.originalStart, c.originalLength);
			const firstNonWsCol = textModel.getLineFirstNonWhitespaceColumn(lineNumber);
			if (!(/^(\t| )*$/.test(originalText) && (firstNonWsCol === 0 || insertColumn <= firstNonWsCol))) {
				return undefined;
			}
		}

		if (c.modifiedLength === 0) {
			continue;
		}

		const text = inlineCompletion.text.substr(c.modifiedStart, c.modifiedLength);
		const lines = strings.splitLines(text);
		parts.push({ column: insertColumn, lines });
	}

	return new GhostText(lineNumber, parts, 0);
}