diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index b77a548..4f84b46 100644 --- a/packages/tailwindcss-language-service/src/completionProvider.ts +++ b/packages/tailwindcss-language-service/src/completionProvider.ts @@ -47,8 +47,8 @@ export function completionsFromClassList( document?: TextDocument, context?: CompletionContext ): CompletionList { - let classNames = classList.split(/[\s+]/) - const partialClassName = classNames[classNames.length - 1] + let classNamesAndWhitespace = classList.split(/(\s+)/) + const partialClassName = classNamesAndWhitespace[classNamesAndWhitespace.length - 1] let sep = state.separator let parts = partialClassName.split(sep) let subset: any @@ -57,10 +57,10 @@ export function completionsFromClassList( let replacementRange = { ...classListRange, - start: { - ...classListRange.start, - character: classListRange.end.character - partialClassName.length, - }, + start: document.positionAt( + document.offsetAt(classListRange.start) + + classNamesAndWhitespace.slice(0, classNamesAndWhitespace.length - 1).join('').length + ), } if (state.jit) { @@ -201,10 +201,12 @@ export function completionsFromClassList( resultingVariants.slice(0, resultingVariants.length - 1).join(sep) + sep, range: { - start: { - ...classListRange.start, - character: classListRange.end.character - partialClassName.length, - }, + start: document.positionAt( + document.offsetAt(classListRange.start) + + classNamesAndWhitespace + .slice(0, classNamesAndWhitespace.length - 1) + .join('').length + ), end: { ...replacementRange.start, character: replacementRange.start.character, @@ -427,16 +429,6 @@ function ensureTriggerCharacterIsIncluded( context.triggerKind === 2 && // CompletionTriggerKind.TriggerCharacter text.slice(-1) !== context.triggerCharacter ) { - let nextChar = document.getText({ - start: position, - end: document.positionAt(document.offsetAt(position) + 1), - }) - // If there's a next char (i.e. we're not at the end of the document) - // then it will be included instead of the trigger character, so we replace it. - // Otherwise we just append. - if (nextChar.length === 0) { - return `${text}${context.triggerCharacter}` - } return `${text.slice(0, text.length - 1)}${context.triggerCharacter}` } return text @@ -448,8 +440,9 @@ async function provideClassAttributeCompletions( position: Position, context?: CompletionContext ): Promise { + let startOffset = Math.max(0, document.offsetAt(position) - 1000) let str = document.getText({ - start: document.positionAt(Math.max(0, document.offsetAt(position) - 1000)), + start: document.positionAt(startOffset), end: position, }) @@ -466,11 +459,13 @@ async function provideClassAttributeCompletions( let match = matches[matches.length - 1] - const lexer = + let lexer = match[0][0] === ':' || (match[1].startsWith('[') && match[1].endsWith(']')) ? getComputedClassAttributeLexer() : getClassAttributeLexer() - lexer.reset(str.substr(match.index + match[0].length - 1)) + let attributeOffset = match.index + match[0].length - 1 + let attributeText = str.substr(attributeOffset) + lexer.reset(attributeText) try { let tokens = Array.from(lexer) @@ -489,10 +484,9 @@ async function provideClassAttributeCompletions( state, classList, { - start: { - line: position.line, - character: position.character - classList.length, - }, + start: document.positionAt( + startOffset + attributeOffset + (attributeText.length - classList.length) + ), end: position, }, undefined,