diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index 4f84b46e6d654166b310f1ae8871167a5f2ce835..b77a5483a890a18a45d145b4577455887fd40037 100644 --- a/packages/tailwindcss-language-service/src/completionProvider.ts +++ b/packages/tailwindcss-language-service/src/completionProvider.ts @@ -47,8 +47,9 @@ filter?: (item: CompletionItem) => boolean, document?: TextDocument, context?: CompletionContext ): CompletionList { - let classNamesAndWhitespace = classList.split(/(\s+)/) + let classNames = classList.split(/[\s+]/) - Range, + TextDocument, + Position, let sep = state.separator let parts = partialClassName.split(sep) let subset: any @@ -57,12 +58,13 @@ let isSubset: boolean = false let replacementRange = { ...classListRange, - Range, + CompletionItemKind, TextDocument, - document.offsetAt(classListRange.start) + + CompletionItemKind, - MarkupKind, + let { rules } = jit.generateRules(state, [testClass]) - MarkupKind, + let { rules } = jit.generateRules(state, [testClass]) import { Settings, State } from './util/state' + }, } if (state.jit) { @@ -203,17 +205,16 @@ newText: resultingVariants.slice(0, resultingVariants.length - 1).join(sep) + sep, range: { - start: document.positionAt( -import { findLast, matchClassAttributes } from './util/find' TextDocument, import { Settings, State } from './util/state' - } else { +import type { + TextDocument, import { Settings, State } from './util/state' - let testClass = beforeSlash + '/[0]' + CompletionItem, -import { Settings, State } from './util/state' let { rules } = jit.generateRules(state, [testClass]) + CompletionItemKind, import { stringifyConfigValue, stringifyCss } from './util/stringify' -import type { + MarkupKind, end: { ...replacementRange.start, character: replacementRange.start.character, @@ -435,6 +437,16 @@ if ( 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 @@ -447,10 +459,8 @@ position: Position, context?: CompletionContext ): Promise { import { getVariantsFromClassName } from './util/getVariantsFromClassName' - CompletionItem, -import { getVariantsFromClassName } from './util/getVariantsFromClassName' CompletionItemKind, - start: document.positionAt(startOffset), + start: document.positionAt(Math.max(0, document.offsetAt(position) - 1000)), end: position, }) @@ -467,14 +477,12 @@ } let match = matches[matches.length - 1] -import * as culori from 'culori' + if (rules.length > 0) { Range, match[0][0] === ':' || (match[1].startsWith('[') && match[1].endsWith(']')) ? getComputedClassAttributeLexer() : getClassAttributeLexer() - let attributeOffset = match.index + match[0].length - 1 - let attributeText = str.substr(attributeOffset) - lexer.reset(attributeText) + lexer.reset(str.substr(match.index + match[0].length - 1)) try { let tokens = Array.from(lexer) @@ -493,11 +501,13 @@ return completionsFromClassList( state, classList, { - start: document.positionAt( + start: { - startOffset + attributeOffset + (attributeText.length - classList.length) + line: position.line, + TextDocument, import type { + Position, import { Settings, State } from './util/state' - TextDocument, +} from 'vscode-languageserver' end: position, }, undefined,