add experimental classRegex setting (#129)
parent
5633349c49
commit
a4fdd949be
File diff suppressed because it is too large
Load Diff
|
@ -158,6 +158,10 @@
|
|||
"default": "error",
|
||||
"markdownDescription": "Unknown value used with the [`@tailwind` directive](https://tailwindcss.com/docs/functions-and-directives/#tailwind)",
|
||||
"scope": "language-overridable"
|
||||
},
|
||||
"tailwindCSS.experimental.classRegex": {
|
||||
"type": "array",
|
||||
"scope": "language-overridable"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ const defaultSettings: Settings = {
|
|||
tabSize: 2,
|
||||
emmetCompletions: false,
|
||||
includeLanguages: {},
|
||||
experimental: {
|
||||
classRegex: [],
|
||||
},
|
||||
validate: true,
|
||||
lint: {
|
||||
cssConflict: 'warning',
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"line-column": "^1.0.2",
|
||||
"mitt": "^2.1.0",
|
||||
"moo": "^0.5.1",
|
||||
"multi-regexp2": "^1.0.3",
|
||||
"semver": "^7.3.2",
|
||||
"sift-string": "^0.0.2",
|
||||
"tsdx": "^0.13.3",
|
||||
|
@ -6417,6 +6418,11 @@
|
|||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/multi-regexp2": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/multi-regexp2/-/multi-regexp2-1.0.3.tgz",
|
||||
"integrity": "sha512-yYrsPk+8TW+r4HK8/7/BIqc7QzcMSIwUGwGouiwIC/anHpjCfKO/PNACGiPYn0WzEMiq+LuEAmZ80NRiCCykiw=="
|
||||
},
|
||||
"node_modules/mute-stream": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
|
||||
|
@ -14741,6 +14747,11 @@
|
|||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"multi-regexp2": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/multi-regexp2/-/multi-regexp2-1.0.3.tgz",
|
||||
"integrity": "sha512-yYrsPk+8TW+r4HK8/7/BIqc7QzcMSIwUGwGouiwIC/anHpjCfKO/PNACGiPYn0WzEMiq+LuEAmZ80NRiCCykiw=="
|
||||
},
|
||||
"mute-stream": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
"line-column": "^1.0.2",
|
||||
"mitt": "^2.1.0",
|
||||
"moo": "^0.5.1",
|
||||
"multi-regexp2": "^1.0.3",
|
||||
"semver": "^7.3.2",
|
||||
"sift-string": "^0.0.2",
|
||||
"tsdx": "^0.13.3",
|
||||
|
|
|
@ -31,6 +31,7 @@ import {
|
|||
} from './util/lexers'
|
||||
import { validateApply } from './util/validateApply'
|
||||
import { flagEnabled } from './util/flagEnabled'
|
||||
import MultiRegexp from 'multi-regexp2'
|
||||
|
||||
export function completionsFromClassList(
|
||||
state: State,
|
||||
|
@ -195,6 +196,72 @@ function provideClassAttributeCompletions(
|
|||
return null
|
||||
}
|
||||
|
||||
async function provideCustomClassNameCompletions(
|
||||
state: State,
|
||||
document: TextDocument,
|
||||
position: Position
|
||||
): Promise<CompletionList> {
|
||||
const settings = await getDocumentSettings(state, document)
|
||||
const regexes = dlv(settings, 'experimental.classRegex', [])
|
||||
if (regexes.length === 0) return null
|
||||
|
||||
const searchRange = {
|
||||
start: { line: Math.max(position.line - 10, 0), character: 0 },
|
||||
end: { line: position.line + 10, character: 0 },
|
||||
}
|
||||
|
||||
let str = document.getText(searchRange)
|
||||
|
||||
for (let i = 0; i < regexes.length; i++) {
|
||||
let [containerRegex, classRegex] = Array.isArray(regexes[i])
|
||||
? regexes[i]
|
||||
: [regexes[i]]
|
||||
containerRegex = new MultiRegexp(new RegExp(containerRegex))
|
||||
try {
|
||||
const match = containerRegex.execForGroup(str, 1)
|
||||
if (match === null) {
|
||||
throw Error()
|
||||
}
|
||||
const searchStart = document.offsetAt(searchRange.start)
|
||||
const matchStart = searchStart + match.start
|
||||
const matchEnd = searchStart + match.end
|
||||
const cursor = document.offsetAt(position)
|
||||
if (cursor >= matchStart && cursor <= matchEnd) {
|
||||
let classList
|
||||
|
||||
if (classRegex) {
|
||||
classRegex = new MultiRegexp(new RegExp(classRegex, 'g'))
|
||||
let classMatch
|
||||
while (
|
||||
(classMatch = classRegex.execForGroup(match.match, 1)) !== null
|
||||
) {
|
||||
const classMatchStart = matchStart + classMatch.start
|
||||
const classMatchEnd = matchStart + classMatch.end
|
||||
if (cursor >= classMatchStart && cursor <= classMatchEnd) {
|
||||
classList = classMatch.match.substr(0, cursor - classMatchStart)
|
||||
}
|
||||
}
|
||||
if (typeof classList === 'undefined') {
|
||||
throw Error()
|
||||
}
|
||||
} else {
|
||||
classList = match.match.substr(0, cursor - matchStart)
|
||||
}
|
||||
|
||||
return completionsFromClassList(state, classList, {
|
||||
start: {
|
||||
line: position.line,
|
||||
character: position.character - classList.length,
|
||||
},
|
||||
end: position,
|
||||
})
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function provideAtApplyCompletions(
|
||||
state: State,
|
||||
document: TextDocument,
|
||||
|
@ -711,7 +778,8 @@ export async function doComplete(
|
|||
provideCssDirectiveCompletions(state, document, position) ||
|
||||
provideScreenDirectiveCompletions(state, document, position) ||
|
||||
provideVariantsDirectiveCompletions(state, document, position) ||
|
||||
provideTailwindDirectiveCompletions(state, document, position)
|
||||
provideTailwindDirectiveCompletions(state, document, position) ||
|
||||
(await provideCustomClassNameCompletions(state, document, position))
|
||||
|
||||
if (result) return result
|
||||
|
||||
|
|
|
@ -41,6 +41,9 @@ export type Settings = {
|
|||
invalidConfigPath: DiagnosticSeveritySetting
|
||||
invalidTailwindDirective: DiagnosticSeveritySetting
|
||||
}
|
||||
experimental: {
|
||||
classRegex: string[]
|
||||
}
|
||||
}
|
||||
|
||||
interface NotificationEmitter {
|
||||
|
|
Loading…
Reference in New Issue