Setting desktop tab completions

This site has lately focused on quite detailed Java-related topics. Next week I will present the promised EDT article, which will dive into even deeper Java territory. So I thought to take a short break and present an entirely pure-Matlab non-Java undocumented feature, which is simple and yet quite useful.

Apparently, Matlab has a file called TC.xml in its [matlabroot '/toolbox/local/'] folder that contains the definitions of the tab-completable functions and their arguments. In order for a user-defined function’s arguments to support tab-completion, a new entry needs to be added to this XML file.

TC.xml & TC.xsd

The full syntax of the TC.xml file can be found in the TC.xsd file, which is located in the same folder as TC.xml. Here are some sample definitions from my TC.xml file (which might vary across Matlab releases):

The first example defines that an unlimited number of addpath arguments are all of type DIR. Therefore, when completing any argument of this function in the Command-Window, Matlab will present only relevant DIR (=folder) elements in the pop-up window (lexically sorted):

Tab-completion of type DIR

Similarly, help defines all its arguments to be a function or sub-function type, so the popup-up will only be populated with the function names currently visible in the desktop:

Tab-completion of types FUN & SUBFUN

Similarly, clear defines all its arguments as function names or variables. Note that the list of available functions and variables may change depending on the current execution stack position. The full list of supported types is defined in the TC.xsd file. It is: VAR, FUN, SUBFUN, DIR, FILE, MFILE, MATFILE, FIGFILE and MDLFILE. Addendum: Matlab release 7.10 (R2010a) added the MCOSPCG and MCOSCLASS types; release 7.13 (R2011b) added the MESSAGEID type.

The whos function defines all its arguments as VAR, except the single MATFILE argument that follows a ‘-file’ argument (look at whos‘s help page to understand why).

The open function defines tab completion only for its first argument (with plenty of possible types…). Likewise, openfig defines its first argument as a FIGFILE, and its second as VAR with a few extra special-purpose strings that are added to the popup-up menu.

Finally, the mlint example shows that multiple arguments can be defined using a single XML definition element. In this case, args #2-10 are defined as VAR (with three extra special-purpose strings), while args #1 and #11+ are defined as FUN.

The careful user can edit the TC.xml file using any text editor (I strongly suggest saving a backup first):

edit(fullfile(matlabroot,'toolbox/local/TC.xml'))

User-defined functions can easily be added to TC.xml, and we can even add/modify the built-in Matlab functions that are already defined. Note that changes to TC.xml only take effect after a Matlab restart. From then on, all future Matlab sessions will use the modification, so a really simple one-time edit can improve our workflow for a long time – at least until we upgrade Matlab, when we’ll need to redo our edits…

TabComplete utility

In order to facilitate TC.xml editing, I have created a utility called TabComplete, which is now available on the Matlab File Exchange. The use of this utility is very simple. For example:

tabcomplete test file 'DIR +data -data no_data'VAR

defines a user-defined function test that accepts a FILE argument, followed by a DIR argument with three special-purpose strings, followed by any number of VAR arguments. If I wished to define specific argument types without any default type, I would use:

tabcomplete test file 'DIR +data -data no_data'''

Using TabComplete for user-defined functions

Addendum: Matlab releases 7.10 (R2010a) through 7.13 (R2011b) have a bug that causes Matlab to enter an endless loop (full CPU load) whenever tab-completion is requested for an argument that has possible values that are not simple terms. In the case above, “+data” and “-data” both cause this abnormal behavior. In such cases, the only remedy is to kill the Matlab process via the OS’s task manager. In Matlab R2010a-R2011b, I therefore suggest to use only simple values. This bug is apparently fixed in R2012a, making non-simple terms safe to use again. I take at least partial credit for this, having reported this bug to Mathworks in August 2011 (1-FCGDEI).

TabComplete can also be used to retrieve the current list of tab-completion definitions:

TabComplete has a few limitations: it does not support the -previous option described above (you can do this by manually editing TC.xml). There are also some inherent limitations in Matlab’s TC functionality: changes take effect only after a Matlab restart (there might be a way to reload the definitions in the current Matlab session, but I do not know of any); the list of standard types cannot be modified; and the default type does not support extra special-purpose strings as do the numbered arguments.

There is another very annoying limitation: by default, TC.xml only supports lowercase function names. This is stupid, since Matlab has many function names with UPPERCASE characters, and certainly user-defined function names also do. Luckily, this last limitation can easily be overcome by editing the TC.xsd file (note that this is the TC.XSD file, not the TC.XML file). Instead of:

34 Responses to Setting desktop tab completions

Thanks for posting this great utility! Seeing your question dialog and looking through the code, I saw your use of the function “setpref.” I didn’t know about this very useful function, so thanks for that too!

