Skip to content

Commit 1046abf

Browse files
authored
Merge pull request #187 from mathworks/dklilley/release/1.2.7
MATLAB extension for VS Code - v1.2.7
2 parents 4d08291 + fa0ca8e commit 1046abf

14 files changed

+775
-26
lines changed

.vscodeignore

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,10 @@ server/.git
2626
server/.github
2727
server/.gitattributes
2828
server/.gitignore
29-
server/webpack.config.js
29+
server/webpack.config.js
30+
31+
# Skip packaging the the source code in licensing/gui folder as it is already built and moved into
32+
# out/ directory by the "compile" script in server/package.json.
33+
34+
# The server/src/licensing/*.ts files compilation is already handled by server/tsconfig.json
35+
server/src/licensing/

CHANGELOG.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.2.7] - 2024-11-07
11+
12+
### Added
13+
- Visual indication of code sections
14+
- Enable browser-based sign in using the `signIn` setting
15+
- Specify the maximum file size for code analysis using the new `maxFileSizeForAnalysis` setting
16+
- Linting support in untitled files and in MATLAB files with different file extensions
17+
18+
### Fixed
19+
- The `installPath` setting no longer syncs between machines
20+
1021
## [1.2.6] - 2024-09-20
1122

1223
### Fixed
@@ -18,7 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1829

1930
### Added
2031
- Symbol rename support
21-
- Enables users to hide "feature not available" error popups
32+
- Enable hiding "feature not available" error popups
2233
- Provides context menu option to add selected folder and subfolders to the path
2334

2435
### Fixed
@@ -27,7 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2738
## [1.2.4] - 2024-07-12
2839

2940
### Added
30-
- Enable users to specify workspace-specific MATLAB install paths
41+
- Enable specifying workspace-specific MATLAB install paths
3142
- Improvements to code folding (requires MATLAB R2024b or later)
3243

3344
### Fixed
@@ -42,7 +53,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4253
- This extension will no longer support MATLAB R2021a in a future release. To make use of the advanced features of the extension or run MATLAB code, you will need to have MATLAB R2021b or later installed.
4354

4455
### Added
45-
- Popups will be shown to inform the user when the connected MATLAB is not supported by the extension, or if support is planned to be removed in a future update.
56+
- Popups will be shown to inform when the connected MATLAB is not supported by the extension, or if support is planned to be removed in a future update.
4657

4758
### Fixed
4859
- Resolved issue with connecting to Intel MATLAB installation on Apple Silicon machines

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,17 @@ You can help improve the extension by sending user experience information to Mat
8181

