Skip to content

MATLAB language server - v1.3.2 #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 6, 2025
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
24 changes: 24 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"version": "0.2.0",
"configurations": [
{
"args": [
"-u",
"bdd",
"--timeout",
"999999",
"--colors",
"${workspaceFolder}/tests/**/*.test.ts",
],
"internalConsoleOptions": "openOnSessionStart",
"name": "Mocha Tests",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
}

]
}
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ MATLAB language server supports these editors by installing the corresponding ex

### Unreleased

### 1.3.2
Release date: 2025-03-06

Fixed:
* Resolves errors with adding workspace folders to the MATLAB path on macOS and Linux systems

### 1.3.1
Release date: 2025-01-23

Expand Down
21 changes: 21 additions & 0 deletions matlab/+matlabls/+handlers/+completions/getCompletions.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function completionsData = getCompletions(code, fileName, cursorPosition)
% GETCOMPLETIONS Retrieves the data for the possible completions at the cursor position in the given code.

% Copyright 2025 The MathWorks, Inc.

completionResultsStr = matlabls.internal.getCompletionsData(code, fileName, cursorPosition);
completionsData = filterCompletionResults(completionResultsStr);
end

function compResultsStruct = filterCompletionResults (completionResultsStr)
completionResults = jsondecode(completionResultsStr);

compResultsStruct = struct;
propsToKeep = ["widgetData", "widgetType", "signatures"];

for prop = propsToKeep
if isfield(completionResults, prop)
compResultsStruct.(prop) = completionResults.(prop);
end
end
end
7 changes: 7 additions & 0 deletions matlab/+matlabls/+handlers/+folding/getFoldingRanges.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function foldingRanges = getFoldingRanges(code)
% GETFOLDINGRANGES Retrieves the code folding ranges for the given code.

% Copyright 2025 The MathWorks, Inc.

foldingRanges = matlabls.internal.getFoldingRanges(code);
end
30 changes: 30 additions & 0 deletions matlab/+matlabls/+handlers/+formatting/formatCode.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
function formattedCode = formatCode (codeToFormat, options)
% FORMATCODE Formats the given MATLAB code according to the specified options.

% Copyright 2025 The MathWorks, Inc.

s = settings;

% Update settings (temporarily) for formatting
cleanupObj1 = setTemporaryValue(s.matlab.editor.tab.InsertSpaces, options.insertSpaces); %#ok<NASGU>
cleanupObj2 = setTemporaryValue(s.matlab.editor.tab.TabSize, options.tabSize); %#ok<NASGU>
cleanupObj3 = setTemporaryValue(s.matlab.editor.tab.IndentSize, options.tabSize); %#ok<NASGU>

% Format code
formattedCode = indentcode(codeToFormat);
end

function cleanupObj = setTemporaryValue (setting, tempValue)
if setting.hasTemporaryValue
originalValue = setting.TemporaryValue;
cleanupObj = onCleanup(@() setTempValue(setting, originalValue));
else
cleanupObj = onCleanup(@() setting.clearTemporaryValue);
end

setTempValue(setting, tempValue);

function setTempValue (setting, tempValue)
setting.TemporaryValue = tempValue;
end
end
8 changes: 8 additions & 0 deletions matlab/+matlabls/+handlers/+indexing/parseInfoFromDocument.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function codeData = parseInfoFromDocument (code, filePath, analysisLimit)
% PARSEINFOFROMDOCUMENT Parses the given MATLAB code and extracts information about
% variables, functions, etc.

% Copyright 2025 The MathWorks, Inc.

codeData = matlabls.internal.computeCodeData(code, filePath, analysisLimit);
end
58 changes: 58 additions & 0 deletions matlab/+matlabls/+handlers/+indexing/parseInfoFromFolder.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
function parseInfoFromFolder (folders, analysisLimit, responseChannel)
% PARSEINFOFROMFOLDER Parses the MATLAB files in the provided folders and extracts
% information about variables, functions, etc.
%
% Instead of returning the parsed results, this function will stream those results
% over the response channel. This allows for these files to be processed without
% blocking the MATLAB thread for the full duration.

% Copyright 2025 The MathWorks, Inc.

filesToParse = getAllMFilesToParse(folders);
parfeval(backgroundPool, @doParseFiles, 0, filesToParse, analysisLimit, responseChannel);
end

function filesToParse = getAllMFilesToParse (folders)
% Gathers a list of all M files within the given folders

filesToParse = [];

for n = 1:numel(folders)
fileListing = dir([folders{n} '/**/*.m']);
fileNames = strings(numel(fileListing), 1);
for m = 1:numel(fileListing)
fileNames(m) = fullfile(fileListing(m).folder, fileListing(m).name);
end
filesToParse = [filesToParse; fileNames]; %#ok<AGROW>
end
end

