[JIT] add opacity modifier completions
parent
1d0af70caa
commit
5cf4b1717d
|
@ -7,6 +7,7 @@ import type {
|
||||||
CompletionList,
|
CompletionList,
|
||||||
TextDocument,
|
TextDocument,
|
||||||
Position,
|
Position,
|
||||||
|
CompletionContext,
|
||||||
} from 'vscode-languageserver'
|
} from 'vscode-languageserver'
|
||||||
const dlv = require('dlv')
|
const dlv = require('dlv')
|
||||||
import removeMeta from './util/removeMeta'
|
import removeMeta from './util/removeMeta'
|
||||||
|
@ -43,7 +44,8 @@ export function completionsFromClassList(
|
||||||
classList: string,
|
classList: string,
|
||||||
classListRange: Range,
|
classListRange: Range,
|
||||||
filter?: (item: CompletionItem) => boolean,
|
filter?: (item: CompletionItem) => boolean,
|
||||||
document?: TextDocument
|
document?: TextDocument,
|
||||||
|
context?: CompletionContext
|
||||||
): CompletionList {
|
): CompletionList {
|
||||||
let classNames = classList.split(/[\s+]/)
|
let classNames = classList.split(/[\s+]/)
|
||||||
const partialClassName = classNames[classNames.length - 1]
|
const partialClassName = classNames[classNames.length - 1]
|
||||||
|
@ -62,6 +64,58 @@ export function completionsFromClassList(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.jit) {
|
if (state.jit) {
|
||||||
|
if (
|
||||||
|
context &&
|
||||||
|
(context.triggerKind === 1 ||
|
||||||
|
(context.triggerKind === 2 && context.triggerCharacter === '/')) &&
|
||||||
|
partialClassName.includes('/')
|
||||||
|
) {
|
||||||
|
let beforeSlash = partialClassName.split('/').slice(0, -1).join('/')
|
||||||
|
let testClass = beforeSlash + '/[0]'
|
||||||
|
let { rules } = jit.generateRules(state, [testClass])
|
||||||
|
if (rules.length > 0) {
|
||||||
|
let opacities = dlv(state.config, 'theme.opacity', {})
|
||||||
|
if (!isObject(opacities)) {
|
||||||
|
opacities = {}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
isIncomplete: false,
|
||||||
|
items: Object.keys(opacities).map((opacity, index) => {
|
||||||
|
let className = `${beforeSlash}/${opacity}`
|
||||||
|
let kind: CompletionItemKind = 21
|
||||||
|
let documentation: string = null
|
||||||
|
|
||||||
|
const color = getColor(state, className)
|
||||||
|
if (color !== null) {
|
||||||
|
kind = 16
|
||||||
|
if (typeof color !== 'string') {
|
||||||
|
documentation = color.toRgbString().replace(/(^rgba\([^)]+) 0\)$/, '$1 0.001)')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: opacity,
|
||||||
|
detail: stringifyConfigValue(opacities[opacity]),
|
||||||
|
documentation,
|
||||||
|
kind,
|
||||||
|
sortText: naturalExpand(index),
|
||||||
|
data: [className],
|
||||||
|
textEdit: {
|
||||||
|
newText: opacity,
|
||||||
|
range: {
|
||||||
|
...replacementRange,
|
||||||
|
start: {
|
||||||
|
...replacementRange.start,
|
||||||
|
character: replacementRange.start.character + beforeSlash.length + 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let allVariants = Object.keys(state.variants)
|
let allVariants = Object.keys(state.variants)
|
||||||
let { variants: existingVariants, offset } = getVariantsFromClassName(state, partialClassName)
|
let { variants: existingVariants, offset } = getVariantsFromClassName(state, partialClassName)
|
||||||
|
|
||||||
|
@ -256,7 +310,8 @@ export function completionsFromClassList(
|
||||||
function provideClassAttributeCompletions(
|
function provideClassAttributeCompletions(
|
||||||
state: State,
|
state: State,
|
||||||
document: TextDocument,
|
document: TextDocument,
|
||||||
position: Position
|
position: Position,
|
||||||
|
context?: CompletionContext
|
||||||
): CompletionList {
|
): CompletionList {
|
||||||
let str = document.getText({
|
let str = document.getText({
|
||||||
start: { line: Math.max(position.line - 10, 0), character: 0 },
|
start: { line: Math.max(position.line - 10, 0), character: 0 },
|
||||||
|
@ -299,7 +354,8 @@ function provideClassAttributeCompletions(
|
||||||
end: position,
|
end: position,
|
||||||
},
|
},
|
||||||
undefined,
|
undefined,
|
||||||
document
|
document,
|
||||||
|
context
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
@ -417,10 +473,11 @@ function provideAtApplyCompletions(
|
||||||
function provideClassNameCompletions(
|
function provideClassNameCompletions(
|
||||||
state: State,
|
state: State,
|
||||||
document: TextDocument,
|
document: TextDocument,
|
||||||
position: Position
|
position: Position,
|
||||||
|
context?: CompletionContext
|
||||||
): CompletionList {
|
): CompletionList {
|
||||||
if (isHtmlContext(state, document, position) || isJsContext(state, document, position)) {
|
if (isHtmlContext(state, document, position) || isJsContext(state, document, position)) {
|
||||||
return provideClassAttributeCompletions(state, document, position)
|
return provideClassAttributeCompletions(state, document, position, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCssContext(state, document, position)) {
|
if (isCssContext(state, document, position)) {
|
||||||
|
@ -925,11 +982,16 @@ async function provideEmmetCompletions(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function doComplete(state: State, document: TextDocument, position: Position) {
|
export async function doComplete(
|
||||||
|
state: State,
|
||||||
|
document: TextDocument,
|
||||||
|
position: Position,
|
||||||
|
context?: CompletionContext
|
||||||
|
) {
|
||||||
if (state === null) return { items: [], isIncomplete: false }
|
if (state === null) return { items: [], isIncomplete: false }
|
||||||
|
|
||||||
const result =
|
const result =
|
||||||
provideClassNameCompletions(state, document, position) ||
|
provideClassNameCompletions(state, document, position, context) ||
|
||||||
provideCssHelperCompletions(state, document, position) ||
|
provideCssHelperCompletions(state, document, position) ||
|
||||||
provideCssDirectiveCompletions(state, document, position) ||
|
provideCssDirectiveCompletions(state, document, position) ||
|
||||||
provideScreenDirectiveCompletions(state, document, position) ||
|
provideScreenDirectiveCompletions(state, document, position) ||
|
||||||
|
@ -958,8 +1020,13 @@ export async function resolveCompletionItem(
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray(item.data)) {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
if (state.jit) {
|
if (state.jit) {
|
||||||
if (item.kind === 9) return item
|
if (item.kind === 9) return item
|
||||||
|
if (item.detail && item.documentation) return item
|
||||||
let { root, rules } = jit.generateRules(state, [item.data.join(state.separator)])
|
let { root, rules } = jit.generateRules(state, [item.data.join(state.separator)])
|
||||||
if (rules.length === 0) return item
|
if (rules.length === 0) return item
|
||||||
if (!item.detail) {
|
if (!item.detail) {
|
||||||
|
|
|
@ -85,6 +85,8 @@ const TRIGGER_CHARACTERS = [
|
||||||
'[',
|
'[',
|
||||||
// JIT "important" prefix
|
// JIT "important" prefix
|
||||||
'!',
|
'!',
|
||||||
|
// JIT opacity modifiers
|
||||||
|
'/',
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
const colorNames = Object.keys(namedColors)
|
const colorNames = Object.keys(namedColors)
|
||||||
|
@ -748,7 +750,7 @@ async function createProjectService(
|
||||||
if (!state.enabled) return null
|
if (!state.enabled) return null
|
||||||
let document = documentService.getDocument(params.textDocument.uri)
|
let document = documentService.getDocument(params.textDocument.uri)
|
||||||
if (!document) return null
|
if (!document) return null
|
||||||
return doComplete(state, document, params.position)
|
return doComplete(state, document, params.position, params.context)
|
||||||
},
|
},
|
||||||
onCompletionResolve(item: CompletionItem): Promise<CompletionItem> {
|
onCompletionResolve(item: CompletionItem): Promise<CompletionItem> {
|
||||||
if (!state.enabled) return null
|
if (!state.enabled) return null
|
||||||
|
|
Loading…
Reference in New Issue