Skip to content
Open
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.3.9] - 2026-02-19

### Fixed
- Resolves an issue starting MATLAB when the `HOME` environment variable is set to an invalid folder (Addresses [mathworks/MATLAB-extension-for-vscode#164](https://github.com/mathworks/MATLAB-extension-for-vscode/issues/164))

## [1.3.8] - 2026-01-09

### Added
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ MATLAB language server implements several Language Server Protocol features and
## Clients
MATLAB language server supports these editors by installing the corresponding extension:
* Emacs - [Emacs-MATLAB-Mode](https://github.com/mathworks/Emacs-MATLAB-Mode)
* Neovim — [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig)
* Visual Studio® Code — [MATLAB extension for Visual Studio Code](https://github.com/mathworks/MATLAB-extension-for-vscode)
* Neovim - [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig)
* Visual Studio® Code - [MATLAB extension for Visual Studio Code](https://github.com/mathworks/MATLAB-extension-for-vscode)
* Zed - [MATLAB support for Zed](https://github.com/zed-extensions/matlab)

## Release Notes

Expand Down
653 changes: 407 additions & 246 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "matlab-language-server",
"version": "1.3.8",
"version": "1.3.9",
"description": "Language Server for MATLAB code",
"main": "./src/index.ts",
"bin": "./out/index.js",
Expand Down
8 changes: 4 additions & 4 deletions src/debug/MatlabDebugAdaptor.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright 2025 The MathWorks, Inc.
// Copyright 2025-2026 The MathWorks, Inc.

import * as debug from '@vscode/debugadapter'
import { DebugProtocol } from '@vscode/debugprotocol';
import { DebugServices, BreakpointInfo } from './DebugServices'
import { ResolvablePromise, createResolvablePromise } from '../utils/PromiseUtils'
import { IMVM, MVMError, MatlabState } from '../mvm/impl/MVM';
import { IMVM, MVMError, MatlabMVMConnectionState } from '../mvm/impl/MVM';
import fs from 'node:fs';

enum BreakpointChangeType {
Expand Down Expand Up @@ -92,8 +92,8 @@ export default class MatlabDebugAdaptor {
this._pendingSetBreakpointPromise = undefined;
this._pendingTemporaryStackChangePromise = undefined;

this._mvm.on(IMVM.Events.stateChange, (state: MatlabState) => {
if (state === MatlabState.DISCONNECTED) {
this._mvm.on(IMVM.Events.stateChange, (state: MatlabMVMConnectionState) => {
if (state === MatlabMVMConnectionState.DISCONNECTED) {
this._handleDisconnect();
this._matlabBreakpoints = [];
}
Expand Down
6 changes: 3 additions & 3 deletions src/licensing/gui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions src/lifecycle/GraphicsPrewarmService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2025 The MathWorks, Inc.
// Copyright 2025-2026 The MathWorks, Inc.

import Logger from '../logging/Logger';
import MVM, { IMVM, MatlabState } from '../mvm/impl/MVM';
import MVM, { IMVM, MatlabMVMConnectionState } from '../mvm/impl/MVM';
import { ConfigurationManager } from './ConfigurationManager';

/**
Expand All @@ -27,10 +27,10 @@ export default class GraphicsPrewarmService {
*
* @param state The MVM state
*/
private async handleMvmStateChange (state: MatlabState): Promise<void> {
if (state === MatlabState.READY) {
private async handleMvmStateChange (state: MatlabMVMConnectionState): Promise<void> {
if (state === MatlabMVMConnectionState.CONNECTED) {
await this.handleMatlabConnectionReady()
} else if (state === MatlabState.DISCONNECTED) {
} else if (state === MatlabMVMConnectionState.DISCONNECTED) {
// Reset hasPrewarmed flag when MATLAB is disconnected
this.hasPrewarmed = false
}
Expand Down
2 changes: 1 addition & 1 deletion src/lifecycle/MatlabCommunicationManager.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/lifecycle/PathSynchronizer.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright 2024-2025 The MathWorks, Inc.
// Copyright 2024-2026 The MathWorks, Inc.

import { WorkspaceFolder, WorkspaceFoldersChangeEvent } from 'vscode-languageserver'
import ClientConnection, { Connection } from '../ClientConnection'
import Logger from '../logging/Logger'
import MatlabLifecycleManager from './MatlabLifecycleManager'
import * as os from 'os'
import path from 'path'
import MVM, { IMVM, MatlabState } from '../mvm/impl/MVM'
import MVM, { IMVM, MatlabMVMConnectionState } from '../mvm/impl/MVM'
import parse from '../mvm/MdaParser'
import * as FileNameUtils from '../utils/FileNameUtils'

Expand All @@ -25,8 +25,8 @@ export default class PathSynchronizer {
initialize (): void {
const clientConnection = ClientConnection.getConnection()

this.mvm.on(IMVM.Events.stateChange, (state: MatlabState) => {
if (state === MatlabState.READY) {
this.mvm.on(IMVM.Events.stateChange, (state: MatlabMVMConnectionState) => {
if (state === MatlabMVMConnectionState.CONNECTED) {
void this.handleMatlabConnected(clientConnection)
}
})
Expand Down
6 changes: 3 additions & 3 deletions src/mvm/MVMServer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2024-2025 The MathWorks, Inc.
// Copyright 2024-2026 The MathWorks, Inc.

import NotificationService, { Notification } from '../notifications/NotificationService'
import MVM, { IMVM, MatlabState, EvalRequest, EvalResponse, FEvalRequest, FEvalResponse, BreakpointRequest, PromptState } from './impl/MVM'
import MVM, { IMVM, MatlabMVMConnectionState, EvalRequest, EvalResponse, FEvalRequest, FEvalResponse, BreakpointRequest, PromptState } from './impl/MVM'

/**
* Provides an interface for sending evals and fevals and listening to the results.
Expand Down Expand Up @@ -32,7 +32,7 @@ export default class MVMServer {
this._mvm.on(IMVM.Events.promptChange, this._handlePromptChange.bind(this));
}

private _handleMvmStateChange (state: MatlabState, release?: string): void {
private _handleMvmStateChange (state: MatlabMVMConnectionState, release?: string): void {
this._notificationService.sendNotification(Notification.MVMStateChange, { state, release });
}

Expand Down
5 changes: 2 additions & 3 deletions src/mvm/impl/MVM.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ export * from './MVMInterface';
/**
* Used to represent the state of MATLAB
*/
export declare enum MatlabState {
export declare enum MatlabMVMConnectionState {
DISCONNECTED = "disconnected",
READY = "ready",
BUSY = "busy"
CONNECTED = "connected"
}
/**
* Provides an interface for sending evals and fevals and listening to the results.
Expand Down
2 changes: 1 addition & 1 deletion src/mvm/impl/MVM.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import LintingSupportProvider from './providers/linting/LintingSupportProvider'
import ExecuteCommandProvider, { MatlabLSCommands } from './providers/lspCommands/ExecuteCommandProvider'
import NavigationSupportProvider from './providers/navigation/NavigationSupportProvider'
import LifecycleNotificationHelper from './lifecycle/LifecycleNotificationHelper'
import MVM, { IMVM, MatlabState } from './mvm/impl/MVM'
import MVM, { IMVM, MatlabMVMConnectionState } from './mvm/impl/MVM'
import FoldingSupportProvider from './providers/folding/FoldingSupportProvider'
import ClientConnection from './ClientConnection'
import PathResolver from './providers/navigation/PathResolver'
Expand Down Expand Up @@ -87,8 +87,8 @@ export async function startServer (): Promise<void> {
hasMatlabBeenRequested = false
})

mvm.on(IMVM.Events.stateChange, (state: MatlabState) => {
if (state === MatlabState.READY) {
mvm.on(IMVM.Events.stateChange, (state: MatlabMVMConnectionState) => {
if (state === MatlabMVMConnectionState.CONNECTED) {
// Handle when the MVM has connected
mvm.feval('matlabls.utils.startupHelper', 0, [])

Expand Down
16 changes: 8 additions & 8 deletions tests/lifecycle/GraphicsPrewarmService.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Copyright 2025 The MathWorks, Inc.
// Copyright 2025-2026 The MathWorks, Inc.
import assert from 'assert'
import sinon from 'sinon'

import getMockMvm from '../mocks/Mvm.mock'
import getMockConfigurationManager from '../mocks/ConfigurationManager.mock'

import { IMVM, MatlabState } from '../../src/mvm/impl/MVM'
import { IMVM, MatlabMVMConnectionState } from '../../src/mvm/impl/MVM'

import GraphicsPrewarmService from '../../src/lifecycle/GraphicsPrewarmService'

Expand All @@ -29,7 +29,7 @@ describe('GraphicsPrewarmService', () => {
const graphicsPrewarmService = new GraphicsPrewarmService(mockMvm, mockConfigurationManager)
assert.ok(!graphicsPrewarmService.hasPrewarmed, 'Should not have prewarmed yet')

mockMvm._emitEvent(IMVM.Events.stateChange, MatlabState.READY)
mockMvm._emitEvent(IMVM.Events.stateChange, MatlabMVMConnectionState.CONNECTED)

// Wait for async operations to resolve
await new Promise(resolve => setTimeout(resolve, 0))
Expand All @@ -46,7 +46,7 @@ describe('GraphicsPrewarmService', () => {
const graphicsPrewarmService = new GraphicsPrewarmService(mockMvm, mockConfigurationManager)
assert.ok(!graphicsPrewarmService.hasPrewarmed, 'Should not have prewarmed yet')

mockMvm._emitEvent(IMVM.Events.stateChange, MatlabState.READY)
mockMvm._emitEvent(IMVM.Events.stateChange, MatlabMVMConnectionState.CONNECTED)

sinon.assert.notCalled(mockMvm.feval)
assert.ok(!graphicsPrewarmService.hasPrewarmed, 'Still should not have prewarmed because setting is disabled')
Expand All @@ -68,7 +68,7 @@ describe('GraphicsPrewarmService', () => {
const graphicsPrewarmService = new GraphicsPrewarmService(mockMvm, mockConfigurationManager)
assert.ok(!graphicsPrewarmService.hasPrewarmed, 'Should not have prewarmed yet')

mockMvm._emitEvent(IMVM.Events.stateChange, MatlabState.READY)
mockMvm._emitEvent(IMVM.Events.stateChange, MatlabMVMConnectionState.CONNECTED)

// Wait for async operations to resolve
await new Promise(resolve => setTimeout(resolve, 0))
Expand All @@ -84,7 +84,7 @@ describe('GraphicsPrewarmService', () => {
const graphicsPrewarmService = new GraphicsPrewarmService(mockMvm, mockConfigurationManager)
assert.ok(!graphicsPrewarmService.hasPrewarmed, 'Should not have prewarmed yet')

mockMvm._emitEvent(IMVM.Events.stateChange, MatlabState.READY)
mockMvm._emitEvent(IMVM.Events.stateChange, MatlabMVMConnectionState.CONNECTED)

// Wait for async operations to resolve
await new Promise(resolve => setTimeout(resolve, 0))
Expand All @@ -100,7 +100,7 @@ describe('GraphicsPrewarmService', () => {
const graphicsPrewarmService = new GraphicsPrewarmService(mockMvm, mockConfigurationManager)
graphicsPrewarmService.hasPrewarmed = true // Manually set prewarmed status

mockMvm._emitEvent(IMVM.Events.stateChange, MatlabState.READY)
mockMvm._emitEvent(IMVM.Events.stateChange, MatlabMVMConnectionState.CONNECTED)

// Wait for async operations to resolve
await new Promise(resolve => setTimeout(resolve, 0))
Expand All @@ -116,7 +116,7 @@ describe('GraphicsPrewarmService', () => {
const graphicsPrewarmService = new GraphicsPrewarmService(mockMvm, mockConfigurationManager)
graphicsPrewarmService.hasPrewarmed = true // Manually set prewarmed status

mockMvm._emitEvent(IMVM.Events.stateChange, MatlabState.DISCONNECTED)
mockMvm._emitEvent(IMVM.Events.stateChange, MatlabMVMConnectionState.DISCONNECTED)

// Wait for async operations to resolve
await new Promise(resolve => setTimeout(resolve, 0))
Expand Down