- Undocumented Matlab - https://undocumentedmatlab.com -

Setting desktop tab completions

Posted By Yair Altman On March 3, 2010 | 37 Comments

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.
A few months ago, a CSSM reader asked [1] whether it is possible to customize Matlab tab-completion [2] for user-defined functions (see related [3]). A similar question on StackOverflow provided the necessary solution lead [4]:
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
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
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 [5] 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 [6] 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 [7]. 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
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:

>> definitions = tabcomplete;
>> definitions(1)
ans =
    functionName: 'addpath'
     defaultType: 'DIR'
     extraValues: ''
        platform: ''
    functionArgs: []
>> definitions(54)
ans =
    functionName: 'openfig'
     defaultType: ''
     extraValues: ''
        platform: ''
    functionArgs: [1x2 struct]
>> definitions(54).functionArgs(1)
ans =
    previousArg: ''
        argType: 'FIGFILE'
    extraValues: ''
>> definitions(54).functionArgs(2)
ans =
    previousArg: ''
        argType: 'VAR'
    extraValues: 'new visible invisible reuse'

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:


  
    
  

Change the xsd:pattern definition element to:

    
    

(note the way comments can be added to the XSD/XML files)

Addendum: Matlab release 7.11 (R2011a) has fixed this XSD definition; perhaps due to this article πŸ™‚

P.S. an entirely different customization, for user-defined class members, was presented by Michal Kutil [8].

Categories: Desktop, Medium risk of breaking in future versions, Undocumented feature


37 Comments (Open | Close)

37 Comments To "Setting desktop tab completions"

#1 Comment By David On March 3, 2010 @ 10:43

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!

#2 Comment By Michal On March 4, 2010 @ 12:42

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

#3 Comment By Yair Altman On March 4, 2010 @ 15:00

@Michal – unfortunately, I don’t know of any other possible location. As far as I know, Matlab directly opens [matlabroot ‘/toolbox/local/TC.xml’]. We can’t win ’em all…

In your toolbox, try modifying TC.xml, with a graceful degradation in case this fails. Something like this:

try
   tabcomplete(...);
catch
   oldFname = fullfile(matlabroot, 'toolbox/local/TC.xml');
   newFname = fullfile(pwd,'TC.xml');
   msgbox(['Please ask your sysadmin to replace ' oldFname ' with ' newFname]);
end

#4 Comment By Henrik Toft On March 12, 2010 @ 02:22

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)

but it does not present me with a “similar” context sensitive help…

Cheers Henrik

#5 Comment By Yair Altman On March 28, 2010 @ 08:35

@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 [15].

#6 Comment By Oleg On June 6, 2013 @ 01:12

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.

#7 Comment By Yair Altman On June 6, 2013 @ 01:46

@Oleg – 13b is too optimistic… The development process is such that releases are finalized months before their official release. At the very earliest you will see it in 14a.

#8 Comment By akash garg On March 3, 2012 @ 10:24

is it possible to perform autocomplete in matlab without using funtionality just like we type in google search bar

#9 Comment By Yair Altman On March 3, 2012 @ 10:38

@Akash – what do you mean “in Matlab”? Do you mean the Command Window? edit boxes in GUI? combo-boxed (pop-up/pop-down menus)? each of them has a different solution

#10 Pingback By Matlab installation take 2 | Undocumented Matlab On September 24, 2012 @ 03:18

[…] check the <Tab key narrows completion> option (most useful for the desktop – see related article) […]

#11 Comment By Marshall On November 28, 2012 @ 14:24

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.

#12 Comment By Yair Altman On November 28, 2012 @ 14:28

@Marshall – I fully agree. Indeed a regrettable programming oversight. Unfortunately, I do not know any workaround.

#13 Comment By Marios On June 26, 2013 @ 15:48

Great post as always!

I modified TC.xsd file (r2013a) from:

to

In order to allow full package names to be added on TC.xml

Now the problem is that if I try to call a package level function as a script, somehow Matlab wont let me. In otherwords on the prompt:

myPackage.myFunction('str')

works fine, but:

myPackage.myFunction str

doesn’t. Is there a reason that packaged functions might not be supporting script-like calling?

#14 Comment By Yair Altman On June 27, 2013 @ 00:02

@Marios – your comment appears without the code, maybe it was stripped away for some reason. Try reposting without <, > characters

#15 Comment By Marios On June 27, 2013 @ 13:55

Sure, here are the lines again. In TC.xsd I changed:

to:

So that by adding a packaged function name on the TC.xml such as:

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.)

#16 Comment By Yair Altman On June 27, 2013 @ 14:03

@Marios – interesting. Since the tab-completion thing is internal (as in binary code, not m-code), there’s not much that we can do about this…

#17 Comment By Marios On July 2, 2013 @ 13:12

Right, there is not much we can do according to Mathworks support as well.

My partial solution is to create function aliases on a flat namespace when I absolutely need tab-completions on the desktop.

#18 Comment By Marc On November 14, 2013 @ 00:56

Hi very nice. I try to do the same for custom class definitions. For the constructor it’s straight forward but I didn’t find any solutions for methods. I tried something like:

 
  
    
    
  

(All with a smaller-as sign at the beginning but, if I print those the text is disappearing…)

But all it did is break TC. You mentioned something about a solution for custom classes but the link doesn’t seem to work. Could you elaborate a little bit more how this works?

#19 Comment By Yair Altman On November 14, 2013 @ 04:44

@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.


    
    

To limit the binding to a specific class, you could try the syntax in Marios’ comment above:

(you’d need to modify xsd:pattern to include the . character, as shown in Marios’ comment)

#20 Comment By Magu_ On February 28, 2014 @ 00:47

Hi

