# Sub-packages and auto-completion

Cross-posted on Wolfram Community

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=0

The 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"]


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.

• @Kuba What I said was not correct. The problem isn't simply caused by BeginPackage. It is somehow dependent on the loading order, or the creation order of the contexts. My suspicion is that when the context foo  is created, all of its subcontexts are removed from auto-completion. Or something like that. I'm not sure. I updated the question to clarify. – Szabolcs Dec 21 '17 at 10:03
• The only solution I could find so far was to factor out the dependencies into a third sub-package which won't be added to the $ContextPath. – Szabolcs Dec 21 '17 at 10:33 • Ok, thanks for the update, will take a closer look later. (deleting old comment) – Kuba Dec 21 '17 at 19:58 • Could you please show the results of Context[TheName] and Context[TheOtherName] ? – Wen Chern Dec 22 '17 at 7:51 • @WenChern The contexts are as expected: fooTheName and foobTheOtherName. – Szabolcs Dec 22 '17 at 9:25 ## 1 Answer 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[];