8282
For more information, see the [MathWorks Privacy Policy](https://www.mathworks.com/company/aboutus/policies_statements.html).
8383

84-
### MATLAB Show Feature Not Available Error
84+
### MATLAB Show Feature Not Available Error Setting
8585
By default, the extension displays an error when a feature requires MATLAB and MATLAB is unable to start. To not display an error, set the `matlab.showFeatureNotAvailableError` setting to `false`.
8686

87+
### MATLAB Max File Size for Analysis Setting
88+
By default, the extension analyzes all files, regardless of their size, for features such as linting, code navigation, and symbol renaming. To limit the maximum number of characters a file can contain, set the `matlab.maxFileSizeForAnalysis` setting. For example, to limit the number of characters to 50,000, set the `matlab.maxFileSizeForAnalysis` setting to `50000`. If a file contains more than the maximum number of characters, features such as linting, code navigation, and symbol renaming are disabled for that file. To remove the limit and analyze all files regardless of their size, set the `matlab.maxFileSizeForAnalysis` setting to `0`.
89+
90+
### MATLAB Sign In Setting
91+
By default, the extension assumes that the MATLAB installation specified in the Install Path setting is activated.
92+
93+
To enable browser-based sign in to your MathWorks account using the Online License Manager or a Network License Manager, set the `matlab.signIn` setting to true. When this setting is enabled, the extension prompts you to sign in when it starts MATLAB.
94+
8795
## Troubleshooting
8896
If the MATLAB install path is not properly configured, you get an error when you try to use certain advanced features, such as document formatting and code navigation.
8997

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Edit MATLAB code with syntax highlighting, linting, navigation support, and more",
55
"icon": "public/L-Membrane_RGB_128x128.png",
66
"license": "MIT",
7-
"version": "1.2.6",
7+
"version": "1.2.7",
88
"engines": {
99
"vscode": "^1.67.0"
1010
},
@@ -61,6 +61,10 @@
6161
"command": "matlab.changeDirectory",
6262
"title": "MATLAB: Change current directory"
6363
},
64+
{
65+
"command": "matlab.enableSignIn",
66+
"title": "MATLAB: Manage Sign In Options"
67+
},
6468
{
6569
"command": "matlab.resetDeprecationPopups",
6670
"title": "MATLAB: Reset Deprecation Warning Popups"
@@ -156,7 +160,7 @@
156160
"MATLAB.installPath": {
157161
"type": "string",
158162
"markdownDescription": "The full path to the top-level directory of the MATLAB installation you want to use with this extension. You can determine the full path to your MATLAB installation using the `matlabroot` command in MATLAB. For more information, refer to the [README](https://github.com/mathworks/MATLAB-extension-for-vscode/blob/main/README.md). This setting can be specified for both the user and workspace setting scopes using the User and Workspace tabs above.",
159-
"scope": "window"
163+
"scope": "machine-overridable"
160164
},
161165
"MATLAB.matlabConnectionTiming": {
162166
"type": "string",
@@ -190,14 +194,27 @@
190194
"usesOnlineServices"
191195
]
192196
},
197+
"MATLAB.signIn": {
198+
"type": "boolean",
199+
"default": false,
200+
"markdownDescription": "Enable this option to present Sign In Options for unactivated MATLAB installations.",
201+
"scope": "machine"
202+
},
193203
"MATLAB.showFeatureNotAvailableError": {
194204
"type": "boolean",
195205
"default": true,
196206
"description": "Display an error when a feature requires MATLAB and MATLAB is unable to start.",
197207
"scope": "window"
208+
},
209+
"MATLAB.maxFileSizeForAnalysis": {
210+
"type": "number",
211+
"default": 0,
212+
"markdownDescription": "The maximum number of characters a file can contain for features such as linting, code navigation, and symbol renaming to be enabled. Use `0` for no limit.",
213+
"scope": "window"
198214
}
199215
}
200216
},
217+
201218
"languages": [
202219
{
203220
"id": "matlab",
@@ -276,11 +293,5 @@
276293
"dependencies": {
277294
"node-fetch": "^2.6.6",
278295
"vscode-languageclient": "^8.0.2"
279-
},
280-
"__metadata": {
281-
"id": "a41a2325-daf7-4cf4-beee-6c76190ad9fc",
282-
"publisherDisplayName": "MathWorks",
283-
"publisherId": "77ca8d5e-8b29-492a-8efb-4bd3de0c10c2",
284-
"isPreReleaseVersion": false
285296
}
286-
}
297+
}

server

Submodule server updated 107 files

src/Notifications.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,16 @@ enum Notification {
2929
MVMStateChange = 'mvmStateChange',
3030

3131
// Telemetry
32-
LogTelemetryData = 'telemetry/logdata'
32+
LogTelemetryData = 'telemetry/logdata',
33+
34+
// Sections generated for Section Styling
35+
MatlabSections = 'matlab/sections',
36+
37+
// Licensing
38+
LicensingServerUrl = 'licensing/server/url',
39+
LicensingData = 'licensing/data',
40+
LicensingDelete = 'licensing/delete',
41+
LicensingError = 'licensing/error'
3342
}
3443

3544
export default Notification

src/extension.ts

Lines changed: 110 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import { Notifier } from './commandwindow/Utilities'
1212
import TerminalService from './commandwindow/TerminalService'
1313
import Notification from './Notifications'
1414
import ExecutionCommandProvider from './commandwindow/ExecutionCommandProvider'
15+
import * as LicensingUtils from './utils/LicensingUtils'
1516
import DeprecationPopupService from './DeprecationPopupService'
16-
17+
import SectionStylingService from './styling/SectionStylingService'
1718
let client: LanguageClient
18-
1919
const OPEN_SETTINGS_ACTION = 'workbench.action.openSettings'
2020
const MATLAB_INSTALL_PATH_SETTING = 'matlab.installPath'
2121

