1
+ // Copyright 2024 The MathWorks, Inc.
2
+
3
+ import { FoldingRangeParams , TextDocuments , FoldingRange } from 'vscode-languageserver'
4
+ import { TextDocument } from 'vscode-languageserver-textdocument'
5
+ import { URI } from 'vscode-uri'
6
+ import MatlabLifecycleManager from '../../lifecycle/MatlabLifecycleManager'
7
+ import { MatlabConnection } from '../../lifecycle/MatlabCommunicationManager'
8
+
9
+
10
+ class FoldingSupportProvider {
11
+ private readonly REQUEST_CHANNEL = '/matlabls/foldDocument/request'
12
+ private readonly RESPONSE_CHANNEL = '/matlabls/foldDocument/response'
13
+
14
+ async handleFoldingRangeRequest ( params : FoldingRangeParams , documentManager : TextDocuments < TextDocument > ) : Promise < FoldingRange [ ] | null > {
15
+ const docToFold = documentManager . get ( params . textDocument . uri )
16
+ if ( docToFold == null ) {
17
+ return null
18
+ }
19
+
20
+ const matlabConnection = await MatlabLifecycleManager . getMatlabConnection ( )
21
+ const isMatlabAvailable = ( matlabConnection != null )
22
+ const matlabRelease = MatlabLifecycleManager . getMatlabRelease ( )
23
+
24
+ // check for connection and release
25
+ if ( ! isMatlabAvailable || ( matlabRelease == null ) || ( matlabRelease < 'R2024b' ) ) {
26
+ return null
27
+ }
28
+
29
+ const fileName = URI . parse ( docToFold . uri ) . fsPath
30
+ const code = docToFold . getText ( )
31
+
32
+ const frArray = await this . getFoldingRangesFromMatlab ( code , fileName , matlabConnection )
33
+
34
+ const foldingRanges = this . processFoldingRanges ( frArray )
35
+
36
+ return foldingRanges ;
37
+ }
38
+
39
+ /**
40
+ * Gets folding ranges from MATLAB.
41
+ *
42
+ * @param code The code in the file
43
+ * @param fileName The file's name
44
+ * @param matlabConnection The connection to MATLAB
45
+ * @returns An array of line numbers
46
+ */
47
+ private async getFoldingRangesFromMatlab ( code : string , fileName : string , matlabConnection : MatlabConnection ) : Promise < number [ ] > {
48
+ return await new Promise < number [ ] > ( resolve => {
49
+ const channelId = matlabConnection . getChannelId ( )
50
+ const channel = `${ this . RESPONSE_CHANNEL } /${ channelId } `
51
+ const responseSub = matlabConnection . subscribe ( channel , message => {
52
+ matlabConnection . unsubscribe ( responseSub )
53
+ resolve ( message as number [ ] )
54
+ } )
55
+
56
+ matlabConnection . publish ( this . REQUEST_CHANNEL , {
57
+ code,
58
+ fileName,
59
+ channelId
60
+ } )
61
+ } )
62
+ }
63
+
64
+ /**
65
+ * Processes folding range data from MATLAB.
66
+ *
67
+ * @param frArray An array of line numbers from MATLAB
68
+ * @returns An array of FoldingRanges
69
+ */
70
+ private processFoldingRanges ( frArray : number [ ] ) : FoldingRange [ ] {
71
+ let fRangeArray : FoldingRange [ ] = [ ]
72
+
73
+ for ( let i = 0 ; i < frArray . length ; i = i + 2 ) {
74
+ let fRange = FoldingRange . create ( frArray [ i ] - 1 , frArray [ i + 1 ] - 1 )
75
+ fRangeArray . push ( fRange )
76
+ }
77
+
78
+ return fRangeArray
79
+ }
80
+ }
81
+
82
+ export default new FoldingSupportProvider ( )
0 commit comments