@@ -6,6 +6,7 @@ const htmlElements = require('./htmlElements.js')
6
6
const tailwindClassNames = require ( 'tailwind-class-names' )
7
7
const dlv = require ( 'dlv' )
8
8
const Color = require ( 'color' )
9
+ const _lineColumn = require ( 'line-column' )
9
10
10
11
const CONFIG_GLOB =
11
12
'**/{tailwind,tailwind.config,tailwind-config,.tailwindrc}.js'
@@ -432,76 +433,67 @@ class TailwindIntellisense {
432
433
this . _providers = [ ]
433
434
434
435
this . _providers . push (
435
- vscode . commands . registerCommand (
436
- 'tailwind.refactor-class-names' ,
437
- ( document , range ) => {
438
- let original = document . getText ( range )
439
-
440
- let order = [
441
- 'hover' ,
442
- 'group-hover' ,
443
- 'active' ,
444
- 'focus' ,
445
- 'sm' ,
446
- 'md' ,
447
- 'lg' ,
448
- 'xl'
449
- ]
450
-
451
- let next = original
452
- . split ( / \s + / )
453
- . sort ( ( a , b ) => {
454
- let aPrefix = a . match ( / ^ ( [ ^ : ] + ) : / )
455
- let bPrefix = b . match ( / ^ ( [ ^ : ] + ) : / )
456
- if ( ! aPrefix && bPrefix ) return - 1
457
- if ( ! bPrefix && aPrefix ) return 1
458
- if ( ! aPrefix && ! bPrefix ) return 0
459
- // at this point they both have a prefix
460
- aPrefix = aPrefix [ 1 ]
461
- bPrefix = bPrefix [ 1 ]
462
-
463
- if ( aPrefix === bPrefix ) return 0
464
-
465
- if (
466
- order . indexOf ( aPrefix ) === - 1 &&
467
- order . indexOf ( bPrefix ) === - 1
468
- )
469
- return 0
470
- if (
471
- order . indexOf ( aPrefix ) !== - 1 &&
472
- order . indexOf ( bPrefix ) === - 1
473
- )
474
- return - 1
475
- if (
476
- order . indexOf ( bPrefix ) !== - 1 &&
477
- order . indexOf ( aPrefix ) === - 1
478
- )
479
- return 1
436
+ vscode . languages . registerDocumentRangeFormattingEditProvider ( HTML_TYPES , {
437
+ provideDocumentRangeFormattingEdits ( document , range ) {
438
+ if (
439
+ ! vscode . workspace . getConfiguration ( 'tailwind' ) . get ( 'format.enable' )
440
+ ) {
441
+ return [ ]
442
+ }
443
+
444
+ let searchStart = new vscode . Position (
445
+ Math . max ( range . start . line - 5 , 0 ) ,
446
+ 0
447
+ )
448
+ let searchEnd = new vscode . Position ( range . end . line + 5 , 0 )
449
+
450
+ let ranges = findClassListsInRange (
451
+ document ,
452
+ new vscode . Range ( searchStart , searchEnd )
453
+ )
480
454
481
- return order . indexOf ( aPrefix ) - order . indexOf ( bPrefix )
482
- } )
483
- . join ( ' ' )
455
+ if ( ! ranges . some ( r => r . contains ( range ) ) ) return [ ]
484
456
485
- let edit = new vscode . WorkspaceEdit ( )
486
- edit . replace ( document . uri , range , next )
487
- vscode . workspace . applyEdit ( edit )
457
+ return ranges . map (
458
+ range =>
459
+ new vscode . TextEdit (
460
+ range ,
461
+ groupClassList ( document . getText ( range ) , tailwind . config )
462
+ )
463
+ )
488
464
}
489
- )
465
+ } )
490
466
)
491
467
492
468
this . _providers . push (
493
- vscode . languages . registerCodeActionsProvider ( HTML_TYPES , {
494
- provideCodeActions ( document , range ) {
495
- let action = new vscode . CodeAction (
496
- 'Arrange class names' ,
497
- vscode . CodeActionKind . Refactor
498
- )
499
- action . command = {
500
- title : 'refactor-class-names' ,
501
- command : 'tailwind.refactor-class-names' ,
502
- arguments : [ document , range ]
469
+ vscode . languages . registerDocumentFormattingEditProvider ( HTML_TYPES , {
470
+ provideDocumentFormattingEdits ( document ) {
471
+ if (
472
+ ! vscode . workspace . getConfiguration ( 'tailwind' ) . get ( 'format.enable' )
473
+ ) {
474
+ return [ ]
503
475
}
504
- return [ action ]
476
+
477
+ let firstLine = document . lineAt ( 0 )
478
+ let lastLine = document . lineAt ( document . lineCount - 1 )
479
+
480
+ let ranges = findClassListsInRange (
481
+ document ,
482
+ new vscode . Range (
483
+ 0 ,
484
+ firstLine . range . start . character ,
485
+ document . lineCount - 1 ,
486
+ lastLine . range . end . character
487
+ )
488
+ )
489
+
490
+ return ranges . map (
491
+ range =>
492
+ new vscode . TextEdit (
493
+ range ,
494
+ groupClassList ( document . getText ( range ) , tailwind . config )
495
+ )
496
+ )
505
497
}
506
498
} )
507
499
)
@@ -863,3 +855,87 @@ function createScreenCompletionItemProvider({
863
855
' '
864
856
)
865
857
}
858
+
859
+ function findClassListsInRange (
860
+ document : vscode . TextDocument ,
861
+ range : vscode . Range
862
+ ) : vscode . Range [ ] {
863
+ let text : string = document . getText ( range )
864
+
865
+ let regex = / ( c l a s s ( N a m e ) ? = ( [ ' " ] ) ) ( [ a - z 0 - 9 - _ : | ! \s ] + ) \3/ gi
866
+ let match
867
+ let ranges = [ ]
868
+ while ( ( match = regex . exec ( text ) ) !== null ) {
869
+ let start = regex . lastIndex - match [ 0 ] . length + match [ 1 ] . length
870
+ let end = start + match [ 4 ] . length
871
+ start = lineColumn ( text , start )
872
+ end = lineColumn ( text , end )
873
+ ranges . push (
874
+ new vscode . Range (
875
+ new vscode . Position (
876
+ range . start . line + start . line ,
877
+ range . start . character + start . col
878
+ ) ,
879
+ new vscode . Position (
880
+ range . start . line + end . line ,
881
+ range . start . character + end . col
882
+ )
883
+ )
884
+ )
885
+ }
886
+ return ranges
887
+ }
888
+
889
+ function groupClassList ( str , twConfig ) {
890
+ let screens = [ ]
891
+
892
+ try {
893
+ screens = Object . keys ( dlv ( twConfig , 'screens' , { } ) )
894
+ } catch ( _ ) { }
895
+
896
+ let states = [ 'hover' , 'group-hover' , 'active' , 'focus' ]
897
+
898
+ let order = [
899
+ ...states ,
900
+ ...flatten (
901
+ screens . map ( screen => [
902
+ screen ,
903
+ ...states . map ( state => `${ screen } :${ state } ` )
904
+ ] )
905
+ )
906
+ ]
907
+
908
+ return str
909
+ . split ( / \s + / )
910
+ . sort ( ( a , b ) => {
911
+ let aPrefix = a . match ( / ^ ( .* ) : / )
912
+ let bPrefix = b . match ( / ^ ( .* ) : / )
913
+ if ( ! aPrefix && bPrefix ) return - 1
914
+ if ( ! bPrefix && aPrefix ) return 1
915
+ if ( ! aPrefix && ! bPrefix ) return 0
916
+ // at this point they both have a prefix
917
+ aPrefix = aPrefix [ 1 ]
918
+ bPrefix = bPrefix [ 1 ]
919
+
920
+ if ( aPrefix === bPrefix ) return 0
921
+
922
+ if ( order . indexOf ( aPrefix ) === - 1 && order . indexOf ( bPrefix ) === - 1 )
923
+ return 0
924
+ if ( order . indexOf ( aPrefix ) !== - 1 && order . indexOf ( bPrefix ) === - 1 )
925
+ return - 1
926
+ if ( order . indexOf ( bPrefix ) !== - 1 && order . indexOf ( aPrefix ) === - 1 )
927
+ return 1
928
+
929
+ return order . indexOf ( aPrefix ) - order . indexOf ( bPrefix )
930
+ } )
931
+ . join ( ' ' )
932
+ }
933
+
934
+ function flatten ( arr ) {
935
+ return arr . reduce ( ( acc , val ) => acc . concat ( val ) , [ ] )
936
+ }
937
+
938
+ function lineColumn ( str , index ) {
939
+ let { line, col } = _lineColumn ( str , index )
940
+ return { line : line - 1 , col : col - 1 }
941
+ }
0 commit comments