reddit / emacs
What does "(setq package-enable-at-startup nil) (package-initialize)" in Emacs config do?
zacque0 · 2022-03-04 00:53
Hi, I encountered these two lines while reading Purcell's config. My main problem is not knowing the differences between "making packages available", "loading packages", and "activating packages".
From the docs, `(setq package-enable-at-startup nil)` doesn't "make installed packages available when Emacs starts". So, does "installed packages" here refer to packages found in `load-path`? Also, what does it mean for a package to be "available"? Such that `(require 'package)` will work?
Then, `(package-initialize)` will "load Emacs Lisp packages, and activate them". So what do "loading" and "activating" here mean? Does "loading" here mean the same thing as `(load FILE)`? Then "activating" means `(provide FEATURE)`?
I've tried reading [Elisp Packaging Section](https://www.gnu.org/software/emacs/manual/html_node/elisp/Packaging.html) but still couldn't understand
thetabit · 2022-03-04 01:52
package in emacs should be thought of as literally, the package manager, so if you disable the package-enable-at-startup, then the package manager is not starting and therefore the packages that are installed are no longer available. This is like an on off switch for the package manager in emacs
edit:
additionally, the enabling means that the system is now available for commands, where package-initialize is one such command, which then executes the actually loading of the installed packages
edit2: provide feature is the last command of a package, and when loaded, registers to emacs that this package is available to initialize
7890yuiop · 2022-03-04 02:12
* By default, Emacs versions 24, 25, and 26 will automatically call `(package-initialize)` *after* processing your init file.
* Consequently, if your init file tries to do anything with packages, it must explicitly call `(package-initialize)` first.
* But if you do that, then ideally you should also tell Emacs *not* to call it *again* after processing your init file (this would generally be harmless, but wasteful).
That's what those lines do. See also: https://stackoverflow.com/questions/11127109/emacs-24-package-system-initialization-problems
This changed in Emacs 27 which now calls `package-initialize` *before* processing your init file, so if you are using 27+ then most likely you do not want either of those lines of code. (Or if you *do* still want to disable `package-enable-at-startup` in 27+ you must now do so in an `early-init.el` file.)
See https://git.savannah.gnu.org/cgit/emacs.git/tree/etc/NEWS.27?id=19dcb237b5b02b36580294ab309124f346a66024#n212
----
As for what `package-initialize` *does*, the important things are:
* It updates `load-path`
* It updates `Info-directory-list`
* It `load`s the `*-autoload.el` files
zacque0 · 2022-03-04 02:19
> if you disable the package-enable-at-startup, then the package manager is not starting and therefore the packages that are installed are no longer available.
Hmm... does it mean disabling `package-enable-at-startup` has the same effect as invoking `emacs -q` from shell?
> the enabling means that the system is now available for commands, where package-initialize is one such command
Can you please clarify what do you mean by "available for commands"?
Erm, since `package-initialize` is an autoloaded command found in the built-in libraries, do you mean that by `(setq package-enable-at-startup t)` I can now invoke those autoloaded commands defined in the built-in libraries? And so, if `(setq package-enable-startup nil)`, I couldn't do that?
> when loaded, registers to emacs that this package is available to initialize
Erm, if you read my question again, I don't really know what do you mean by "loading a package". Here you introduce a new terminology again---"initialize a package". So, what does it mean to "initalize a package"? You meant `(require FEATURE)`?
karthink · 2022-03-04 02:33
Glossary:
- `package`: One or more elisp files that provide features/functionality. Also called a library if it's included in Emacs.
- `package`: Also the library that Emacs uses for package management. `package.el` is the name of the file, `package` is the feature it provides. (Thus all package management functions/vars begin with `package-`.)
- "activating a package": Load the autoloads for the package in question. This makes (some) interactive commands from that package available for calling, and lets Emacs know where to find the full elisp file(s) for this package. This action is _cheap_ in terms of time and memory.
- "loading a package": Load all the elisp files corresponding to a package. This action is _expensive_. You need to do this to actually use it.
- "package available": It's on the load path and the autoloads for this package have been loaded. You can load the full package using `require`.
- "package installed": Emacs has marked the package as installed, typically by adding an entry to the variable `package-selected-packages` in your custom file. If you installed it during this session, it has also been made available (see previous).
- `package-initialize`: Function that activates your installed packages (see previous and third point). Does some extra things besides.
- `package-enable-at-startup`: If this boolean is true, then packages are initialized (same as activated, see previous) at startup. This happens before loading your init file as of 27.2. If it's false, packages will not be initialized (same as activated).
- `load`: Function to load any elisp file, not necesarily a library/package. Load, run and execute are the same in this context.
- `provide`: Function that "registers" a file as a library/package.
- `require`: Similar to `load`, but register the library/package in the list of currently available features (a list called `features`). Unlike `load`, will not reload already loaded packages.
So the sequence of things that happen is:
`install` -> `activate` or `initialize` -> `load` or `require` -> use.
Someone will correct me if I got some minutiae wrong, but this is the basic picture.
zacque0 · 2022-03-04 02:40
Thanks, so from my understanding, for Emacs versions 24, 25, and 26, you need to call `(package-initialize)` before doing anything with packages. If you don't do anything with packages, you can leave it out.
In Emacs version 27, the installed packages are now activated **before** loading the init file. Since that has the same effect as calling `(package-initialize)` before loading the init file, you don't need to call `(package-initialize)` even if you're doing anything with packages in your init file, unless you disable `package-enable-at-startup`. It means that, in Emacs version 27, if you disable `package-enable-at-startup`, you need to call `(package-initialize)` explicitly by your own. And if you don't set `package-enable-at-startup`, you can forget about invoking `(package-initialize)`.
thetabit · 2022-03-04 02:45
No problem at all, I completely understand what you are saying, it took me a long time to piece this information together myself.
First things first, I find that looking up the words in a dictionary is a great place to learn literal/philosophical meanings. There is so much jargon in all of our technology that is folded into basic concepts, its great to look at the literal definitions in the dictionary and analyze specifically the differences and similarities between the words. If you can focus that information towards the context of emacs you'll begin to see what emacs actually is. Anyway, look up the words initialize and instantiate, you'll notice that there is a difference between these two concepts. Initialize is like something has come to life, where instantiate means that a "thing" has manifested before your very eyes. In these terms, something must first be available before it can come to life. ;)
7890yuiop · 2022-03-04 02:52
All correct.
zacque0 · 2022-03-04 05:35
Thanks, that helps a lot. To make sure I fully understand, I'll put it into my own words.
> install -> activate or initialize -> load or require -> use.
A package is one/more Elisp files providing a coherent set of features. There is also a built-in package called `package` (as defined by the `package.el` file) that is responsible for managing Emacs packages. In particular, it enables the users to `install`/`update`/`delete` packages.
By installing a package, `package` will download the Elisp files through the web to your local file system. Behind the scene, `package` adds that installed path to `load-path` and the package "name" to `package-selected-packages` variable in custom file. Packages installed in the current session will automatically be made available. (Note: Users can manually install a package by downloading it through other means, then add its path to `load-path` in their respective configs.)
A package is available when it's on the `load-path` and is activated/initialized. By initialized, it means that all the autoloads inside a package are loaded. Usually (depending on the value of `package-enable-at-startup`), this initialisation stage is performed by invoking `package-initialize`(either implicitly or explicitly) during Emacs startup.
After a package is made available, it's now ready to be loaded either by `load`-ing or `require`-ing it. By loading, it means that all the definitions are instantiated. All the Elisp files (either *.el or *.elc) will be evaluated. Both `load` and `require` are similar but `require` will only load the package once.[note 1]
Once a package is loaded, all the variables and definitions can be used in your code, just like those you defined by your own.
[note 1]: It achieves this by keeping a list of `feature` in a variable called `features`. Whenever `(require FEATURE)` is invoked, it will check `FEATURE` against that list of features. If `FEATURE` is found in the that list, it'll skip `load`-ing the file. Otherwise, it'll `load` the file and add `FEATURE` to that list.
zacque0 · 2022-03-04 05:41
Question: How to `initialize` a package manually? E.g. in a running Emacs session, I add a package path to `load-path`. Then what can I do to `initialize` it? Or do I simply `load`/`require` it directly?
zacque0 · 2022-03-04 05:49
> First things first, I find that looking up the words in a dictionary is a great place to learn literal/philosophical meanings. There is so much jargon in all of our technology that is folded into basic concepts, its great to look at the literal definitions in the dictionary and analyze specifically the differences and similarities between the words.
Thanks! That's an unexpected but interesting philosophical/artistic take on the problem. I appreciate it a lot.
> If you can focus that information towards the context of emacs you'll begin to see what emacs actually is.
Indeed I'm in the process of understanding and appreciating what Emacs actually is and what Emacs can be.
karthink · 2022-03-04 06:55
You have to add it to the load path and generate an autoloads file for the package (`make-autoload` or `make-directory-autoloads`). If the file is in the load path and named autoloads.el I think it gets initialized automatically, otherwise you have to manually load the autoload files.
There's some other stuff too, like updating Info paths, but that's not necessary.
EDIT: Take a look at `package-activate-1` to see how packages are initialized.
zacque0 · 2022-03-04 22:33
Thanks! That's a good place to start :D