53
$\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$
3
  • $\begingroup$ Link to W Community version $\endgroup$
    – Szabolcs
    Aug 8, 2014 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$ Dec 14, 2015 at 14:11
  • 1
    $\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, 2015 at 11:30

3 Answers 3

45
$\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$
6
  • $\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, 2014 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$ Dec 14, 2015 at 14:15
  • 1
    $\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, 2015 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$ Dec 15, 2015 at 15:25
  • 3
    $\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, 2015 at 16:50
31
$\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$
5
  • $\begingroup$ Do you have any idea what Color is supposed to do? $\endgroup$
    – b3m2a1
    Sep 17, 2017 at 23:10
  • 1
    $\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, 2017 at 23:19
  • 2
    $\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, 2018 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, 2018 at 22:39
  • $\begingroup$ Do you know how to get the auto-complete list for unit names? (see my question) $\endgroup$
    – user13892
    Aug 7, 2021 at 23:04
12
$\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$
2
  • 1
    $\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, 2019 at 1:12
  • $\begingroup$ The problem with this is that one would want auto-completion for a package. Using a resource function in a package makes it depend on some external resource the package author has no control over, and also requires an internet connection. I would not recommend using this for package authors, but looking at the source code can be instructive. $\endgroup$
    – Szabolcs
    Mar 2, 2020 at 19:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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