function doParseFiles (filesToParse, analysisLimit, responseChannel)
% Processes the given list of files.
%
% This can be executed in a separate thread (e.g. parfeval) to avoid blocking
% the MATLAB thread.

for n = 1:numel(filesToParse)
filePath = filesToParse{n};
isLastFile = (n == numel(filesToParse));
parseFile(filePath, isLastFile, analysisLimit, responseChannel);
end
end

function parseFile (filePath, isLastFile, analysisLimit, responseChannel)
% Parses an individual file and publishes the results over the response channel.
%
% If the file to be parsed is the last file, an `isDone` flag on the results is
% set to true to indicate that the parsing process has completed.

code = fileread(filePath);
codeData = matlabls.handlers.indexing.parseInfoFromDocument(code, filePath, analysisLimit);

% Send data for this file
msg.filePath = filePath;
msg.codeData = codeData;
msg.isDone = isLastFile;

matlabls.internal.CommunicationManager.publish(responseChannel, msg);
end
9 changes: 9 additions & 0 deletions matlab/+matlabls/+handlers/+linting/getLintData.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function lintData = getLintData(code, fileName)
% GETLINTDATA Gathers linting data for the provided MATLAB® code.

% Copyright 2025 The MathWorks, Inc.

lintData = checkcode('-text', code, fileName, '-id', '-severity', '-fix', '-string');
lintData = split(deblank(lintData), newline);
lintData(cellfun(@isempty, lintData)) = [];
end
11 changes: 11 additions & 0 deletions matlab/+matlabls/+handlers/+linting/getSuppressionEdits.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function suppressionEdits = getSuppressionEdits(code, diagnosticId, diagnosticLine, suppressInFile)
% GETSUPPRESSIONEDITS Gets the edits required to suppress the given linting diagnostic.

% Copyright 2025 The MathWorks, Inc.

if suppressInFile
diagnosticId = strcat('*', diagnosticId);
end

suppressionEdits = matlabls.internal.getDiagnosticSuppressionEdits(code, diagnosticId, diagnosticLine);
end
57 changes: 57 additions & 0 deletions matlab/+matlabls/+handlers/+navigation/resolveNameToPath.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
function resolvedPath = resolveNameToPath(name, contextFile)
% RESOLVENAMETOPATH Resolves a name (e.g. "plot") to the respective file path which
% corresponds to the definition of that name.

% Copyright 2025 The MathWorks, Inc.

resolvedPath = resolvePath(name, contextFile);

% If the name is not found, try CDing to the context file's
% directory and searching again
if strlength(resolvedPath) == 0
returnDir = cdToPackageRoot(contextFile);
resolvedPath = resolvePath(name, contextFile);
cd(returnDir);
end
end

function resolvedPath = resolvePath (name, contextFile)
if isMATLABReleaseOlderThan('R2023b')
% For usage in R2023a and earlier
[isFound, resolvedPath] = matlabls.internal.resolvePath(name, contextFile);
elseif isMATLABReleaseOlderThan('R2024a')
% For usage in R2023b only
[isFound, resolvedPath] = matlab.internal.language.introspective.resolveFile(name, []);
elseif isMATLABReleaseOlderThan('R2024b')
% For usage in R2024a only
ec = matlab.lang.internal.introspective.ExecutionContext;
[isFound, resolvedPath] = matlab.lang.internal.introspective.resolveFile(name, ec);
else
% For usage in R2024b and later
ic = matlab.lang.internal.introspective.IntrospectiveContext.caller;
[isFound, resolvedPath] = matlab.lang.internal.introspective.resolveFile(name, ic);
end

if ~isFound
resolvedPath = '';
end
end

function returnDir = cdToPackageRoot (filePath)
% Given a file path, CDs to the directory at the root-level of the
% file's package structure. If the file is not within a package,
% this CDs to the file's directory.

splitDirs = strsplit(fileparts(filePath), filesep);

% Determine how far up the path we need to CD
lastInd = numel(splitDirs);
while lastInd > 1
if ~startsWith(splitDirs(lastInd), '+')
break;
end
lastInd = lastInd - 1;
end

returnDir = cd(strjoin(splitDirs(1:lastInd), filesep));
end
47 changes: 0 additions & 47 deletions matlab/+matlabls/+handlers/CompletionSupportHandler.m

This file was deleted.

19 changes: 0 additions & 19 deletions matlab/+matlabls/+handlers/FeatureHandler.m

This file was deleted.

33 changes: 0 additions & 33 deletions matlab/+matlabls/+handlers/FoldingSupportHandler.m

This file was deleted.

Loading