MATLAB Spoken Here
September 14th, 2009
MATLAB-Emacs integration is back
I'd like to welcome guest blogger Eric Ludlam from the MATLAB Graphics team.
Back in April of this year, Mike wrote a Desktop Blog article stating that it's the little things that count. In the comments to this article several people who were long time users of EmacsLink wrote in after discovering that the R2009a Editor interface stopped supporting EmacsLink.
As an author of a lot of Emacs code, and the current maintainer of the matlab-emacs project on Source Forge, and the guy who helped bring the original Emacs Link into existence, I was both glad to know that so many folks had found it useful, and sad that they had never joined the matlab-emacs mailing list over on Source Forge, where the many questions could be easily answered.
What is the matlab-emacs project?
The matlab-emacs project is a MATLAB mode for Emacs that consists of Emacs Lisp code that implements a major-mode for Emacs that assists in the editing of MATLAB scripts.
It also allows Emacs to be used in place of the MATLAB Editor for editing your MATLAB source code, debugging MATLAB code, and syntax/semantic checking of your MATLAB code with mlint.
The MATLAB mode for Emacs does NOT include "EmacsLink", which was a tool that more tightly integrated MATLAB and Emacs for purposes of debugging M code. "EmacsLink" only included the communication interface between MATLAB and Emacs. The editing mode has always been a part of the matlab-emacs project.
matlab-mode, which forms the root of the matlab-emacs project was first written by Matt Wette in 1991.
Where to get matlab-emacs.
The matlab-emacs project is hosted on SourceForge where the Emacs Lisp code can be downloaded from CVS.
Detailed download and installation instructions are available here.
Be sure to join the mailing list to get help on setting up and using the matlab-emacs project.
Once you have downloaded the code using your preferred method, read the INSTALL file for full details.
The matlab-emacs project has been expanded by it's users to include support for several features in CEDET. CEDET is an Emacs package that supplies an object system needed by the mlint support, and a complex completion/navigation package.
Writing MATLAB code in Emacs
Writing MATLAB code in Emacs is much like writing any other code in Emacs. The matlab-mode for Emacs has several features users have come to expect from Emacs, plus several features that make editing MATLAB code even better.
What I'm sure many users think of as a single "EmacsLink", as it shipped with MATLAB, had two parts. One part was communication between MATLAB and Emacs for debugging. The other was the MATLAB script editing mode.
Nothing has changed with the editing mode, except to make these tools even better, such as supporting the latest indentation styles, cell-mode, and programming constructs, such as the MATLAB Object System. As such, your editing experience in Emacs has only gotten better.
Setting up matlab-mode for Emacs is pretty easy. Here is an example simple setup:
(add-to-list 'load-path "~/path/to/matlab_dot_el")
;; Enable CEDET feature support for MATLAB code. (Optional)
In this screenshot done with Emacs 23 on Linux, you can see some syntax highlighting, and mlint support for nested functions, and bold-face cross-function variables. The blue line over the nested function, and TAGS menu is part of the CEDET support that includes function browsing and completion. It also shows if/end block matching, and CEDET summary mode showing function details.
Currenlty, the matlab-mode for Emacs supports these features:
- Syntax Highlighting. There are three coloring levels supported.
- Smart indentation. The TAB key, and RETURN key will both indent your code lines. Indent region (C-M-\) for larger areas.
- Code auto-fill & Paragraph fill. M-q does an excellent job on large comments. Autofill is syntax aware, and can find nice places to put line breaks in code.
- Syntax aware block movement. Forward/Backward sexp (C-M-f,C-M-b), and Begin/End of function (C-M-a,C-M-e) correctly moves over begin/end syntax.
- Paren style matching for blocks. Highlight a matching end when the cursor is on an if, and many other matching constructs.
- mlint support. Highlight mlint warings in your code, and a convenient conext menu for tagging and navigating through errors. Some errors can be automatically fixed by Emacs.
- Highlight nested variables. Using mlint, nested variables are highlighted, assiting when working with nested functions.
- Completion engine. Using tools in CEDET, Emacs will parse your M files and provide pretty good completion and code decoration.
How to use Emacs instead of the MATLAB Editor
OK, now to answer many of the questions that have shown up in the comments to the Desktop blog. The most common question seemed to be "Why did you take EmacsLink away?", and Mike and Ken have done a fine job answering that. The real question should be "What should I do now?"
Thankfully, I have two answers, and you can choose the one that best suites your development style.
Using Emacs as an external editor.
You can use Emacs as an external editor now in a way that is similar to what EmacsLink provided.
One of the questions that showed up on the blog was was regarding using the preference panel to set Emacs as the default editor, and the complaint was:
- This creates a new emacs process every time I "edit" or "open" a different function. What should happen is that only the first "edit" should start a new session, and subsequent "edit"s should open the file in the existing session. I can pretty quickly have about 30 extra windows open on my desktop.
- Upon an error, clicking on the error link in the matlab command window opens the official editor, not emacs, even though I specified emacs in the preferences.
The answer to these problems is to use an old Emacs tool called emacsclient. Emacslient lets you tell an already running Emacs to load a file in for editing. To enable emacsclient in your emacs, add this line to your ~/.emacs file:
From the unix command prompt, you can now call emacsclient like this:
emacsclient -n myfile.m
and myfile.m will be loaded into Emacs for editing.
After researching this problem with the Ken and Mike, I have provided some simple tools for getting this setup. The matlab-emacs project now has a toolbox directory. If you were to install matlab-emacs in the directory ~/lisp/matlab-emacs, you can now place code like this in your startup.m file:
This will add the matlab-emacs project toolbox to your path, and the emacsinit script will configure MATLAB to tell an already running Emacs what to do when you type edit, or click on a link in the command window.
This screenshot shows a hand-setup where the location of emacsclient is specified as an argument to emacsinit. This is important on Windows because it may not be on your path. Now, when stopped in the debugger, you can click on the blue line number to jump to that location in some file. The file being debugged is a rubik snake demo I wrote a few years back.
This is a great step forward from just sticking the word "emacs" in the provided text field, but does not answer this question:
- And, of course, none of the other interactivity features are working .. no evaling code from emacs, no debugging, etc.
For this, you will need to use the Emacs command matlab-shell.
The Emacs command M-x matlab-shell RET, on unix, will start MATLAB as a subprocess under Emacs. The command prompt will be available in an Emacs buffer the same way the unix prompt shows up if you type M-x shell.
If you use matlab-shell it will automatically configure your MATLAB as described in the previous section, allowing "edit" command to open files in a currently running Emacs. In addtion, Emacs will be able to send text from M files to the running MATLAB for execution.
Once the matlab-shell has been started, you can select "Run Region" or "Run Cell" from the menu while editing .m files. This will send the text from your source file to matlab-shell for execution.
If you just want to move the cursor to the shell, you can do M-x matlab-shell RET a second time to bring an already running shell forward.
In the above image, you can see the latest Aquamacs running matlab-shell. Selecting "Go to Last Error" or clicking the links moves the cursor to the typo that was introduced in my catapult modeling program.
To debug, you can use the toolbar to set breakpoints, or use the the db commands. For example:
dbstop in ls
This will cause the ls.m file to popup in an Emacs buffer, with the debug arrow pointing at the correct line. Stepping through this file, or into new files will move the arrow to the correct place.
For windows users
MATLAB does not support a tty command window on Windows so you cannot use matlab-shell. You will still be able to use emacsclient however. To do so, you will need to modify the setup configuration like this:
where you would replace the argument to emacsinit with the real path to your emacsclient binary on your system. The -n argument specifies that emacsclient should not wait for the user to finish editing the file.
Windows configuration of emacsclient is also not as easy as it is on Unix. You may need to read up on configuring your Emacsclient to work propertly before starting with the matlab-emacs configuration.
Make matlab-emacs better
The matlab-emacs project has been around for a long time, and its many contributors have made it a powerful way to work with MATLAB. If you want to Emacs as you editor, join the matlab-emacs mailing list, and help make it better.
The below screenshot includes matlab-mode with CEDET support enabled, matlab-shell running, editing, and debugging sliceomatic with ECB, the Emacs Code browser all running together.
For the vim users who also posted comments, the techniques used here for Emacs will also work with vim. Modifying the two MATLAB script files to call to vim instead ought to make it easy to start using vim, or just about any other editor, with MATLAB.
-by Eric Ludlam, The MathWorks