@@ -537,9 +537,59 @@ export function createNullClient(): Client {
537537return new NullClient ( ) ;
538538}
539539
540+ class FoldingRangeProvider implements vscode . FoldingRangeProvider {
541+ private client :DefaultClient ;
542+ constructor ( client :DefaultClient ) {
543+ this . client = client ;
544+ }
545+ provideFoldingRanges ( document :vscode . TextDocument , context :vscode . FoldingContext ,
546+ token :vscode . CancellationToken ) :Promise < vscode . FoldingRange [ ] > {
547+ let id :number = ++ abortRequestId ;
548+ let params :GetFoldingRangesParams = {
549+ id :id ,
550+ uri :document . uri . toString ( )
551+ } ;
552+ return new Promise < vscode . FoldingRange [ ] > ( ( resolve , reject ) => {
553+ this . client . notifyWhenReady ( ( ) => {
554+ this . client . languageClient . sendRequest ( GetFoldingRangesRequest , params )
555+ . then ( ( ranges ) => {
556+ if ( ranges . canceled ) {
557+ reject ( ) ;
558+ } else {
559+ let result :vscode . FoldingRange [ ] = [ ] ;
560+ ranges . ranges . forEach ( ( r ) => {
561+ let foldingRange :vscode . FoldingRange = {
562+ start :r . range . start . line ,
563+ end :r . range . end . line
564+ } ;
565+ switch ( r . kind ) {
566+ case FoldingRangeKind . Comment :
567+ foldingRange . kind = vscode . FoldingRangeKind . Comment ;
568+ break ;
569+ case FoldingRangeKind . Imports :
570+ foldingRange . kind = vscode . FoldingRangeKind . Imports ;
571+ break ;
572+ case FoldingRangeKind . Region :
573+ foldingRange . kind = vscode . FoldingRangeKind . Region ;
574+ break ;
575+ default :
576+ break ;
577+ }
578+ result . push ( foldingRange ) ;
579+ } ) ;
580+ resolve ( result ) ;
581+ }
582+ } ) ;
583+ token . onCancellationRequested ( e => this . client . abortRequest ( id ) ) ;
584+ } ) ;
585+ } ) ;
586+ }
587+ }
588+
540589export class DefaultClient implements Client {
541590private innerLanguageClient ?:LanguageClient ; // The "client" that launches and communicates with our language "server" process.
542591private disposables :vscode . Disposable [ ] = [ ] ;
592+ private codeFoldingProviderDisposable :vscode . Disposable | undefined ;
543593private innerConfiguration ?:configs . CppProperties ;
544594private rootPathFileWatcher ?:vscode . FileSystemWatcher ;
545595private rootFolder ?:vscode . WorkspaceFolder ;
@@ -551,6 +601,10 @@ export class DefaultClient implements Client {
551601private visibleRanges = new Map < string , Range [ ] > ( ) ;
552602private settingsTracker :SettingsTracker ;
553603private configurationProvider ?:string ;
604+ private documentSelector :DocumentFilter [ ] = [
605+ { scheme :'file' , language :'cpp' } ,
606+ { scheme :'file' , language :'c' }
607+ ] ;
554608
555609// The "model" that is displayed via the UI (status bar).
556610private model :ClientModel = new ClientModel ( ) ;
@@ -586,7 +640,7 @@ export class DefaultClient implements Client {
586640return this . model . referencesCommandMode . Value ;
587641}
588642
589- private get languageClient ( ) :LanguageClient {
643+ public get languageClient ( ) :LanguageClient {
590644if ( ! this . innerLanguageClient ) {
591645throw new Error ( "Attempting to use languageClient before initialized" ) ;
592646}
@@ -665,11 +719,6 @@ export class DefaultClient implements Client {
665719telemetry . logLanguageServerEvent ( "NonDefaultInitialCppSettings" , this . settingsTracker . getUserModifiedSettings ( ) ) ;
666720failureMessageShown = false ;
667721
668- let documentSelector :DocumentFilter [ ] = [
669- { scheme :'file' , language :'cpp' } ,
670- { scheme :'file' , language :'c' }
671- ] ;
672-
673722class CodeActionProvider implements vscode . CodeActionProvider {
674723private client :DefaultClient ;
675724constructor ( client :DefaultClient ) {
@@ -994,55 +1043,6 @@ export class DefaultClient implements Client {
9941043}
9951044}
9961045
997- class FoldingRangeProvider implements vscode . FoldingRangeProvider {
998- private client :DefaultClient ;
999- constructor ( client :DefaultClient ) {
1000- this . client = client ;
1001- }
1002- provideFoldingRanges ( document :vscode . TextDocument , context :vscode . FoldingContext ,
1003- token :vscode . CancellationToken ) :Promise < vscode . FoldingRange [ ] > {
1004- let id :number = ++ abortRequestId ;
1005- let params :GetFoldingRangesParams = {
1006- id :id ,
1007- uri :document . uri . toString ( )
1008- } ;
1009- return new Promise < vscode . FoldingRange [ ] > ( ( resolve , reject ) => {
1010- this . client . notifyWhenReady ( ( ) => {
1011- this . client . languageClient . sendRequest ( GetFoldingRangesRequest , params )
1012- . then ( ( ranges ) => {
1013- if ( ranges . canceled ) {
1014- reject ( ) ;
1015- } else {
1016- let result :vscode . FoldingRange [ ] = [ ] ;
1017- ranges . ranges . forEach ( ( r ) => {
1018- let foldingRange :vscode . FoldingRange = {
1019- start :r . range . start . line ,
1020- end :r . range . end . line
1021- } ;
1022- switch ( r . kind ) {
1023- case FoldingRangeKind . Comment :
1024- foldingRange . kind = vscode . FoldingRangeKind . Comment ;
1025- break ;
1026- case FoldingRangeKind . Imports :
1027- foldingRange . kind = vscode . FoldingRangeKind . Imports ;
1028- break ;
1029- case FoldingRangeKind . Region :
1030- foldingRange . kind = vscode . FoldingRangeKind . Region ;
1031- break ;
1032- default :
1033- break ;
1034- }
1035- result . push ( foldingRange ) ;
1036- } ) ;
1037- resolve ( result ) ;
1038- }
1039- } ) ;
1040- token . onCancellationRequested ( e => this . client . abortRequest ( id ) ) ;
1041- } ) ;
1042- } ) ;
1043- }
1044- }
1045-
10461046if ( firstClient ) {
10471047workspaceReferences = new refs . ReferencesManager ( this ) ;
10481048
@@ -1058,12 +1058,15 @@ export class DefaultClient implements Client {
10581058
10591059this . registerFileWatcher ( ) ;
10601060
1061- this . disposables . push ( vscode . languages . registerRenameProvider ( documentSelector , new RenameProvider ( this ) ) ) ;
1062- this . disposables . push ( vscode . languages . registerReferenceProvider ( documentSelector , new FindAllReferencesProvider ( this ) ) ) ;
1061+ this . disposables . push ( vscode . languages . registerRenameProvider ( this . documentSelector , new RenameProvider ( this ) ) ) ;
1062+ this . disposables . push ( vscode . languages . registerReferenceProvider ( this . documentSelector , new FindAllReferencesProvider ( this ) ) ) ;
10631063this . disposables . push ( vscode . languages . registerWorkspaceSymbolProvider ( new WorkspaceSymbolProvider ( this ) ) ) ;
1064- this . disposables . push ( vscode . languages . registerDocumentSymbolProvider ( documentSelector , new DocumentSymbolProvider ( this ) , undefined ) ) ;
1065- this . disposables . push ( vscode . languages . registerCodeActionsProvider ( documentSelector , new CodeActionProvider ( this ) , undefined ) ) ;
1066- this . disposables . push ( vscode . languages . registerFoldingRangeProvider ( documentSelector , new FoldingRangeProvider ( this ) ) ) ;
1064+ this . disposables . push ( vscode . languages . registerDocumentSymbolProvider ( this . documentSelector , new DocumentSymbolProvider ( this ) , undefined ) ) ;
1065+ this . disposables . push ( vscode . languages . registerCodeActionsProvider ( this . documentSelector , new CodeActionProvider ( this ) , undefined ) ) ;
1066+ let settings :CppSettings = new CppSettings ( ) ;
1067+ if ( settings . codeFolding ) {
1068+ this . codeFoldingProviderDisposable = vscode . languages . registerFoldingRangeProvider ( this . documentSelector , new FoldingRangeProvider ( this ) ) ;
1069+ }
10671070
10681071// Listen for messages from the language server.
10691072this . registerNotifications ( ) ;
@@ -1350,6 +1353,15 @@ export class DefaultClient implements Client {
13501353if ( changedSettings [ "commentContinuationPatterns" ] ) {
13511354updateLanguageConfigurations ( ) ;
13521355}
1356+ if ( changedSettings [ "codeFolding" ] ) {
1357+ let settings :CppSettings = new CppSettings ( ) ;
1358+ if ( settings . codeFolding ) {
1359+ this . codeFoldingProviderDisposable = vscode . languages . registerFoldingRangeProvider ( this . documentSelector , new FoldingRangeProvider ( this ) ) ;
1360+ } else if ( this . codeFoldingProviderDisposable ) {
1361+ this . codeFoldingProviderDisposable . dispose ( ) ;
1362+ this . codeFoldingProviderDisposable = undefined ;
1363+ }
1364+ }
13531365this . configuration . onDidChangeSettings ( ) ;
13541366telemetry . logLanguageServerEvent ( "CppSettingsChange" , changedSettings , undefined ) ;
13551367}
@@ -2540,6 +2552,10 @@ export class DefaultClient implements Client {
25402552return promise . then ( ( ) => {
25412553this . disposables . forEach ( ( d ) => d . dispose ( ) ) ;
25422554this . disposables = [ ] ;
2555+ if ( this . codeFoldingProviderDisposable ) {
2556+ this . codeFoldingProviderDisposable . dispose ( ) ;
2557+ this . codeFoldingProviderDisposable = undefined ;
2558+ }
25432559this . model . dispose ( ) ;
25442560} ) ;
25452561}
@@ -2594,7 +2610,7 @@ export class DefaultClient implements Client {
25942610this . model . referencesCommandMode . Value = mode ;
25952611}
25962612
2597- private abortRequest ( id :number ) :void {
2613+ public abortRequest ( id :number ) :void {
25982614let params :AbortRequestParams = {
25992615id :id
26002616} ;