38
$\begingroup$

Mathematica 10 has introduced file name completion for the arguments of certain built-in functions, such as Import, SetDirectory, ReadList, etc.

Is it possible to add file name completion or other argument completion for user-defined functions?

For example,

readCSV[file_] := Import[file, "CSV"]

I would like file name completion to be triggered after typing readCSV["...

$\endgroup$
  • $\begingroup$ Link to W Community version $\endgroup$ – Szabolcs Aug 8 '14 at 18:37
  • $\begingroup$ In the case we have optional argument and there is a .m file with the options according to this answer on the Prompt a set of possible options, how would it be possible to achieve string autocompletion on my custom function ? $\endgroup$ – Athanassios Dec 14 '15 at 14:11
  • $\begingroup$ @Athanassios Sorry, I do not know the answer to that. I don't really like to customize Mathematica to such an extent by editing installation files. It seems that autocompletion can only be customized by editing installation files (though I might be wrong). $\endgroup$ – Szabolcs Dec 15 '15 at 11:30
33
$\begingroup$

There is an undocumented file in the installation directory named specialArgFunctions.tr:

NotebookOpen @ FileNameJoin @
  { $InstallationDirectory, "SystemFiles", "FrontEnd", "SystemResources"
  , "FunctionalFrequency", "specialArgFunctions.tr"
  }

This file describes in detail how to attach completion actions to each parameter of listed functions. For example, it contains the entry:

"Import"->{2, "ImportFormats_Names.trie"},

and explains that 2 specifies absolute pathname completion for the first argument, and that the second argument should be completed from a compiled list found in the file ImportFormats_Names.trie in the same directory.

So, we can achieve the desired goal by adding the following entry for readCSV:

"readCSV"->{2},

filename completion screenshot

The rules use symbol names unqualified by context. Thus, they apply equally well for symbols in any context. In fact, experimentation shows that the parameters of qualified symbols are not completed, even for the shipped rules (e.g. try completing System`Import["c:\\).

As usual, the undocumented nature of this feature means that it could change at any time.

$\endgroup$
  • $\begingroup$ +1 Great! It would be nice if there was some kind of fileplaceholder that one could put in the usage message in the function template $\endgroup$ – Rojo Aug 10 '14 at 1:00
  • $\begingroup$ This is fine if you need file-completion, what about string auto-completion from a list of defined possible options for a custom function, see my question above ? $\endgroup$ – Athanassios Dec 14 '15 at 14:15
  • $\begingroup$ @Athanassios specialArgFunctions.tr shows an example for a function with a hard-coded list of acceptable values for the first argument: "MyPlanetInfo"->{{"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Uranus", "Neptune"}} $\endgroup$ – WReach Dec 14 '15 at 15:29
  • $\begingroup$ @WReach I played a bit more with auto-completion feature and I noticed that when you define an enumerated list of options, in a .m file according to this (mathematica.stackexchange.com/questions/78935/…)How to Answer, then string auto-completion is not needed because the drop-down list is filtered automatically as you start typing the name of the option, e.g. com->getD.... and drop-down list displays only "getDatabase". $\endgroup$ – Athanassios Dec 15 '15 at 15:25
  • 2
    $\begingroup$ @Athanassios Yes, the method in (78935) enables autocompletion for option arguments, whereas the method here using specialArgFunctions.tr enables autocompletion for regular (non-option) arguments. $\endgroup$ – WReach Dec 15 '15 at 16:50
20
$\begingroup$

Before you start using this, be aware that this is all undocumented and unsupported functionality. It may change at any time, it may crash Mathematica, and it may bite you when you least expect it. I wouldn't be surprised if it turned out that incorrect use messes up the internal state of the front end. Use at your own risk.

I tried the examples I show here in M10.0.2 and M11.0.1. I assume it also works in inbetween versions.


We can add custom completion to our own functions this way:

addCompletion = FE`Evaluate[FEPrivate`AddSpecialArgCompletion[#]] &

addCompletion["readCSV" -> {2}]

addCompletion takes an argument of the form "functionName" -> {a1, a2, ...}. "functionName" is a string containing the name of the function to use completion for. a1, a2, ... are argument specifiers that control how auto-completion is done for the first, second, etc. arguments.

Argument specifiers can be:

  • A numeric code with the following meanings:

    Normal argument     0
    AbsoluteFilename    2
    RelativeFilename    3
    Color               4
    PackageName         7
    DirectoryName       8
    InterpreterType     9
    
  • A list of strings. Each string will be a possible completion for that argument.

  • A string containing a keyword referring to an internal list:

    "Style"
    "ScreenStyleEnvironment"
    "PrintingStyleEnvironment"
    "MenuListStyles"
    "MenuListScreenStyleEnvironments"
    "MenuListPrintingStyleEnvironments"
    "codingNoteFontCom"
    "ExternalDataCharacterEncoding"
    "MenuListPalettesMenu"
    "MenuListStyleDefinitions"
    "ConvertersPath"
    "MenuListDisplayAsFormatTypes"
    "MenuListConvertFormatTypes"
    "MenuListCellTags"
    "MenuListWindows"
    "MenuListHelpWindows"
    "MenuListPackageWindows"
    "MenuListPaletteWindows"
    "MenuListPlayerWindows"
    "MenuListStylesheetWindows"
    "MenuListTextWindows"
    "MenuListFonts"
    "MenuListGlobalEvaluators"
    "MenuListNotebookEvaluators"
    "MenuListStartEvaluators"
    "MenuListQuitEvaluators"
    "MenuListNotebooksMenu"
    
  • Some other forms for argument specifiers are described in specialArgFunctions.tr, see References below


Example

A custom myImport function could be set up like this:

addCompletion["myImport" -> {2, $ImportFormats}]

enter image description here


References:

$\endgroup$
  • $\begingroup$ Do you have any idea what Color is supposed to do? $\endgroup$ – b3m2a1 Sep 17 '17 at 23:10
  • $\begingroup$ Also on 11.2 "MenuListHelpWindows" throws a completion error (I only point this out because it's worth noting for other people that--being undocumented--not all of this is assured to work properly or at all). $\endgroup$ – b3m2a1 Sep 17 '17 at 23:19
  • $\begingroup$ It might be worth noting that your "functionName" can be a fully-qualified name. E.g. addCompletion["PkgCont`func" -> {{"A1", "A2", "A3"}}] will only respond when the FE sees "PkgCont`func" and not just "func". $\endgroup$ – b3m2a1 Feb 11 '18 at 22:28
  • $\begingroup$ Oh and another thing I just found: you can autocomplete to a List. e.g. addCompletion[ "asd" -> {{"{\"Gravity\", \"Iowa\", \"UnitedStates\"}"}}] will turn that into a proper List rather than injecting it as a String. I haven't been able to get it to work for other types though. $\endgroup$ – b3m2a1 Feb 11 '18 at 22:39
5
$\begingroup$

This can be accomplished with the AddCodeCompletion function in the function repository.

Evaluate the following piece of code:

AddCodeCompletion = ResourceFunction["AddCodeCompletion"]
AddCodeCompletion["readCSV"]["AbsoluteFileName"]

readCSV will now auto-complete absolute file paths. AddCodeCompletion can be used with relative filenames as well.

Note: AddCodeCompletion function uses FEPrivate`AddSpecialArgCompletion just like Szabolcs' answer to this question.

$\endgroup$
  • $\begingroup$ My guess (haven’t looked at the source) is that this function is actually less useful than the FEPrivate one as the FEPrivate call can do completions for many functions at once whereas many FR functions seem a little half-baked and thus likely do not have the edge cases like that. $\endgroup$ – b3m2a1 Apr 23 at 1:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.