@@ -27,10 +27,15 @@ export const CONNECTION_STATUS_LABELS = {
2727
const CONNECTION_STATUS_COMMAND = 'matlab.changeMatlabConnection'
2828
export let connectionStatusNotification: vscode.StatusBarItem
2929

30+
// Command to enable or disable Sign In options for MATLAB
31+
const MATLAB_ENABLE_SIGN_IN_COMMAND = 'matlab.enableSignIn'
32+
3033
let telemetryLogger: TelemetryLogger
3134

3235
let deprecationPopupService: DeprecationPopupService
3336

37+
let sectionStylingService: SectionStylingService;
38+
3439
let mvm: MVM;
3540
let terminalService: TerminalService;
3641
let executionCommandProvider: ExecutionCommandProvider;
@@ -53,9 +58,20 @@ export async function activate (context: vscode.ExtensionContext): Promise<void>
5358
connectionStatusNotification.text = CONNECTION_STATUS_LABELS.NOT_CONNECTED
5459
connectionStatusNotification.command = CONNECTION_STATUS_COMMAND
5560
connectionStatusNotification.show()
56-
context.subscriptions.push(connectionStatusNotification)
5761

62+
context.subscriptions.push(connectionStatusNotification)
5863
context.subscriptions.push(vscode.commands.registerCommand(CONNECTION_STATUS_COMMAND, () => handleChangeMatlabConnection()))
64+
// Event handler when VSCode configuration is changed by the user and executes corresponding functions for specific settings.
65+
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => {
66+
const configuration = vscode.workspace.getConfiguration('MATLAB')
67+
68+
// Updates the licensing status bar item and listeners based on the 'signIn' setting.
69+
if (configuration.get<boolean>(LicensingUtils.LICENSING_SETTING_NAME) ?? false) {
70+
LicensingUtils.setupLicensingListeners(client)
71+
} else {
72+
LicensingUtils.removeLicensingListeners()
73+
}
74+
}))
5975

6076
// Set up langauge server
6177
const serverModule: string = context.asAbsolutePath(
@@ -102,7 +118,6 @@ export async function activate (context: vscode.ExtensionContext): Promise<void>
102118
client.onNotification(Notification.MatlabFeatureUnavailable, () => handleFeatureUnavailable())
103119
client.onNotification(Notification.MatlabFeatureUnavailableNoMatlab, () => handleFeatureUnavailableWithNoMatlab())
104120
client.onNotification(Notification.LogTelemetryData, (data: TelemetryEvent) => handleTelemetryReceived(data))
105-
106121
mvm = new MVM(client as Notifier);
107122
terminalService = new TerminalService(client as Notifier, mvm);
108123
executionCommandProvider = new ExecutionCommandProvider(mvm, terminalService, telemetryLogger);
@@ -115,32 +130,114 @@ export async function activate (context: vscode.ExtensionContext): Promise<void>
115130
context.subscriptions.push(vscode.commands.registerCommand('matlab.addFolderAndSubfoldersToPath', async (uri: vscode.Uri) => await executionCommandProvider.handleAddFolderAndSubfoldersToPath(uri)))
116131
context.subscriptions.push(vscode.commands.registerCommand('matlab.changeDirectory', async (uri: vscode.Uri) => await executionCommandProvider.handleChangeDirectory(uri)))
117132

133+
// Register a custom command which allows the user enable / disable Sign In options.
134+
// Using this custom command would be an alternative approach to going to enabling the setting.
135+
context.subscriptions.push(vscode.commands.registerCommand(MATLAB_ENABLE_SIGN_IN_COMMAND, async () => await handleEnableSignIn()))
136+
137+
// Setup listeners only if licensing workflows are enabled.
138+
// Any further changes to the configuration settings will be handled by configChangeListener.
139+
if (LicensingUtils.isSignInSettingEnabled()) {
140+
LicensingUtils.setupLicensingListeners(client)
141+
}
142+
118143
deprecationPopupService = new DeprecationPopupService(context)
119144
deprecationPopupService.initialize(client)
120145

146+
sectionStylingService = new SectionStylingService(context)
147+
sectionStylingService.initialize(client);
148+
121149
await client.start()
122150
}
123151

