1
1
'use strict'
2
2
3
3
import * as vscode from 'vscode'
4
- import { join , dirname } from 'path'
4
+ import { dirname } from 'path'
5
+ const htmlElements = require ( './htmlElements.js' )
5
6
const tailwindClassNames = require ( 'tailwind-class-names' )
6
7
const dlv = require ( 'dlv' )
7
8
const Color = require ( 'color' )
@@ -21,9 +22,7 @@ const HTML_TYPES = [
21
22
'handlebars' ,
22
23
'ejs' ,
23
24
'nunjucks' ,
24
- 'haml' ,
25
- // for jsx
26
- ...JS_TYPES
25
+ 'haml'
27
26
]
28
27
const CSS_TYPES = [ 'css' , 'sass' , 'scss' , 'less' , 'postcss' , 'stylus' ]
29
28
@@ -147,7 +146,17 @@ function createCompletionItemProvider({
147
146
// match emmet style syntax
148
147
// e.g. .flex.items-center
149
148
let currentLine = lines [ lines . length - 1 ]
150
- matches = currentLine . match ( / \. ( [ ^ ( ) # > * ^ \[ \] = $ @ { } ] * ) $ / i)
149
+ let currentWord = currentLine . split ( ' ' ) . pop ( )
150
+ matches = currentWord . match ( / ^ \. ( [ ^ . ( ) # > * ^ \[ \] = $ @ { } ] * ) $ / )
151
+ if ( ! matches ) {
152
+ matches = currentWord . match (
153
+ new RegExp (
154
+ `^([A-Z][a-zA-Z0-9]*|[a-z][a-z0-9]*-[a-z0-9-]+|${ htmlElements . join (
155
+ '|'
156
+ ) } ).*?\\.([^.()#>*^ \\[\\]=$@{}]*)$`
157
+ )
158
+ )
159
+ }
151
160
let parts = matches [ matches . length - 1 ] . split ( '.' )
152
161
str = parts [ parts . length - 1 ]
153
162
}
@@ -422,32 +431,78 @@ class TailwindIntellisense {
422
431
createCompletionItemProvider ( {
423
432
items : this . _items ,
424
433
languages : HTML_TYPES ,
425
- regex : / \b c l a s s ( N a m e ) ? = [ " ' ] ( [ ^ " ' ] * ) $ / , // /\bclass(Name)?=(["'])(?!.*?\2)/
434
+ regex : / \b c l a s s = [ " ' ] ( [ ^ " ' ] * ) $ / , // /\bclass(Name)?=(["'])(?!.*?\2)/
426
435
triggerCharacters : [ "'" , '"' , ' ' , '.' , separator ] ,
427
436
config : tailwind . config ,
428
437
emmet : true
429
438
} )
430
439
)
431
440
441
+ this . _providers . push (
442
+ createCompletionItemProvider ( {
443
+ items : this . _items ,
444
+ languages : JS_TYPES ,
445
+ regex : / \b c l a s s ( N a m e ) ? = [ " ' ] ( [ ^ " ' ] * ) $ / , // /\bclass(Name)?=(["'])(?!.*?\2)/
446
+ triggerCharacters : [ "'" , '"' , ' ' , separator ]
447
+ . concat ( [
448
+ Object . keys (
449
+ vscode . workspace . getConfiguration ( 'emmet.includeLanguages' )
450
+ ) . indexOf ( 'javascript' ) !== - 1 && '.'
451
+ ] )
452
+ . filter ( Boolean ) ,
453
+ config : tailwind . config ,
454
+ emmet :
455
+ Object . keys (
456
+ vscode . workspace . getConfiguration ( 'emmet.includeLanguages' )
457
+ ) . indexOf ( 'javascript' ) !== - 1
458
+ } )
459
+ )
460
+
432
461
// Vue.js
433
462
this . _providers . push (
434
463
createCompletionItemProvider ( {
435
464
items : this . _items ,
436
465
languages : [ 'vue' ] ,
437
- regex : / \b c l a s s ( N a m e ) ? = [ " ' ] ( [ ^ " ' ] * ) $ / ,
466
+ regex : / \b c l a s s = [ " ' ] ( [ ^ " ' ] * ) $ / ,
438
467
enable : text => {
439
468
if (
440
- ( text . indexOf ( '<template' ) !== - 1 &&
441
- text . indexOf ( '</template>' ) === - 1 ) ||
442
- ( text . indexOf ( '<script' ) !== - 1 && text . indexOf ( '</script>' ) === - 1 )
469
+ text . indexOf ( '<template' ) !== - 1 &&
470
+ text . indexOf ( '</template>' ) === - 1
443
471
) {
444
472
return true
445
473
}
446
474
return false
447
475
} ,
448
- triggerCharacters : [ "'" , '"' , ' ' , '.' , separator ] ,
476
+ triggerCharacters : [ "'" , '"' , ' ' , separator ]
477
+ . concat ( [
478
+ Object . keys (
479
+ vscode . workspace . getConfiguration ( 'emmet.includeLanguages' )
480
+ ) . indexOf ( 'vue-html' ) !== - 1 && '.'
481
+ ] )
482
+ . filter ( Boolean ) ,
449
483
config : tailwind . config ,
450
- emmet : true
484
+ emmet :
485
+ Object . keys (
486
+ vscode . workspace . getConfiguration ( 'emmet.includeLanguages' )
487
+ ) . indexOf ( 'vue-html' ) !== - 1
488
+ } )
489
+ )
490
+ this . _providers . push (
491
+ createCompletionItemProvider ( {
492
+ items : this . _items ,
493
+ languages : [ 'vue' ] ,
494
+ regex : / \b c l a s s = [ " ' ] ( [ ^ " ' ] * ) $ / ,
495
+ enable : text => {
496
+ if (
497
+ text . indexOf ( '<script' ) !== - 1 &&
498
+ text . indexOf ( '</script>' ) === - 1
499
+ ) {
500
+ return true
501
+ }
502
+ return false
503
+ } ,
504
+ triggerCharacters : [ "'" , '"' , ' ' , separator ] ,
505
+ config : tailwind . config
451
506
} )
452
507
)
453
508
this . _providers . push (
@@ -493,86 +548,89 @@ class TailwindIntellisense {
493
548
)
494
549
495
550
this . _providers . push (
496
- vscode . languages . registerHoverProvider ( HTML_TYPES , {
497
- provideHover : ( document , position , token ) => {
498
- const range1 : vscode . Range = new vscode . Range (
499
- new vscode . Position ( Math . max ( position . line - 5 , 0 ) , 0 ) ,
500
- position
501
- )
502
- const text1 : string = document . getText ( range1 )
503
-
504
- if ( ! / \b c l a s s ( N a m e ) ? = [ ' " ] [ ^ ' " ] * $ / . test ( text1 ) ) return
505
-
506
- const range2 : vscode . Range = new vscode . Range (
507
- new vscode . Position ( Math . max ( position . line - 5 , 0 ) , 0 ) ,
508
- position . with ( { line : position . line + 1 } )
509
- )
510
- const text2 : string = document . getText ( range2 )
511
-
512
- let str = text1 + text2 . substr ( text1 . length ) . match ( / ^ ( [ ^ " ' ] * ) / ) [ 0 ]
513
- let matches = str . match ( / \b c l a s s ( N a m e ) ? = [ " ' ] ( [ ^ " ' ] * ) $ / )
514
-
515
- if ( matches && matches [ 2 ] ) {
516
- let className = matches [ 2 ] . split ( ' ' ) . pop ( )
517
- let parts = className . split ( ':' )
518
-
519
- if ( typeof dlv ( this . _tailwind . classNames , parts ) === 'string' ) {
520
- let base = parts . pop ( )
521
- let selector = `.${ escapeClassName ( className ) } `
522
-
523
- if ( parts . indexOf ( 'hover' ) !== - 1 ) {
524
- selector += ':hover'
525
- } else if ( parts . indexOf ( 'focus' ) !== - 1 ) {
526
- selector += ':focus'
527
- } else if ( parts . indexOf ( 'active' ) !== - 1 ) {
528
- selector += ':active'
529
- } else if ( parts . indexOf ( 'group-hover' ) !== - 1 ) {
530
- selector = `.group:hover ${ selector } `
531
- }
551
+ vscode . languages . registerHoverProvider (
552
+ [ ...HTML_TYPES , ...JS_TYPES , 'vue' ] ,
553
+ {
554
+ provideHover : ( document , position , token ) => {
555
+ const range1 : vscode . Range = new vscode . Range (
556
+ new vscode . Position ( Math . max ( position . line - 5 , 0 ) , 0 ) ,
557
+ position
558
+ )
559
+ const text1 : string = document . getText ( range1 )
560
+
561
+ if ( ! / \b c l a s s ( N a m e ) ? = [ ' " ] [ ^ ' " ] * $ / . test ( text1 ) ) return
562
+
563
+ const range2 : vscode . Range = new vscode . Range (
564
+ new vscode . Position ( Math . max ( position . line - 5 , 0 ) , 0 ) ,
565
+ position . with ( { line : position . line + 1 } )
566
+ )
567
+ const text2 : string = document . getText ( range2 )
568
+
569
+ let str = text1 + text2 . substr ( text1 . length ) . match ( / ^ ( [ ^ " ' ] * ) / ) [ 0 ]
570
+ let matches = str . match ( / \b c l a s s ( N a m e ) ? = [ " ' ] ( [ ^ " ' ] * ) $ / )
571
+
572
+ if ( matches && matches [ 2 ] ) {
573
+ let className = matches [ 2 ] . split ( ' ' ) . pop ( )
574
+ let parts = className . split ( ':' )
575
+
576
+ if ( typeof dlv ( this . _tailwind . classNames , parts ) === 'string' ) {
577
+ let base = parts . pop ( )
578
+ let selector = `.${ escapeClassName ( className ) } `
579
+
580
+ if ( parts . indexOf ( 'hover' ) !== - 1 ) {
581
+ selector += ':hover'
582
+ } else if ( parts . indexOf ( 'focus' ) !== - 1 ) {
583
+ selector += ':focus'
584
+ } else if ( parts . indexOf ( 'active' ) !== - 1 ) {
585
+ selector += ':active'
586
+ } else if ( parts . indexOf ( 'group-hover' ) !== - 1 ) {
587
+ selector = `.group:hover ${ selector } `
588
+ }
532
589
533
- let hoverStr = new vscode . MarkdownString ( )
534
- let css = this . _tailwind . classNames [ base ]
535
- let m = css . match ( / ^ ( : : ? [ a - z - ] + ) { ( .* ?) } / )
536
- if ( m ) {
537
- selector += m [ 1 ]
538
- css = m [ 2 ] . trim ( )
539
- }
540
- css = css . replace ( / ( [ ; { ] ) / g, '$1\n' ) . replace ( / ^ / gm, ' ' )
541
- let code = `${ selector } {\n${ css } \n}`
542
- let screens = dlv ( this . _tailwind . config , 'screens' , { } )
543
-
544
- Object . keys ( screens ) . some ( screen => {
545
- if ( parts . indexOf ( screen ) !== - 1 ) {
546
- code = `@media (min-width: ${
547
- screens [ screen ]
548
- } ) {\n${ code . replace ( / ^ / gm, ' ' ) } \n}`
549
- return true
590
+ let hoverStr = new vscode . MarkdownString ( )
591
+ let css = this . _tailwind . classNames [ base ]
592
+ let m = css . match ( / ^ ( : : ? [ a - z - ] + ) { ( .* ?) } / )
593
+ if ( m ) {
594
+ selector += m [ 1 ]
595
+ css = m [ 2 ] . trim ( )
550
596
}
551
- return false
552
- } )
553
- hoverStr . appendCodeblock ( code , 'css' )
554
-
555
- let hoverRange = new vscode . Range (
556
- new vscode . Position (
557
- position . line ,
558
- position . character +
559
- str . length -
560
- text1 . length -
561
- className . length
562
- ) ,
563
- new vscode . Position (
564
- position . line ,
565
- position . character + str . length - text1 . length
597
+ css = css . replace ( / ( [ ; { ] ) / g, '$1\n' ) . replace ( / ^ / gm, ' ' )
598
+ let code = `${ selector } {\n${ css } \n}`
599
+ let screens = dlv ( this . _tailwind . config , 'screens' , { } )
600
+
601
+ Object . keys ( screens ) . some ( screen => {
602
+ if ( parts . indexOf ( screen ) !== - 1 ) {
603
+ code = `@media (min-width: ${
604
+ screens [ screen ]
605
+ } ) {\n${ code . replace ( / ^ / gm, ' ' ) } \n}`
606
+ return true
607
+ }
608
+ return false
609
+ } )
610
+ hoverStr . appendCodeblock ( code , 'css' )
611
+
612
+ let hoverRange = new vscode . Range (
613
+ new vscode . Position (
614
+ position . line ,
615
+ position . character +
616
+ str . length -
617
+ text1 . length -
618
+ className . length
619
+ ) ,
620
+ new vscode . Position (
621
+ position . line ,
622
+ position . character + str . length - text1 . length
623
+ )
566
624
)
567
- )
568
625
569
- return new vscode . Hover ( hoverStr , hoverRange )
626
+ return new vscode . Hover ( hoverStr , hoverRange )
627
+ }
570
628
}
571
- }
572
629
573
- return null
630
+ return null
631
+ }
574
632
}
575
- } )
633
+ )
576
634
)
577
635
578
636
this . _disposable = vscode . Disposable . from ( ...this . _providers )
0 commit comments