@@ -23,51 +23,65 @@ export function activate(context: vscode.ExtensionContext) {
2323
2424 // Register a folding range provider for jxml
2525 context . subscriptions . push (
26- vscode . languages . registerFoldingRangeProvider ( 'jxml' , {
27- provideFoldingRanges ( document , context , token ) {
28- console . log ( 'Folding provider called for' , document . fileName ) ;
29- const foldingRanges : vscode . FoldingRange [ ] = [ ] ;
30- const startRegex = / < \? ( j x m l ) ? / ;
31- const endRegex = / \? > / ;
32- let startLine : number | null = null ;
33- let inScript = false ;
34- // Track JS block folding inside <? ... ?>
35- let jsBlockStack : number [ ] = [ ] ;
36- for ( let i = 0 ; i < document . lineCount ; i ++ ) {
37- const line = document . lineAt ( i ) . text ;
38- if ( ! inScript && startRegex . test ( line ) ) {
39- startLine = i ;
40- inScript = true ;
41- continue ;
42- }
43- if ( inScript && endRegex . test ( line ) ) {
44- if ( startLine !== null ) {
45- foldingRanges . push ( new vscode . FoldingRange ( startLine , i ) ) ;
46- console . log ( `Folding range: ${ startLine } to ${ i } ` ) ;
47- }
48- startLine = null ;
49- inScript = false ;
50- jsBlockStack = [ ] ;
51- continue ;
52- }
53- if ( inScript ) {
54- // Custom JS block folding for { ... }
55- if ( line . includes ( '{' ) ) {
56- jsBlockStack . push ( i ) ;
57- }
58- if ( line . includes ( '}' ) ) {
59- const blockStart = jsBlockStack . pop ( ) ;
60- if ( blockStart !== undefined && blockStart < i ) {
61- foldingRanges . push ( new vscode . FoldingRange ( blockStart , i ) ) ;
62- console . log ( `JS block folding: ${ blockStart } to ${ i } ` ) ;
63- }
64- }
65- }
66- }
67- return foldingRanges ;
68- }
69- } )
70- ) ;
26+ vscode . languages . registerFoldingRangeProvider ( 'jxml' , {
27+ async provideFoldingRanges ( document , token ) {
28+ // Create a virtual document to get HTML folding ranges
29+ const virtualDoc = await vscode . workspace . openTextDocument ( {
30+ language : 'html' ,
31+ content : document . getText ( )
32+ } ) ;
33+ const htmlRanges = await vscode . commands . executeCommand < vscode . FoldingRange [ ] > (
34+ 'vscode.executeFoldingRangeProvider' ,
35+ virtualDoc . uri
36+ ) || [ ] ;
37+
38+ // --- Custom JXML and JavaScript folding logic ---
39+ const jxmlAndJsRanges : vscode . FoldingRange [ ] = [ ] ;
40+ const text = document . getText ( ) ;
41+ const startRegex = / < \? ( j x m l ) ? / g;
42+ const endRegex = / \? > / g;
43+ let startMatch ;
44+
45+ while ( ( startMatch = startRegex . exec ( text ) ) !== null ) {
46+ endRegex . lastIndex = startMatch . index + startMatch [ 0 ] . length ;
47+ const endMatch = endRegex . exec ( text ) ;
48+ if ( endMatch ) {
49+ const startPos = document . positionAt ( startMatch . index ) ;
50+ const endPos = document . positionAt ( endMatch . index + endMatch [ 0 ] . length ) ;
51+
52+ // 1. Fold the entire <? ... ?> block
53+ if ( startPos . line < endPos . line ) {
54+ jxmlAndJsRanges . push ( new vscode . FoldingRange ( startPos . line , endPos . line , vscode . FoldingRangeKind . Region ) ) ;
55+ }
56+
57+ // 2. Find and fold {...} blocks within the JXML block
58+ const blockContentStartIndex = startMatch . index + startMatch [ 0 ] . length ;
59+ const blockContentEndIndex = endMatch . index ;
60+ const openBraceStack : number [ ] = [ ] ;
61+
62+ for ( let i = blockContentStartIndex ; i < blockContentEndIndex ; i ++ ) {
63+ if ( text [ i ] === '{' ) {
64+ openBraceStack . push ( i ) ;
65+ } else if ( text [ i ] === '}' && openBraceStack . length > 0 ) {
66+ const openBraceIndex = openBraceStack . pop ( ) ;
67+ if ( openBraceIndex ) {
68+ const jsStartPos = document . positionAt ( openBraceIndex ) ;
69+ const jsEndPos = document . positionAt ( i ) ;
70+ if ( jsStartPos . line < jsEndPos . line ) {
71+ jxmlAndJsRanges . push ( new vscode . FoldingRange ( jsStartPos . line , jsEndPos . line ) ) ;
72+ }
73+ }
74+ }
75+ }
76+ startRegex . lastIndex = endMatch . index + endMatch [ 0 ] . length ;
77+ }
78+ }
79+
80+ // Combine all the folding ranges
81+ return [ ...htmlRanges , ...jxmlAndJsRanges ] ;
82+ }
83+ } )
84+ ) ;
7185}
7286
7387// This method is called when your extension is deactivated
0 commit comments