@@ -8,10 +8,12 @@ import * as path from 'path';
88import * as nls from 'vscode-nls' ;
99const localize = nls . loadMessageBundle ( ) ;
1010
11- import { workspace , languages , ExtensionContext , extensions , Uri , LanguageConfiguration , TextDocument , FoldingRangeList as VSFoldingRangeList , FoldingRange as VSFoldingRange } from 'vscode' ;
12- import { LanguageClient , LanguageClientOptions , RequestType , ServerOptions , TransportKind , NotificationType , DidChangeConfigurationNotification , TextDocumentIdentifier } from 'vscode-languageclient' ;
11+ import { workspace , languages , ExtensionContext , extensions , Uri , LanguageConfiguration , TextDocument , FoldingRangeList , FoldingRange , Disposable } from 'vscode' ;
12+ import { LanguageClient , LanguageClientOptions , RequestType , ServerOptions , TransportKind , NotificationType , DidChangeConfigurationNotification } from 'vscode-languageclient' ;
1313import TelemetryReporter from 'vscode-extension-telemetry' ;
1414
15+ import { FoldingRangesRequest } from './protocol/foldingProvider.proposed' ;
16+
1517import { hash } from './utils/hash' ;
1618
1719namespace VSCodeContentRequest {
@@ -30,57 +32,6 @@ namespace SchemaAssociationNotification {
3032 export const type : NotificationType < ISchemaAssociations , any > = new NotificationType ( 'json/schemaAssociations' ) ;
3133}
3234
33- interface FoldingRangeList {
34- /**
35- * The folding ranges.
36- */
37- ranges : FoldingRange [ ] ;
38- }
39-
40- export enum FoldingRangeType {
41- /**
42- * Folding range for a comment
43- */
44- Comment = 'comment' ,
45- /**
46- * Folding range for a imports or includes
47- */
48- Imports = 'imports' ,
49- /**
50- * Folding range for a region (e.g. `#region`)
51- */
52- Region = 'region'
53- }
54-
55- interface FoldingRange {
56-
57- /**
58- * The start line number
59- */
60- startLine : number ;
61-
62- /**
63- * The end line number
64- */
65- endLine : number ;
66-
67- /**
68- * The actual color value for this color range.
69- */
70- type ?: FoldingRangeType ;
71- }
72-
73- interface FoldingRangeRequest {
74- /**
75- * The text document.
76- */
77- textDocument : TextDocumentIdentifier ;
78- }
79-
80- namespace FoldingRangesRequest {
81- export const type : RequestType < FoldingRangeRequest , FoldingRangeList | null , any , any > = new RequestType ( 'textDocument/foldingRanges' ) ;
82- }
83-
8435interface IPackageInfo {
8536 name : string ;
8637 version : string ;
@@ -106,6 +57,9 @@ interface JSONSchemaSettings {
10657
10758let telemetryReporter : TelemetryReporter | undefined ;
10859
60+ let foldingProviderRegistration : Disposable | undefined = void 0 ;
61+ const foldingSetting = 'json.experimental.syntaxFolding' ;
62+
10963export function activate ( context : ExtensionContext ) {
11064
11165 let toDispose = context . subscriptions ;
@@ -150,7 +104,7 @@ export function activate(context: ExtensionContext) {
150104 let disposable = client . start ( ) ;
151105 toDispose . push ( disposable ) ;
152106 client . onReady ( ) . then ( ( ) => {
153- client . onTelemetry ( e => {
107+ disposable = client . onTelemetry ( e => {
154108 if ( telemetryReporter ) {
155109 telemetryReporter . sendTelemetryEvent ( e . key , e . data ) ;
156110 }
@@ -176,16 +130,13 @@ export function activate(context: ExtensionContext) {
176130
177131 client . sendNotification ( SchemaAssociationNotification . type , getSchemaAssociation ( context ) ) ;
178132
179- languages . registerFoldingProvider ( documentSelector , {
180- provideFoldingRanges ( document : TextDocument ) {
181- return client . sendRequest ( FoldingRangesRequest . type , { textDocument : client . code2ProtocolConverter . asTextDocumentIdentifier ( document ) } ) . then ( res => {
182- if ( res && Array . isArray ( res . ranges ) ) {
183- return new VSFoldingRangeList ( res . ranges . map ( r => new VSFoldingRange ( r . startLine , r . endLine , r . type ) ) ) ;
184- }
185- return null ;
186- } ) ;
133+ initFoldingProvider ( ) ;
134+ toDispose . push ( workspace . onDidChangeConfiguration ( c => {
135+ if ( c . affectsConfiguration ( foldingSetting ) ) {
136+ initFoldingProvider ( ) ;
187137 }
188- } ) ;
138+ } ) ) ;
139+ toDispose . push ( { dispose : ( ) => foldingProviderRegistration && foldingProviderRegistration . dispose ( ) } ) ;
189140 } ) ;
190141
191142 let languageConfiguration : LanguageConfiguration = {
@@ -197,6 +148,29 @@ export function activate(context: ExtensionContext) {
197148 } ;
198149 languages . setLanguageConfiguration ( 'json' , languageConfiguration ) ;
199150 languages . setLanguageConfiguration ( 'jsonc' , languageConfiguration ) ;
151+
152+ function initFoldingProvider ( ) {
153+ let enable = workspace . getConfiguration ( ) . get ( foldingSetting ) ;
154+ if ( enable ) {
155+ if ( ! foldingProviderRegistration ) {
156+ foldingProviderRegistration = languages . registerFoldingProvider ( documentSelector , {
157+ provideFoldingRanges ( document : TextDocument ) {
158+ return client . sendRequest ( FoldingRangesRequest . type , { textDocument : client . code2ProtocolConverter . asTextDocumentIdentifier ( document ) } ) . then ( res => {
159+ if ( res && Array . isArray ( res . ranges ) ) {
160+ return new FoldingRangeList ( res . ranges . map ( r => new FoldingRange ( r . startLine , r . endLine , r . type ) ) ) ;
161+ }
162+ return null ;
163+ } ) ;
164+ }
165+ } ) ;
166+ }
167+ } else {
168+ if ( foldingProviderRegistration ) {
169+ foldingProviderRegistration . dispose ( ) ;
170+ foldingProviderRegistration = void 0 ;
171+ }
172+ }
173+ }
200174}
201175
202176export function deactivate ( ) : Promise < any > {
0 commit comments