Hi, thanks for inspirational blog spot. Have you got any idea if it is possible to save TC.xml to any other location, where the Matlab path is set? It can be useful in case that I have not permission to modify TC.xml in [matlabroot '/toolbox/local/'] folder, or if I distribute own toolbox and can’t modify default TC.xml:). BTW thank you for link. Best Michal

A related question, which however is not tab completion, but presents informaiton is the same way:

When in the workspace I type e.g. “plot(” or “corrcoef(” and wait a second, I am presented with a context sensitive help showing a number of ways to use the “plot” or “corrcoef” functions. Where is this context sensitive help stored? I have tried to look at different functions to see how the help-section is written, and made a similar setup:

function testHelp(x,varargin)% TESTHELP See how context help is defined% TESTHELP(X)%% TESTHELP(X,Y)

@Henrik – I believe the syntax help is taken from the “Syntax” section of the relevant function’s doc page (the HTML webpage that is presented as a result of the doc function).

If no doc page is defined, then the help-tooltip popup displays the arguments defined in your function’s declaration. In your example, testHelp is declared as having arguments “x” and “varargin”. “varargin” is always converted to “…”, so your tooltip will say: testHelp(x,…). If you wish to modify this, then specify meaningful argument names (which is always a good thing to do), and/or create a doc page.

I tried to implement on R2013a a custom doc page but couldn’t get the desired result. Even if the section is title ‘Syntax’, I still get the ‘…’ as a hint. If anybody finds a workaround please post it and in the meantime submit a request to TMW for custom syntax hints. Hopefully, with enough requests we will see it in R2013b.

This is only tangentially related… but I’m hoping there is an undocumented way to change the fact that Matlab Tab completes case-insensitively but doesn’t auto-replace the name when it finds the wrong case. This results in tab-completions to functions that error.

I can have auto-completion on the prompt. So on the prompt, when I type: >> myP<tab>.myF<tab><space>myF<tab> I can now autocomplete myF to myFile but some how Matlab doesn’t push the string literal myFile as an argument to myPack.myFun but instead gives an error:

Error: Unexpected MATLAB expression.

Of course if I call myPack.myFun(‘myFile’) it works fine. My conclusion is that command-syntax doesn’t work with packaged functions but of course function syntax does.

I opened a ticket with Mathworks support but they said this functionality is not supported at this point. My general feeling is that packages are pretty half baked at this point. (also Ctrl-D on imported functions doesn’t work etc.)

@Marc – “ClassName” is not one of the acceptable ctype enumerations, explaining why your TC broke. You need to use “MCOSPKG” and/or “MCOSCLASS” to signify that the first arg needs to be a class object.

This is very neat I didn’t know that exist. I did it for the fieldnames but failed for methods so far.

“methods” seems to behave differently depending on nargout. Zero output should not matter in this case single output gives back names in cell’s and double output the same again as well as some meta-data cell matrix which I don’t understand fully (and searching in google for function methods doesn’t really help^^).

I have a related, seemingly-trivial question. I was wondering whether there’s any way to disable tab auto-complete altogether outside of a GUI interface.

I often need to work through a shell mode command line on Unix. If I copy-paste blocks of code from my desktop editor, whenever there is a tab in the original code, I get a “no completions found” output, which sometimes renders the output illegible.

I was not able to find any documentation of discussions on how to do that.

Thank you for responding so quickly— Let me make myself clearer: I am on the Unix command line and I am not using a GUI. I am trying to find a way to get the same result outside of the GUI platform. Is there any hope?

Thanks! I understand now that you previously were indeed referring to command line preferences control, so you did get me right. I will follow your advise. If it works it would save me infinite irritations…

Unfortunately it doesn’t do what it should. I changed the matlab.prf file as instructed, restarted Matlab, but the “no completions found” feedback still appears following tabs. Is there anything else to try before giving up?

Yair Altman (1 day 12 hours ago): @Chad – Matlab uses an opaque panel for displaying Java components, so even if the component is made transparent, it would still just show the opaque panel beneath it....

Chad (1 day 21 hours ago): Hi Yair, Thanks for your book and blog on using java with Matlab. I am using the dial gauge from jfreechart, and I’m overlaying multiple gauges in my UI layout to give a more...

Richard (6 days 0 hours ago): Running R2015a, I have what may be a related issue, but I’m not sure. Simply put java callbacks appear to be suppressed when changing the stacking order of components in a...

Yair Altman (10 days 3 hours ago): @Mark – indeed, an internal bug in Matlab causes the minimal line width to be apparently 0.75. The export_fig utility works-around this bug and exports a file (EPS/PDF)...

Yair Altman (10 days 3 hours ago): @John – yes. You can export to EPS (vectorized format) by specifying a file name ending in “.eps”, or by using the “-eps” input parameter.

Yair Altman (10 days 3 hours ago): @David – I was (and am) not aware that this violates any license agreement. I am an engineer and not a lawyer. If anyone things that it violates the license then they...