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.
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") (load-library "matlab-load") ;; Enable CEDET feature support for MATLAB code. (Optional) (matlab-cedet-setup)
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:
addpath('~/lisp/matlab-emacs/toolbox','-begin'); rehash; emacsinit;
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 ls dbstep dbstep dbquit
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:
addpath('~/lisp/matlab-emacs/toolbox','-begin'); rehash; emacsinit('c:/applications/Emacs/lib-src/emacsclient -n');
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.
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
Comments are closed.
37 CommentsOldest to Newest
I wondered if you could expand on your comment about Vim.
The MATLAB code that the matlab-shell for Emacs program uses are pretty simple, and could be used to have MATLAB pull up files in vim instead. You could use the same emacsinit script with vim instead. For example:
emacsinit('xterm -e vim');
As I am not a vim user, I couldn’t say what the best use case is.
“Matlab-Emacs Integration is Back,” but not as we EmacsLink users remember it. I’m disappointed that the authors appear to be acting disingenously here. The first approach mentioned above (using Emacs as an external editor) is the same bone you threw us when we first complained about removing EmacsLink. As a simple external editor, Emacs can’t do integrated debugging like before. The second approach (using matlab-shell) is a kludgy work-around that won’t be nearly as convenient for me as using the old EmacsLink.
I fail to see how keeping EmacsLink threatens your goal to make the built-in Matlab editor “the best editor for Matlab.” In fact, I like the built-in Matlab editor a lot, but Emacs allows me to handle C, VHDL, assembly, and Matlab code and write a paper in LaTex all within the same application. Not only that, but I can tailor Emacs to behave consistently for all these targets.
I’ll stick with R2008b and cross my fingers that MathWorks will release future Matlab versions with EmacsLink.
I think Eric (the author of the new MATLAB-Emacs integration) would be disappointed to hear his efforts referred to as “disingenuous”. Maintaining the matlab-emacs open source project is something he does in his spare time and thus any fruit it bears is worthy of thanks.
We never saw EmacsLink as a threat. As I’ve said before, there was a legacy architecture on which EmacsLink relied which was lowering the overall maintainability of the MATLAB Editor. Much of the Editor has been re-architected, with an eye towards providing public APIs that are both polished and maintainable. There was no reasonable way to maintain the EmacsLink capability during this period of re-architecture.
P.S. the MATLAB Editor also handles C/C++, VHDL, Java, Verilog and XML/HTML.
I just started using a computer with r2009. Wow! The loss of EmacsLink is an *insufferable* take-away!
I can appreciate that you want to improve your native matlab editor. It definitely needs it. But the loss of EmacsLink feels feels like a bitter slap in the face.
Just so you can better understand your users a little better, I’ve been using emacs for better than 12 years now, and I probably use it for at least 30 hours per week. Almost all of the time, emacs is the only application I have open on my desktop. I run my shells inside emacs, and I use gud-mode constantly.
I know that I can develop in both C and Matlab many, many times faster than my peer programmers who use non-emacs IDEs, and it helps my productivity to be able to write and debug my matlab code the same way I write and debug my C code.
Forcing me to use this Matlab editor has cost me a lot of productivity! Thanks a lot, and please bring it back!
I have recently learned about ViEmu which, for Vi/Vim users, looks very interesting. I exchanged an e-mail with the developer of ViEmu who told me that it is written in a quite generic C++ code that can in principle be adapted to work with MATLAB’s editor. However he is not economically interested at this moment to undertake such an adaptation. I know that there are many out there who have been looking for ways to communicate between Vi/Vim and MATLAB (not just to edit code in Vi/Vim). I believe that the desired communication can be achieved via ViEmu. I wondered if there would be enough people really interested on ViEmu that the developer may consider to adapt ViEmu to MATLAB’s editor.
Since I started using matlab-emacs some days ago I never experienced Emacslink. But I experienced some trouble using while using “emacsclient -n” on MAC OS (Snow Leopard). MATLAB’S edit.m (that is the script running if you type “edit “) uses the unix command ” “which” “emacsclient -n” ” trying to get the path to the emacsclient script, but MATLAB won’t find a “emacsclient -n” script. Eventually I received the MATLAB error “Could not find external editor”.
I edited edit.m as a workaround. But this is not a nice way. I would be happy if someone has a better solution!
I, like Eric, use Emacs for the majority of my analysis/development tasks (have for a long time). This is not going to change. I will never go back to using a separate editor/IDE for every type of development I do, and the Matlab editor is not the answer. I love Matlab, but this sort of productivity impairment is a big deal to me. It only pushes me further towards using Python+SciPy for analysis/development – it seems to be only a matter of time before the Open Source Python+SciPy combination replaces Matlab completely for me.
I’d like to add my name to the chorus of people who want to see Emacslink returned. Being able to debug from within emacs on a Windows machine is such a powerful thing. I plan to hold off upgrading in hopes of the return of Emacslink functionality on Windows.
At the very least opening it up to the users to support would be a useful gesture. Of course, I’d like to see things added by Matlab and the community to make this tool even more powerful (such as windows console mode and integration into the org-babel literate programming framework).
Thanks a lot!
This was awfully useful.
Just a question: how can I terminate a running script in emacs, i.e. what’s the corresponding control-C Matlab command in matlab-shell?
Thanks a lot,
I have one problem: on Mac I can edit the function through the edit command however I don’t get the file loaded in emacs when I click on a function link in a warning or error in matlab. Is there a way to fix this?
Also. when I try to load the m-lint mode I get a “Cannot open load file: linemark”…any help?
Maybe someone following this post or on the newsgroup can help you with questions in comments #10 and #12.
The error hyperlinks call the opentoline function. If you want them to open in another editor, you can manually edit that file and replace the calls to the MATLAB Editor with system shell commands that launch that file wherever you please (just save a backup copy first, just in case).
Dunno if anyone’s paying attention to this thread anymore – but I have a problem with emacsclient. It works fine if there’s an emacs window already open, but fails to open anything if the process isn’t already alive. Is this by design or am I doing something wrong?
If anyone is interested – I figured out the solution to my problem. The editor in the MATLAB preferences should be:
emacsclient -a emacs -n
So if there’s no current emacs server, it’ll open a new emacs window.
I couldn’t get emacsclient to work on Matlab 7.5 (R2007b) running on Windows. Whenever I tried editing a file using
a Command Prompt window would open up with an error message saying:
'"emacsclient -a emacs -n"' is not recognized as an internal or external command, operable program or batch file.
I knew that it wasn’t an issue with emacsclient because I could open the file from the Windows command prompt without any errors.
After snooping around in the edit.m file, I figured out that the problem stemmed from the fact that edit.m wraps calls to user-supplied external editors in double quotes “in case it contains spaces.” Of course, when you’re trying to use the -a or -n option with emacsclient, this wrapping in double quotes confuses Windows, which tries to interpret the entire string as an executable rather than parsing it into an executable (emacsclient) plus arguments (-a emacs -n).
I was able to make it work seamlessly by changing lines 220-227 in the openExternalEditor function from this:
if ispc % On Windows, we need to wrap the editor command in double quotes % in case it contains spaces if nargin == 0 system(['"' editor '" &']); else system(['"' editor '" "' file '" &']); end
if ispc % We don't want to use double quotes since our editor % command contains arguments, and the & is unnecessary if nargin == 0 system(editor); % but we do still need to wrap the file in double % quotes, in case it includes a path with folder names % that have spaces... else system([editor ' "' file '"']); end
I’m not sure whether this would be an issue for other versions of Matlab on Windows, but I figured I’d pass along the info in case it helps someone else!
Why not add a public API so people can reimplement EmacsLink on top of it? By removing EmacsLink you cause a lot of pain for a lot of hardcore Matlab users and thus Mathworks clients. The Matlab Editor is just a pain to use for people used to Emacs and well at least under Linux it looks ugly like hell.
Until you bring EmacsLink back or at provide least a public API that allows to reimplement EmacsClient I’ll try everything to avoid Matlab!
Hi Mike, thanks a lot for your great article! I set up my emacs according to your article and now I am able to use matlab-shell. It is much more convenient. However every time I run matlab-shell I would get this information:
if usejava(‘jvm’), com.mathworks.services.Prefs.setBooleanPref(‘EditorGraphicalDebugging’, false); end
In my .emacs file, I put:
(setq matlab-shell-command-switches ‘(“-nosplash” “-nodesktop” “-nojvm”))
but it doesn’t work.
Any idea how I should deal with it? Thank you so much!
Is emacslink still unavailable? I am using R2010b.
I’m trying to use emacs 23.3.1 (cygwin) with matlab and matlab-shell doesn’t work. I suppose this is the same reason as stated above in general for any Windows user.
I echo George’s feelings exactly: I will never go back to using a separate editor/IDE for every type of development I do, and the Matlab editor is not the answer. Hmm.., GNU-Octave has a nice emacs mode…
I am also curious to hear about a new matlab.el lisp file for Emacs. Any news regarding a new version for emacs 23.3 or newer? I would never use the built-in crippled limited pseudo-emacs in matlab, but I and my entire research team will be perfectly happy to continue to work with the usual matlab-code-mode in Emacs.
I didn’t even find a proper website to download the matlab.el – what do i miss here ?
For those tyring to get this working under mac osx, there are two things I needed to do. OSX does not define the PATH variable as in other *nix and even setting it in my environment.plist did not do it (though maybe I did not get that syntax right). But by modifing
(defcustom matlab-shell-command "matlab" .... to be (defcustom matlab-shell-command "/Applications/MatLab/MATLAB_R2011a.app/bin/matlab" ....
I was able to get it to run properly
Should have been clear.. the above is to get matlab-shell under emacs to work, not emacslink. But with the shell running under emacs you can go back and forth between code and execution, debug code, etc.. Graphics windows show up separately but the rest of the interface is inside an emacs shell window.
You can specify which options to send to matlab by adding
(custom-set-variables '(matlab-shell-command-switches '("-nodesktop -noslpash -nojvm")))
to your .emacs.
It’s been 5 month but hope you’ll come across this/figured it out.
I use emacs at about 180 chars width.
When using matlab-shell mode I can define a string variable “foo” up to that width s.t.
returns the full string unwrapped.
However,when I query a vector or matrix “test”
matlab wraps the display at column 70
That seemed like a good clue and it suggested this was more of a matlab inside emacs problem than an emacs problem, but I haven’t figured out how to configure emacs to understand the terminal width when it’s running inside emacs..
(defcustom matlab-fill-fudge-hard-maximum 150
inside of matlab.el
Can anyone help ?
I’ve been using your script opentoline (slightly modified) to interact with vim. It worked perfectly with matlab 2010, but not with matlab 2011b. Clicking on a “error line link” opens an instance of the matlab editor. The script opentoline is not called.
Has anybody manage to get it to work with version 2011b?
Thank you for your help
I’m replying to my previous post.
With newer matlab version, one should override the file errorDocCallback.m since opentoline.m is not called anymore.
See my bug report here:
Great work! I’m really enjoying using this. Quick question though, is there a simple way to run multiple concurrent matlab sessions?
ESS provides this functionality by repeatedly invoking the shell launcher, and then offers a function (ess-switch-process) to define which shell regions, lines, etc, will be sent to during execution. There’s some treatment of it here http://stackoverflow.com/q/4504244/288545
I’m curious if something similar is possible with matlab-mode for emacs. Thanks!
@Codre (Comment #24):
Have you (or anyone else for that matter) found a solution to your question with too short line wrapping in matlab-shell output? I have started using this package and really like it, but am finding the inability to change the output fill width similarly frustrating.
It seems like changing the MATLAB setting ‘CommandWindowSize’ (from [80 25] to [130 25]) might do the trick, but I have been unable to edit that setting in MATLAB or change how it gets initialized. I am using MATLAB R2012a and emacs 23.1.1 on Linux.
But mostly, thanks to Eric for his excellent work!
I have a partial solution to changing CommandWindowSize from the default. Create a shell script that sets stty rows and columns to better quantities then calls MATLAB (passing along arguments). Then customize matlab-shell-command to call this script instead of matlab. This only changes the initialization of CommandWindowSize; I have not found a way to update this parameter dynamically.
Being a matlab user for over 20 years, I just now installed Aquamacs (GNU Emacs 220.127.116.11) and wanted to try editing, debugging and running m-files from this editor. When I open an m-file, it recognizes it as a matlab file and inserts a MATLAB main menu pick. When I drill down into this, there is the menu line “Start Matlab”, but no joy, it cannot find the matlab executable.
I am absolutely new to emacs/Aquamacs, and would like an “Idiot’s Guide” to configure the matlab mode properly. I know Linux/Unix well, but am not experienced as a Mac OsX pilot.
I am using Mountain Lion and Matlab R2012b.
If the solution is RTFM, I would like to know which and where to find it.
I’ve been using this for a while, and I’m experiencing the matlab shell interaction slowing down dramatically (almost unusable) when the shell buffer becomes quite large (around 20.000 lines). Somebody with the same issue? Any suggestion to fix this?
My understanding is that the MATLAB mode should activate auto-complete when editing m-file. Correct? My auto-complete does not seem to be working while editing m-file. It works when using the matlab-shell though. Any suggestions?
Is the old EmacsLink still available for download somewhere?
Love this but it is very slow…. any suggestions on mitigating this problem?
For anyone who has questions/issues regarding MATLAB-Emacs, I’d suggest that you send an email to the mailing list: email@example.com
I just upgraded to R2013a and the change Dylan made to edit.m (http://blogs.mathworks.com/community/2009/09/14/matlab-emacs-integration-is-back/#comment-7430) for Windows compatibility broke. You can fix it though! Modify your edit.m, in the resolvePath() function:
[classInfo, whichTopic] = helpUtils.splitClassInformation(argName, relativePath, true, false);
should be changed to
[classInfo, whichTopic] = helpUtils.splitClassInformation(argName, relativePath, false);
Hope this helps anyone else that recently upgraded to R2013a and broke emacs support in the process.
1. Are there any plans to add tty command window support for Windows 7 and later platforms (64 bit) – thus allowing users forced to work on Windoze platforms to access matlab-shell mode within emacs?
2. Perhaps a connection routed through cygwin might be possible – with Cygwin providing the shell capability instead of Windoze?
Yes, this would make the system dependent on a fourth product. But it seems like we’ve already crossed the “dependent on another product we don’t control” line, since emacs’ matlab-shell mode already requires CEDET, right?