People seem to be missing the point that no conceivable package loading tool — use-package, general, straight, by-hand gnarly lisp using eval-after-load, etc., etc. — will solve the original problem as stated. You want a binding to appear, tying project to magit. That binding is specified at the top level in one of magit’s many lisp files. You want this binding to appear without loading magit. There is no approach which will accomplish this, other than excerpting that binding yourself, as you’ve done in the “clever/hacky” solution
Yes, agreed. My contention is not with the inherent complexity of the situation. Rather, my issue is related to this last part of your paragraph,
though I’d put it in the project :config stanza for better organization
That’s the whole problem with using use-package forms for configuration! use-package is centered around a single feature at a time, whereas many configurations involve tying multiple features together. In this case, it doesn’t matter if I put the configuration in project’s use-package form or in magit’s use-package form–in either case, one of the forms will be misleading because it will seem like all of the configurations related to that package is in that form, but it won’t be true because something about it is being configured in the other package’s form.
That’s not the only thing, either. Another example is completions. I use vertico and corfu, but they tie in closely with a lot of built-in Emacs completion stuff, so I have the following settings,
(customize-set-variable 'read-extended-command-predicate #'command-completion-default-include-p)
(setq completion-category-overrides '((file (styles partial-completion))))
(setq completion-styles '(flex basic))
those settings are not part of the vertico package, but they’re being set because I’m using vertico and want it to behave a certain way. So, do they go in the vertico use-package, or do they go in an emacs or simple.el use-package, or do they just go at the top level somewhere?
The truth is that we don’t actually configure packages in isolation, which is why I feel like use-package kind of imposes a structure that appears to make sense in a lot of cases, but does NOT actually make sense in the general case.
99% of the time, yes. As far as I know there are three “lifecycle hooks”: prelude, init, config. Prelude is evaluated when the use-package form is encountered no matter what (even if it’s :disabled, etc); then init is evaluated if the package is not disabled via :requires, :disabled, :if, etc; then config is essentially the same as
with-eval-after-load
.