Great article. Can this method also be used for classes?
For the constructor it’s rather simple following your procedure. But I did fail to do so for class methods. I did post this question also on Stackoverflow ( [16]). Feel free to answer also there if you like and earn your credit.

#21 Comment By Yair Altman On March 2, 2014 @ 10:44

@Magu – try to implement hidden methods fieldnames and/or methods in your class. The first is for properties, the second is for methods.

#22 Comment By Magu_ On March 4, 2014 @ 03:07

Thank you for your answer.

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^^).

That’s my take so far:

classdef test (smaller_as) < handle
    properties
        s
    end
    methods
        function o = test()
        end
    end
    methods (Hidden)
        function out = fieldnames(o)
            out = {'x1'; 'x2'};
        end
        function [names,meta] = methods(o)
            names = {'y1'; 'y2'};
            meta = {'' '' 'test.test' '' []; ...
                    '' '' 'test.asd' '(A,B)' 'C'};
        end
    end
end

#23 Comment By Yannay On June 15, 2014 @ 12:51

Dear Yair,

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.

Many Thanks,
Yannay

#24 Comment By Yannay On June 15, 2014 @ 12:55

sorry, I meant that I was UNable to find any documentation OR discussions…

#25 Comment By Yair Altman On June 15, 2014 @ 12:58

@Yannay – You can disable command-window tab completion via the main Preferences: Keyboard/Shortcuts group – Tab Completion section – “Enable in Command Window” checkbox.

#26 Comment By Yannay On June 15, 2014 @ 13:16

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?

#27 Comment By Yair Altman On June 15, 2014 @ 13:30

Yannay – simply add the following line to your matlab.prf file (edit([prefdir,'/matlab.prf'])):

CommandWindowTabCompletion=Bfalse

(remember to restart Matlab in order for the change to take effect)

Discussion: [17]

#28 Comment By Yannay On June 15, 2014 @ 13:33

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…

#29 Comment By Yannay On June 15, 2014 @ 14:11

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?

#30 Comment By Yair Altman On June 15, 2014 @ 15:02

try replacing your tabs with spaces in the editor

#31 Comment By Yannay On June 15, 2014 @ 15:56

Yes, I was aware of this option. I am putting it off right now, and will update here if I find a solution. Many thanks for taking the time and explaining about the off-GUI preferences setting.

#32 Comment By Oleg Komarov On July 9, 2014 @ 09:45

Note that tab completion for class properties can also be achieved by subclassing the matlab.System class as I describe in my answer: [18]

#33 Comment By Yair Altman On July 9, 2014 @ 10:09

@Oleg – thanks for the cross-reference

#34 Pingback By Class object tab completion & improper field names | Undocumented Matlab On July 17, 2014 @ 11:48

[…] I described the hack for desktop tab-completion a few years ago. Unfortunately, that hack only works for functions. […]

#35 Comment By Sunke On December 11, 2015 @ 06:23

Is it possible to make tab-completion case sensitive with editing the TC.xsd file?

if the functions DOtest.m and dothis.m exist,

I want MaTlab to offer me only DOtest for the case that I enter DO[TAB]

Is this possible?

#36 Comment By tobias On December 4, 2017 @ 15:04

Hi Yair,

your article saved my fingers for years now, thank you very much!

But with R2016b I cannot find TC.xml anywhere, there seems to be a new solution for tab-completion.

It can be found under “Tab key narrows completions” in the keyboard preferences and is deactivated by default. The entry in matlab.prf can be found under “CommandWindowTabNarrows=Btrue” while “CommandWindowTabCompletion” seems to be removed/replaced.

Do you have any experience with that?

Many thanks in advance!
Tobias

#37 Comment By tobias On December 4, 2017 @ 15:14

Ok, I’ve just found your “Take 2” about that topic, thanks!


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/setting-desktop-tab-completions

URLs in this post:

[1] asked: https://www.mathworks.com/matlabcentral/newsreader/view_thread/264550

[2] Matlab tab-completion: http://blogs.mathworks.com/desktop/2007/04/27/tab-completion-will-save-your-fingers/

[3] related: http://blogs.mathworks.com/desktop/2009/08/10/tab-to-narrow-completions/

[4] solution lead: http://stackoverflow.com/questions/1842804/tab-completion-of-filenames-as-arguments-for-matlab-scripts

[5] help page: http://www.mathworks.com/access/helpdesk/help/techdoc/ref/whos.html

[6] special-purpose strings: http://www.mathworks.com/access/helpdesk/help/techdoc/ref/openfig.html

[7] available on the Matlab File Exchange: http://www.mathworks.com/matlabcentral/fileexchange/26830-tabcomplete

[8] presented by Michal Kutil: http://www.tim.cz/en/nfaq/matlab-simulink/tab-completion.php

[9] setPrompt – Setting the Matlab Desktop prompt : https://undocumentedmatlab.com/articles/setprompt-setting-matlab-desktop-prompt

[10] Setting the Matlab desktop layout programmatically : https://undocumentedmatlab.com/articles/setting-the-matlab-desktop-layout-programmatically

[11] User-defined tab completions – take 2 : https://undocumentedmatlab.com/articles/user-defined-tab-completions-take-2

[12] Setting class property types : https://undocumentedmatlab.com/articles/setting-class-property-types

[13] Setting class property types – take 2 : https://undocumentedmatlab.com/articles/setting-class-property-types-2

[14] Setting status-bar text : https://undocumentedmatlab.com/articles/setting-status-bar-text

[15] : http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_env/bruby4n-1.html#f3-40511

[16] : http://stackoverflow.com/questions/19931996/tab-completion-of-custom-class-methods-in-matlab

[17] : https://undocumentedmatlab.com/blog/changing-system-preferences-programmatically

[18] : http://www.mathworks.co.uk/matlabcentral/answers/138149#answer_144336

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.