# Sub-packages and auto-completion

Posted 2 years ago
1853 Views
|
2 Replies
|
7 Total Likes
|
 Cross-posted on Mathematica.SE I have a Mathematica application that consists of two sub-packages, corresponding to the contexts foo (foo.m) and foob (b.m). Some of the definitions in foo.m rely on functions in b.m. Therefore b.m must be loaded before foo.m in some way (there are multiple ways to achieve this).If I do this, auto-completion will be available for foo symbols, but not for foob symbols. Why? How can I enable auto-completion for both sub-packages? Actually, completion for foob symbols works when requested explicitly with Command-K, but the completion window doesn't pop up automatically.If the loading order is reversed, i.e. load foo first, then foob, then everything is fine. But I cannot do that because of the dependency structure. Here's the package source, for convenience: https://www.dropbox.com/s/z6eoxumeqd42411/foo.zip?dl=0The directory structure looks like this:And here's the file contents: (* init.m *) Get["foob"] (* Must be loaded first in some way because foo.m uses it. *) Get["foofoo"]  (* foo.m *) (* Normally, BeginPackage would refer to foob in its second argument. Since in this basic example foo doesn't actually use foob, I removed this to demonstrate that the problem isn't caused by it. *) BeginPackage["foo" (* , {"foob"} *)] TheName::usage == "TheName[]"; Begin["Private"] End[] EndPackage[]  (* b.m *) BeginPackage["foob"] TheOtherName::usage == "TheOtherName[]"; Begin["Private"] End[] EndPackage[] If I load foo (which in turn loads foob as well, through init.m), TheOtherName is not offered for completion.I need a solution where one sub-package can be dependent on the other, but auto-completion works for both. If I change init.m to Get["foofoo"] Get["foob"] (i.e. I exchange the order of the two Get commands), then auto-completion works fine. I do not want to do this because in my real use case, foo depends on foob, therefore foo.m would need to load b.m in some way. A second Get["foob"] after this would cause double-loading of b.m, which is ugly and slow. These are large packages and the slowdown is actually noticeable on a Raspberry Pi.If I use Get["foob"] Get["foofoo"] or Get["foofoo"] Needs["foob"] to prevent double-loading, then auto-completion is broken again.I am hoping to find out what precisely in Get["foob"] re-enables auto-completion and re-create that thing in isolation without actually re-evaluating all definitions from b.m.
Answer
2 Replies
Sort By:
Posted 2 years ago
Answer
Posted 2 years ago

So I can provide some clarification and a workaround

### Clarification

First off, this only triggers on the EndPackage:

For example, this still allows ggg to autocomplete:

BeginPackage["fooa"];
ggg::usage = "asdasd";
EndPackage[];

(*Break this into different cells or the FE acts like EndPackage was called!*)
Abort[]

BeginPackage["foo", {"fooa"}];


But the moment you call EndPackage[] ggg stops autocompleting.

Further investigation shows that even simply messing with the $ContextPath is enough to do it. BeginPackage["fooa"]; ggg::usage = "asdasd"; EndPackage[]; (* again, split these into two cells *) PrependTo[$ContextPath, "foo"];


Next, this does not seem to have to do with the standard way the FE handles autocompletions (as I know it at least).

I say this because the following doesn't prevent it from auto-completing (working from a Quit kernel):

BeginPackage["fooa"];
ggg::usage = "asdasd";
EndPackage[];

FrontEndExecute@
FrontEndUpdateKernelSymbolContexts[
"foo",
Join[
{"foo", "fooa"},
$ContextPath ], {{"foo", {"aaa"}, {}, {"aaa"}, {}}} ]  And even more to the point, this isn't enough to preserve the autocompletion: BeginPackage["fooa"]; ggg::usage = "asdasd"; EndPackage[]; (* Split the cell here *) InternalSymbolList[False] (* And further split here *) BeginPackage["foo"]; EndPackage[] (* Make sure to call InternalSymbolList[True] after trying this *)  why this happens is something I haven't been able to figure out. This behavior is a lot like the behavior involved in developerFunctions.m. There doesn't seem to be anything in NeedCurrentFrontEndSymbolsPacket to explain it. ### Workaround Since this triggers on $ContextPath edits, you simply need to edit the \$ContextPath again.

This will recover the auto-completion:

BeginPackage["fooa"];
EndPackage[];


So after you load your packages, you can use that to get your autocompletions back.

Answer
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments