MATLAB Runner & Debugger (R2020a compatible)
Run, debug and plot MATLAB code from VS Code with MATLAB releases that the
official MathWorks extension no longer supports (it needs R2021a/R2021b).
Tested with R2020a; it should work with any release from about R2016b on
that ships Java 8 (which includes the Nashorn JavaScript engine used by the
in-MATLAB agent).
Features
Run a file (Ctrl+F5 or the play button), the current selection/line
(Shift+Enter or Ctrl+F9, MATLAB's Evaluate Selection) or the current %%
section (Ctrl+Enter). With nothing selected the current line is evaluated.
Both go to the command window that is already open, as if typed at its prompt.
Debug with the standard VS Code UI: breakpoints (incl. conditional),
step over / into / out, continue, call stack with frame selection,
Variables view (structs, cells, arrays, maps, tables, objects expand),
hover datatips over whole property chains (h.Params.min_band, not just the
word under the mouse) and Watch evaluation, Debug Console REPL in the paused
workspace,
dbstop if error style exception breakpoints (uncaught/caught errors,
warnings, NaN/Inf).
MATLAB command window as a VS Code terminal (MATLAB R2020a: Open Command Window): interactive prompt, history, K>> prompt while paused, Ctrl+C
interrupts.
Command window output (disp, fprintf, unsuppressed results, warnings,
errors) appears in that terminal and in the Debug Console. The terminal opens
automatically when you run or debug a file; set
matlab-r2020a.showCommandWindowOnRun to false if you would rather open it
yourself. Output produced before the terminal was opened is kept and replayed,
so nothing is lost.
Plot catalog on the Variables view: right-click a variable while paused
and pick a plot from the Plot submenu — plot, stem, stairs, bar,
area, histogram, pie, semilogy, loglog, imagesc, surf, mesh,
contour, spy, or a magnitude spectrum in dB. The entries offered depend
on the value's shape: a scalar gets no menu at all, a vector gets the
one-dimensional plots, and a 2-D matrix gets all of them. It works on nested
values too (a struct field, a cell element, a matrix row), and the plot is
drawn in the stack frame you are looking at.
Plots open as normal MATLAB figure windows (fully interactive: zoom,
rotate, data tips). MATLAB: Show Current Figure in VS Code additionally
renders a snapshot of the current figure in an editor tab.
Go to Definition (Ctrl+click, F12) on a variable, function, class or
method name.
- Variables jump to where they are bound in the enclosing scope: a
function parameter or output, a
for loop variable, a global or
persistent declaration, a catch identifier, an anonymous function
parameter, or the first assignment. Each function in a file is its own
scope; a nested function also sees its parent's variables, and a script is
one scope. Comments and char literals are ignored, so % x = 1 is not a
definition of x.
- Properties and struct fields are resolved on the object, before
variables and functions, so
min_band in h.Params.min_band goes to the
properties block that declares it — never to an unrelated variable of the
same name. While MATLAB is running it is asked what h.Params actually is
(class, then which), which is the only reliable answer; with nothing
running, a property of the class being edited and the first assignment of a
struct field are still found. Only the root of the chain is ever touched,
and only when it is already a variable, so a Ctrl+click cannot call a
function.
- Functions are looked up after variables (a MATLAB variable shadows a
function of the same name): local, nested and
methods-block functions in
the file itself, then a neighbouring file (including private/), then
MATLAB's own which — which knows the real search path, so toolbox
functions, +package functions and @class methods resolve too — and
finally a search of the workspace.
Everything except the which step works with no MATLAB running, and which
is skipped while MATLAB is busy so a long computation can never make
Ctrl+click hang.
Help on a name (F1), like F1 in MATLAB's own editor: the help text for
the function, class or method under the cursor (or for the selection) opens
in a panel beside the code, with the See also names as links you can follow
and a button to jump to the definition. The text comes from MATLAB's own
help; when no session is running, or MATLAB is busy with your program, the
help comment of the file itself is used instead, so F1 still answers for
your own functions. Set matlab-r2020a.help.useMatlabBrowser to open
MATLAB's real Help browser (doc) instead — it is exempted from the window
hiding while it is open.
Clickable error locations. When MATLAB reports an error, the
Error in foo (line 3) lines of the stack become links in the command window
and in the Debug Console — clicking one opens that file at that line, as
clicking the error in MATLAB's own command window does. Warning stacks
(In foo (line 8)) link the same way. In the command window the file is
resolved when you click, so toolbox and +package functions resolve too; the
Debug Console can only attach a location it can find without waiting, so a
name MATLAB has to be asked about may link from the second occurrence on.
Diagnostics from MATLAB's own Code Analyzer (mlint.exe), which is part
of every MATLAB installation.
A MATLAB icon on .m files in editor tabs and the explorer, contributed as
a language icon. File icon themes use it only where they define no icon of
their own for .m; the default (Seti) theme does not, so it shows. A theme
that does claim .m (Material Icon Theme, for instance) keeps its own icon.
MATLAB's own command window and editor windows stay hidden; the session and
its workspace persist between runs, like the MATLAB desktop.
Requirements
- Windows, MATLAB installed (any release with a Java 8 runtime, e.g. R2020a).
- No MATLAB toolboxes, no Python, no COM registration needed.
Setup
- Install the extension (
.vsix) or run it from source (npm install,
npm run build, then F5 in VS Code).
- If several MATLAB releases are installed, the oldest one is used by
default. Pick one explicitly with the
matlab-r2020a.installPath setting,
e.g. C:\Program Files\MATLAB\R2020a.
- Open a folder with
.m files. The first run starts MATLAB in the
background (10 to 30 seconds); a status bar item shows the session state.
Usage
All commands live under the MATLAB R2020a category in the command palette.
| Action |
How |
| Run current file |
Ctrl+F5, play button, or MATLAB R2020a: Run File |
| Debug current file |
F5 (creates a default launch configuration), or the debug button |
| Run selection / line |
Shift+Enter or MATLAB R2020a: Run Selection or Current Line |
Run %% section |
Ctrl+Enter |
| Command window |
MATLAB R2020a: Open Command Window or click the status bar item |
| Interrupt |
Ctrl+C in the command window, or MATLAB R2020a: Interrupt Execution |
| Help on the name at the cursor |
F1 (in a .m editor), or MATLAB R2020a: Help on Selection |
| Show figure in VS Code |
MATLAB R2020a: Show Current Figure in VS Code |
| Quit MATLAB |
MATLAB R2020a: Stop MATLAB Session |
F1 is VS Code's Command Palette key; this extension takes it over only while a
MATLAB editor has focus, which is where MATLAB itself uses it for help. The
palette is still on Ctrl+Shift+P, and the binding can be removed in
Keyboard Shortcuts like any other.
A launch.json entry looks like this:
{
"type": "matlab-r2020a",
"request": "launch",
"name": "MATLAB: Run current file",
"program": "${file}",
"stopOnEntry": false
}
Coexisting with the official MathWorks extension
The MathWorks extension (MathWorks.language-matlab) claims the debug type
matlab and the command ids matlab.runFile, matlab.runSection,
matlab.runSelection, matlab.openCommandWindow and matlab.interrupt. VS
Code allows only one extension per debug type and refuses a duplicate command
id, so everything here is namespaced instead: debug type matlab-r2020a,
commands matlab-r2020a.*, settings matlab-r2020a.*. Both extensions can be
installed at the same time.
One thing still overlaps: Ctrl+Enter is bound to "run section" by both
extensions, and only one of them wins. If it runs the wrong one, either
disable the MathWorks extension for this workspace (Extensions view, gear icon,
"Disable (Workspace)") or rebind the key in your keyboard shortcuts.
program is run by name after changing MATLAB's current folder to the file's
folder (or cwd), so both scripts and zero-argument functions work.
How it works
MATLAB is started with -nodesktop -minimize and a startup command that runs
matlab/vscode_agent.m. That function uses MATLAB's bundled Java 8 Nashorn
engine to start a small listener thread inside the MATLAB process. The
extension talks to it over a local TCP socket:
console submits text exactly as if typed at the prompt (this is the only
way to run dbstep, dbcont, ... which MATLAB refuses through COM or the
engine APIs);
eval evaluates helper functions synchronously and returns their output
(call stack, variables, breakpoints); MATLAB answers whenever it is at a
prompt, including the K>> debug prompt;
interrupt is the equivalent of Ctrl+C and works even during busy loops.
Command window output is read live from MATLAB's -logfile.
Limitations
input() and keyboard inside scripts cannot receive text from VS Code
(there is no console); use the MATLAB window (MATLAB R2020a: Show MATLAB Command Window) or interrupt.
- "Pause" in the debug toolbar interrupts the program instead of breaking
into it; MATLAB has no external "break now" for a running program.
- Variables of a frame other than the current one are read through
dbup/dbdown, which prints "In workspace belonging to ..." lines in
MATLAB's log (filtered from the Debug Console).
- Windows only (relies on
matlab.exe startup flags and a PowerShell helper
to hide the native command window).
Development
npm install
npm run build # bundle to dist/extension.js
npm run typecheck
npm run package # create the .vsix
scratch/ holds the feasibility experiments and integration tests used while
building the extension (scratch/session_test.js exercises the whole
session layer against a real MATLAB without VS Code).
| |