7
7
import * as path from 'path' ;
8
8
9
9
import {
10
- workspace as Workspace , window as Window , languages as Languages , Uri , TextDocument , CodeActionContext , Diagnostic , ProviderResult ,
10
+ workspace as Workspace , window as Window , languages as Languages , Uri , TextDocument , CodeActionContext , Diagnostic ,
11
11
Command , CodeAction , MessageItem , ConfigurationTarget , env as Env , CodeActionKind , WorkspaceConfiguration , NotebookCell , commands ,
12
12
ExtensionContext , LanguageStatusItem , LanguageStatusSeverity , DocumentFilter as VDocumentFilter
13
13
} from 'vscode' ;
@@ -151,7 +151,11 @@ export namespace ESLintClient {
151
151
languageStatus . name = 'ESLint' ;
152
152
languageStatus . text = 'ESLint' ;
153
153
languageStatus . command = { title : 'Open ESLint Output' , command : 'eslint.showOutputChannel' } ;
154
- const documentStatus : Map < string , Status > = new Map ( ) ;
154
+ type StatusInfo = Omit < StatusParams , 'uri' > & {
155
+ firstReport : boolean ;
156
+ fixTime ?: number ;
157
+ } ;
158
+ const documentStatus : Map < string , StatusInfo > = new Map ( ) ;
155
159
156
160
// If the workspace configuration changes we need to update the synced documents since the
157
161
// list of probe language type can change.
@@ -492,7 +496,7 @@ export namespace ESLintClient {
492
496
return next ( document , cells ) ;
493
497
}
494
498
} ,
495
- provideCodeActions : ( document , range , context , token , next ) : ProviderResult < ( Command | CodeAction ) [ ] > => {
499
+ provideCodeActions : async ( document , range , context , token , next ) : Promise < ( Command | CodeAction ) [ ] | null | undefined > => {
496
500
if ( ! syncedDocuments . has ( document . uri . toString ( ) ) ) {
497
501
return [ ] ;
498
502
}
@@ -512,7 +516,20 @@ export namespace ESLintClient {
512
516
return [ ] ;
513
517
}
514
518
const newContext : CodeActionContext = Object . assign ( { } , context , { diagnostics : eslintDiagnostics } ) ;
515
- return next ( document , range , newContext , token ) ;
519
+ const start = Date . now ( ) ;
520
+ const result = await next ( document , range , newContext , token ) ;
521
+ if ( context . only ?. value . startsWith ( 'source.fixAll' ) ) {
522
+ const statusInfo = documentStatus . get ( document . uri . toString ( ) ) ;
523
+ if ( statusInfo !== undefined ) {
524
+ if ( statusInfo . firstReport === true ) {
525
+ statusInfo . firstReport = false ;
526
+ statusInfo . validationTime = 0 ;
527
+ }
528
+ statusInfo . fixTime = Date . now ( ) - start ;
529
+ updateStatusBar ( document . uri . toString ( ) ) ;
530
+ }
531
+ }
532
+ return result ;
516
533
} ,
517
534
workspace : {
518
535
didChangeWatchedFile : ( event , next ) => {
@@ -769,9 +786,9 @@ export namespace ESLintClient {
769
786
}
770
787
771
788
function updateDocumentStatus ( params : StatusParams ) : void {
772
- const needsUpdate = ! documentStatus . has ( params . uri ) ;
773
- documentStatus . set ( params . uri , params . state ) ;
774
- if ( needsUpdate ) {
789
+ const hasStatus = documentStatus . has ( params . uri ) ;
790
+ documentStatus . set ( params . uri , Object . assign ( { } , params , { firstReport : ! hasStatus } ) ) ;
791
+ if ( ! hasStatus ) {
775
792
updateLanguageStatusSelector ( ) ;
776
793
}
777
794
updateStatusBar ( params . uri ) ;
@@ -793,18 +810,21 @@ export namespace ESLintClient {
793
810
}
794
811
795
812
function updateStatusBar ( uri : string | undefined ) {
796
- const status = function ( ) {
813
+ const statusInfo = function ( ) : StatusInfo {
797
814
if ( serverRunning === false ) {
798
- return Status . error ;
815
+ return { state : Status . error , firstReport : true } ;
799
816
}
800
817
if ( uri === undefined ) {
801
818
uri = Window . activeTextEditor ?. document . uri . toString ( ) ;
802
819
}
803
- return ( uri !== undefined ? documentStatus . get ( uri ) : undefined ) ?? Status . ok ;
820
+ const params = uri !== undefined ? documentStatus . get ( uri ) : undefined ;
821
+ return params ?? { state : Status . ok , firstReport : true } ;
804
822
} ( ) ;
805
- let text : string = 'ESLint' ;
823
+
824
+ const timeTaken = statusInfo . firstReport ? - 1 : Math . max ( statusInfo . validationTime ?? - 1 , statusInfo . fixTime ?? - 1 ) ;
825
+ const text : string = timeTaken > 250 ? `ESLint [${ timeTaken } ms]` : 'ESLint' ;
806
826
let severity : LanguageStatusSeverity = LanguageStatusSeverity . Information ;
807
- switch ( status ) {
827
+ switch ( statusInfo . state ) {
808
828
case Status . ok :
809
829
break ;
810
830
case Status . warn :
@@ -814,6 +834,23 @@ export namespace ESLintClient {
814
834
severity = LanguageStatusSeverity . Error ;
815
835
break ;
816
836
}
837
+ if ( severity === LanguageStatusSeverity . Information && timeTaken > 250 ) {
838
+ severity = LanguageStatusSeverity . Warning ;
839
+ }
840
+ if ( severity === LanguageStatusSeverity . Warning && timeTaken > 750 ) {
841
+ severity = LanguageStatusSeverity . Error ;
842
+ }
843
+ if ( timeTaken > 250 ) {
844
+ const message = ( statusInfo . validationTime ?? 0 ) > ( statusInfo . fixTime ?? 0 )
845
+ ? `Linting file ${ uri } took ${ timeTaken } ms`
846
+ : `Computing fixes for file ${ uri } during save took ${ timeTaken } ms` ;
847
+ if ( timeTaken > 750 ) {
848
+ client . error ( message ) ;
849
+ } else {
850
+ client . warn ( message ) ;
851
+ }
852
+ }
853
+
817
854
languageStatus . text = text ;
818
855
languageStatus . severity = severity ;
819
856
}
0 commit comments