152+
/**
153+
* Handles enabling MATLAB licensing workflows.
154+
*
155+
* Checks if the `signIn` setting is enabled. If it is not enabled,
156+
* updates the setting to enable it and displays a message indicating the workflows
157+
* have been enabled. If it is already enabled, displays a message indicating that.
158+
*
159+
* @param context - The context in which the extension is running.
160+
* @returns A promise that resolves when the operation is complete.
161+
*/
162+
async function handleEnableSignIn (): Promise<void> {
163+
const configuration = vscode.workspace.getConfiguration('MATLAB');
164+
const enable = 'Enable'
165+
const disable = 'Disable';
166+
167+
const choices = LicensingUtils.isSignInSettingEnabled() ? [disable] : [enable]
168+
169+
const choice = await vscode.window.showQuickPick(choices, {
170+
placeHolder: 'Manage Sign In Options'
171+
})
172+
173+
if (choice == null) {
174+
return
175+
}
176+
177+
if (choice === 'Enable') {
178+
await configuration.update(LicensingUtils.LICENSING_SETTING_NAME, true, vscode.ConfigurationTarget.Global);
179+
void vscode.window.showInformationMessage('Sign In Options enabled.')
180+
} else if (choice === 'Disable') {
181+
await configuration.update(LicensingUtils.LICENSING_SETTING_NAME, false, vscode.ConfigurationTarget.Global);
182+
void vscode.window.showInformationMessage('Sign In Options disabled.')
183+
}
184+
}
185+
124186
/**
125187
* Handles user input about whether to connect or disconnect from MATLAB®
126188
*/
127189
function handleChangeMatlabConnection (): void {
128-
void vscode.window.showQuickPick(['Connect to MATLAB', 'Disconnect from MATLAB'], {
190+
const connect = 'Connect to MATLAB';
191+
const disconnect = 'Disconnect from MATLAB';
192+
const options = [connect, disconnect]
193+
194+
const isSignInEnabled = LicensingUtils.isSignInSettingEnabled()
195+
const signOut = 'Sign Out of MATLAB'
196+
const isLicensed = LicensingUtils.getMinimalLicensingInfo() !== ''
197+
const isMatlabConnecting = connectionStatusNotification.text === CONNECTION_STATUS_LABELS.CONNECTING
198+
199+
// Only show signout option when signin setting is enabled, MATLAB is connected and is licensed
200+
if (isSignInEnabled && isLicensed && isMatlabConnected()) {
201+
options.push(signOut)
202+
}
203+
204+
void vscode.window.showQuickPick(options, {
129205
placeHolder: 'Change MATLAB Connection'
130206
}).then(choice => {
131207
if (choice == null) {
132208
return
133209
}
134210

135-
if (choice === 'Connect to MATLAB') {
211+
if (choice === connect) {
212+
// Opens the browser tab with licensing URL.
213+
// This will only occur when the tab is accidentally closed by the user and wants to
214+
// connect to MATLAB
215+
if (isSignInEnabled && !isLicensed && isMatlabConnecting) {
216+
void client.sendNotification(Notification.LicensingServerUrl)
217+
}
136218
sendConnectionActionNotification('connect')
137-
} else if (choice === 'Disconnect from MATLAB') {
219+
} else if (choice === disconnect) {
138220
sendConnectionActionNotification('disconnect')
139221
terminalService.closeTerminal();
222+
} else if (choice === signOut) {
223+
void client.sendNotification(Notification.LicensingDelete)
224+
sendConnectionActionNotification('disconnect')
140225
}
141226
})
142227
}
143228

229+
/**
230+
* Checks if a connection to MATLAB is currently established.
231+
*
232+
* This function determines the connection status by checking if the connection status
233+
* notification text includes a specific label indicating a successful connection.
234+
*
235+
* @returns `true` if MATLAB is connected, otherwise `false`.
236+
*/
237+
function isMatlabConnected (): boolean {
238+
return connectionStatusNotification.text.includes(CONNECTION_STATUS_LABELS.CONNECTED)
239+
}
240+
144241
/**
145242
* Handles the notifiaction that the connection to MATLAB has changed (either has connected,
146243
* disconnected, or is in the process of connecting)
@@ -150,9 +247,14 @@ function handleChangeMatlabConnection (): void {
150247
function handleConnectionStatusChange (data: { connectionStatus: string }): void {
151248
if (data.connectionStatus === 'connected') {
152249
connectionStatusNotification.text = CONNECTION_STATUS_LABELS.CONNECTED
250+
const licensingInfo = LicensingUtils.getMinimalLicensingInfo()
251+
252+
if (LicensingUtils.isSignInSettingEnabled() && licensingInfo !== '') {
253+
connectionStatusNotification.text += licensingInfo
254+
}
153255
} else if (data.connectionStatus === 'disconnected') {
154256
terminalService.closeTerminal();
155-
if (connectionStatusNotification.text === CONNECTION_STATUS_LABELS.CONNECTED) {
257+
if (isMatlabConnected()) {
156258
const message = NotificationConstants.MATLAB_CLOSED.message
157259
const options = NotificationConstants.MATLAB_CLOSED.options
158260
vscode.window.showWarningMessage(message, ...options

0 commit comments

Comments
 (0)