Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ MATLAB language server supports these editors by installing the corresponding ex

### Unreleased

Fixed:
* General bug fixes

### 1.2.1
Release date: 2024-04-04

Expand Down
33 changes: 33 additions & 0 deletions matlab/+matlabls/+handlers/FoldingSupportHandler.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
classdef (Hidden) FoldingSupportHandler < matlabls.handlers.FeatureHandler
% FOLDINGSUPPORTHANDLER The feature handler for retrieving a document's
% folding ranges.

% Copyright 2024 The MathWorks, Inc.


properties (Access = private)
RequestChannel = "/matlabls/foldDocument/request"
ResponseChannel = "/matlabls/foldDocument/response"
end

methods
function this = FoldingSupportHandler ()
this = this@matlabls.handlers.FeatureHandler();
this.RequestSubscriptions = matlabls.internal.CommunicationManager.subscribe(this.RequestChannel, @this.handleFoldingRangeRequest);
end
end

methods (Access = private)
function handleFoldingRangeRequest (this, msg)
% Handles folding range requests
codeToFold = msg.code;

fRangesArray = matlabls.internal.getFoldingRanges(codeToFold);
response.data = fRangesArray;

% Send folding ranges
responseChannel = strcat(this.ResponseChannel, '/', msg.channelId);
matlabls.internal.CommunicationManager.publish(responseChannel, response.data)
end
end
end
Binary file added matlab/+matlabls/+internal/getFoldingRanges.p
Binary file not shown.
1 change: 1 addition & 0 deletions matlab/+matlabls/MatlabLanguageServerHelper.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ function initializeFeatureHandlers (this)
this.FeatureHandlers(end + 1) = matlabls.handlers.IndexingHandler();
this.FeatureHandlers(end + 1) = matlabls.handlers.LintingSupportHandler();
this.FeatureHandlers(end + 1) = matlabls.handlers.NavigationSupportHandler();
this.FeatureHandlers(end + 1) = matlabls.handlers.FoldingSupportHandler();
end
end
end
82 changes: 82 additions & 0 deletions src/providers/folding/FoldingSupportProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2024 The MathWorks, Inc.

import { FoldingRangeParams, TextDocuments, FoldingRange} from 'vscode-languageserver'
import { TextDocument } from 'vscode-languageserver-textdocument'
import { URI } from 'vscode-uri'
import MatlabLifecycleManager from '../../lifecycle/MatlabLifecycleManager'
import { MatlabConnection } from '../../lifecycle/MatlabCommunicationManager'


class FoldingSupportProvider {
private readonly REQUEST_CHANNEL = '/matlabls/foldDocument/request'
private readonly RESPONSE_CHANNEL = '/matlabls/foldDocument/response'

async handleFoldingRangeRequest (params: FoldingRangeParams, documentManager: TextDocuments<TextDocument>): Promise<FoldingRange[] | null> {
const docToFold = documentManager.get(params.textDocument.uri)
if (docToFold == null) {
return null
}

const matlabConnection = await MatlabLifecycleManager.getMatlabConnection()
const isMatlabAvailable = (matlabConnection != null)
const matlabRelease = MatlabLifecycleManager.getMatlabRelease()

// check for connection and release
if (!isMatlabAvailable || (matlabRelease == null) || (matlabRelease < 'R2024b')) {
return null
}

const fileName = URI.parse(docToFold.uri).fsPath
const code = docToFold.getText()

const frArray = await this.getFoldingRangesFromMatlab(code, fileName, matlabConnection)

const foldingRanges = this.processFoldingRanges(frArray)

return foldingRanges;
}

/**
* Gets folding ranges from MATLAB.
*
* @param code The code in the file
* @param fileName The file's name
* @param matlabConnection The connection to MATLAB
* @returns An array of line numbers
*/
private async getFoldingRangesFromMatlab (code: string, fileName: string, matlabConnection: MatlabConnection): Promise<number[]> {
return await new Promise<number[]>(resolve => {
const channelId = matlabConnection.getChannelId()
const channel = `${this.RESPONSE_CHANNEL}/${channelId}`
const responseSub = matlabConnection.subscribe(channel, message => {
matlabConnection.unsubscribe(responseSub)
resolve(message as number[])
})

matlabConnection.publish(this.REQUEST_CHANNEL, {
code,
fileName,
channelId
})
})
}

/**
* Processes folding range data from MATLAB.
*
* @param frArray An array of line numbers from MATLAB
* @returns An array of FoldingRanges
*/
private processFoldingRanges (frArray: number[]): FoldingRange[] {
let fRangeArray: FoldingRange[] = []

for(let i = 0; i < frArray.length; i = i+2) {
let fRange = FoldingRange.create(frArray[i] - 1, frArray[i+1] - 1)
fRangeArray.push(fRange)
}

return fRangeArray
}
}

export default new FoldingSupportProvider()
11 changes: 11 additions & 0 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import ExecuteCommandProvider, { MatlabLSCommands } from './providers/lspCommand
import NavigationSupportProvider, { RequestType } from './providers/navigation/NavigationSupportProvider'
import LifecycleNotificationHelper from './lifecycle/LifecycleNotificationHelper'
import MVM from './mvm/MVM'
import FoldingSupportProvider from './providers/folding/FoldingSupportProvider'
import { FoldingRange } from 'vscode-languageserver'

// Create a connection for the server
export const connection = createConnection(ProposedFeatures.all)
Expand Down Expand Up @@ -68,6 +70,7 @@ connection.onInitialize((params: InitializeParams) => {
executeCommandProvider: {
commands: Object.values(MatlabLSCommands)
},
foldingRangeProvider: true,
referencesProvider: true,
signatureHelpProvider: {
triggerCharacters: ['(', ',']
Expand Down Expand Up @@ -178,6 +181,14 @@ connection.onSignatureHelp(async params => {
return await CompletionProvider.handleSignatureHelpRequest(params, documentManager)
})

/** -------------------- FOLDING SUPPORT -------------------- **/
connection.onFoldingRanges(async params => {
// Retrieve the folding ranges
// If there are valid folding ranges, hand them back to the IDE
// Else, return null, so the IDE falls back to indent-based folding
return await FoldingSupportProvider.handleFoldingRangeRequest(params, documentManager)
})

/** -------------------- FORMATTING SUPPORT -------------------- **/
connection.onDocumentFormatting(async params => {
// Gather a set of document edits required for formatting, which the IDE will execute
Expand Down