Skip to content

Commit 534eb25

Browse files
committed
update custom regex support (#129)
fixes "ors" in regexes
1 parent d115e00 commit 534eb25

File tree

1 file changed

+60
-7
lines changed

1 file changed

+60
-7
lines changed

packages/tailwindcss-language-service/src/completionProvider.ts

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,62 @@ function provideClassAttributeCompletions(
197197
return null
198198
}
199199

200+
function createMultiRegexp(regexString: string) {
201+
let insideCharClass = false
202+
let captureGroupIndex = -1
203+
204+
for (let i = 0; i < regexString.length; i++) {
205+
if (
206+
!insideCharClass &&
207+
regexString[i] === '[' &&
208+
regexString[i - 1] !== '\\'
209+
) {
210+
insideCharClass = true
211+
} else if (
212+
insideCharClass &&
213+
regexString[i] === ']' &&
214+
regexString[i - 1] !== '\\'
215+
) {
216+
insideCharClass = false
217+
} else if (
218+
!insideCharClass &&
219+
regexString[i] === '(' &&
220+
regexString.substr(i + 1, 2) !== '?:'
221+
) {
222+
captureGroupIndex = i
223+
break
224+
}
225+
}
226+
227+
const re = /(?:[^\\]|^)\(\?:/g
228+
let match: RegExpExecArray
229+
let nonCaptureGroupIndexes: number[] = []
230+
231+
while ((match = re.exec(regexString)) !== null) {
232+
if (match[0].startsWith('(')) {
233+
nonCaptureGroupIndexes.push(match.index)
234+
} else {
235+
nonCaptureGroupIndexes.push(match.index + 1)
236+
}
237+
}
238+
239+
const regex = new MultiRegexp(
240+
new RegExp(
241+
regexString.replace(re, (m) => m.substr(0, m.length - 2)),
242+
'g'
243+
)
244+
)
245+
246+
let groupIndex =
247+
1 + nonCaptureGroupIndexes.filter((i) => i < captureGroupIndex).length
248+
249+
return {
250+
exec: (str: string) => {
251+
return regex.execForGroup(str, groupIndex)
252+
},
253+
}
254+
}
255+
200256
async function provideCustomClassNameCompletions(
201257
state: State,
202258
document: TextDocument,
@@ -221,10 +277,10 @@ async function provideCustomClassNameCompletions(
221277
? regexes[i]
222278
: [regexes[i]]
223279

224-
containerRegex = new MultiRegexp(new RegExp(containerRegex, 'g'))
280+
containerRegex = createMultiRegexp(containerRegex)
225281
let containerMatch
226282

227-
while ((containerMatch = containerRegex.execForGroup(str, 1)) !== null) {
283+
while ((containerMatch = containerRegex.exec(str)) !== null) {
228284
const searchStart = document.offsetAt(searchRange.start)
229285
const matchStart = searchStart + containerMatch.start
230286
const matchEnd = searchStart + containerMatch.end
@@ -233,14 +289,11 @@ async function provideCustomClassNameCompletions(
233289
let classList
234290

235291
if (classRegex) {
236-
classRegex = new MultiRegexp(new RegExp(classRegex, 'g'))
292+
classRegex = createMultiRegexp(classRegex)
237293
let classMatch
238294

239295
while (
240-
(classMatch = classRegex.execForGroup(
241-
containerMatch.match,
242-
1
243-
)) !== null
296+
(classMatch = classRegex.exec(containerMatch.match)) !== null
244297
) {
245298
const classMatchStart = matchStart + classMatch.start
246299
const classMatchEnd = matchStart + classMatch.end

0 commit comments

Comments
 (0)