This is a heads up that I've pushed some commits that implement asynchronicity in package.el. I'll explain implementation details below, but I want to list the surface changes first.





- New variable `package-menu-async'. If this is non-nil the package menu uses asynchronous operations when refreshing the archives and when installing packages. For the purpose of testing on the devlist, I've set the default to t. We can discuss whether we prefer this on or off when Emacs gets released.





- For the sake of simplicity, when you hit `x' in the package-menu you will no longer get two separate prompts for install/delete. You'll be prompted a single time for everything.





- If you don't use the package-menu, nothing has changed on the surface. That is, if you invoke `M-x package-install' or call this function with a single argument everything will be synchronous. But the implementation is there (determined by the function's 3rd and 4th args), so we could use the prefix arg to specify async here.





Cheers to all,



Artur





-----



Implementation (for those who care)

-----





- Most functions which involve downloading data now take an extra optional ASYNC argument (some of them also take an additional CALLBACK argument). This defaults to nil. If it is t, any downloads involved are performed asynchronously (and, if appropriate, CALLBACK is called afterwards).





- The only really async function (actually a macro) is `package--with-work-buffer-async'. All other functions simply propagate their ASYNC argument down to this one. If ASYNC nil, it just defers the work back to `package--with-work-buffer'.





- Archives are refreshed all at the same time (which leads to a signficant speed boost if you have several archives configured), so there's a new variable `package--downloads-in-progress' to keep track of which archive downloads are still ongoing. The function `package--update-downloads-in-progress' takes care of controling this variable and calling a relevant hook when it's all done.





- Package downloads are performed in sequence, because it is generally not safe to do them in parallel (and deciding when/how it is safe is complicated). So there's no variable to keep track of them. `package-menu--perform-transaction' takes care to call `package-install' on one package at a time (and possibly calls `package-delete' afterwards). In turn, `package-install' takes care to install everything in the order specified by `package-compute-transaction' (which ensures dependencies come before the package itself). This is all done with recursive callbacks.

