protesilaos / dotfiles

Configuration files for Emacs and some other programs. Running on Arch Linux. Managed with GNU Stow.
GNU General Public License v3.0
184 stars 18 forks source link

Question about the way you use customize #1

Closed dabrahams closed 9 months ago

dabrahams commented 1 year ago

Hi there; I'm exploring your dotfiles for inspiration as I go through my umpteenth everything-bankruptcy. I didn't know a better way to ask a question, so filed an issue. I notice you don't use custom-set-variables anywhere, for reasons I think I understand, but you also make extensive use of defcustom and defgroup. Would you mind taking a moment to explain your motivation and approach?

Thanks in advance!

protesilaos commented 1 year ago

Note that I am using the emacs-git package from the AUR. This means that I am on Emacs 30 which includes the setopt: its syntax is like setq except it uses custom-set internally.

I use setopt in some places and will eventually make it the norm across my files. Sometimes though, the :type of a defcustom is not correct and setopt will throw an exception, whereas setq will not. For those cases, I rely on the latter.

I use defcustom and defgroup for two reasons:

  1. For their intended purpose of exposing them to the Custom UI and relevant functions.
  2. To add semantics for those who read the source code. I personally find it easier to find a file's points of entry by grepping for defcustom than trying to guess which defvar is safe to modify.

Please let me know if this answers your questions and/or if you have any other questions.

protesilaos commented 1 year ago

Please note that my usage of defcustom and defgroup may not be as good as it is for my packages. For example, check the file modus-themes.el: https://github.com/protesilaos/modus-themes

dabrahams commented 1 year ago

Okay, that's a start; I guess I'm trying to understand how you deal with your own settings, given this:

;;; Make Custom UI code disposable
(prot-emacs-builtin-package 'cus-edit
  ;; Disable the damn thing
  (setq custom-file (make-temp-file "emacs-custom-")))

Do you never use the customize UI at all? Do you use it to explore and then pick things out of the temporary custom-file to encode in your official configuration?

I'm somewhat inclined to let the file persist locally, but put it in my .gitignore so it doesn't propagate to other machines; that way I can use it as a way to experiment with settings without losing them.

protesilaos commented 1 year ago

Do you never use the customize UI at all?

I use it for testing purposes, such as to make sure that the :type I create is correct. Otherwise no. I prefer to find customisation options by looking at their source code. For example, I start with M-x find-library and then will do M-x occur (or M-s o with the default keys) for defcustom. If it is a big package, I will run a directory-wide grep. The upside of this method is that I get to see the default value and how the variable is used, because sometimes the documentation string is not sufficiently informative.

Do you use it to explore and then pick things out of the temporary custom-file to encode in your official configuration?

The only reason I make the custom-file temporary is to enable commands like M-x list-packages. Without the custom-file, Emacs cannot know which packages it has installed and so operations like package-autoremove will not work as intended. I would prefer to send the custom-file to the null-device but it would break things.

I'm somewhat inclined to let the file persist locally

I stopped doing that after the Nth time I got confused by the state Emacs was in. Old configurations will linger in the custom-file even after a package has removed them. Over time, this creates incompatibilities. The way I have it now is that all customisations are declared/known at startup and there is no other source of truth.

What you describe has its advantages. Maybe I should configure this to make it easier for you to adapt it to your liking?

dabrahams commented 1 year ago

sometimes the documentation string is not sufficiently informative

Yes, people are bad at documentation

The only reason I make the custom-file temporary is to enable commands like M-x list-packages. Without the custom-file, Emacs cannot know which packages it has installed

Okay, now I'm quite confused. If package-selected-packages needs to be set in the file for package management to work, how can you afford to throw away the custom-file every time you quit emacs?

Maybe I should configure this to make it easier for you to adapt it to your liking?

Thanks, but while I'm using your config as inspiration, I'm not copying-and-modifying it. Yet. :-)

protesilaos commented 1 year ago

Okay, now I'm quite confused. If package-selected-packages needs to be set in the file for package management to work, how can you afford to throw away the custom-file every time you quit emacs?

Package management, like package-install and package-delete, works just fine. The command package-autoremove needs to read a list of packages, so it reads from the custom-file. Similarly, list-packages needs to write the installed packages there. I have no problem because if I plan to do an autoremove, I will list the packages anyway, at which point the temporary custom-file will be created.

When I close and restart Emacs, the configuration is produced by reading only my files. This way, I never get any surprises.

Thanks, but while I'm using your config as inspiration, I'm not copying-and-modifying it.

Very well! That is better and I have intentionally made mine less reproducible for this reason: I prefer that people get in the habit of reading the code they will end up using.

EDIT: fix typos.

dabrahams commented 1 year ago

I prefer that people get in the habit of reading the code they will end up using.

Well, I still believe in libraries and abstraction. But I also believe that if you're not vending your config as a library, I shouldn't treat it as one :-).

protesilaos commented 1 year ago

Nicely put!

dabrahams commented 1 year ago

the configuration is produced by reading only my files

Do you mean that package-install is called explicitly at startup, on all the packages you are using?

Thanks

dabrahams commented 9 months ago

Do you never use the customize UI at all?

I use it for testing purposes, such as to make sure that the :type I create is correct. Otherwise no. I prefer to find customisation options by looking at their source code. For example, I start with M-x find-library and then will do M-x occur (or M-s o with the default keys) for defcustom. If it is a big package, I will run a directory-wide grep. The upside of this method is that I get to see the default value and how the variable is used, because sometimes the documentation string is not sufficiently informative.

Then I wonder what you would do about this: there are several projects I visit often that want to do a whole bunch of directory-local configuration that emacs considers unsafe. I don't want those configurations and I don't want to be bothered about them either. If I accept emacs' prompt to "always ignore", it writes the ignored-local-variable-values into the custom file. I don't see ignored-local-variable-values in your dotfiles, so presumably you've never encountered this problem…?

protesilaos commented 9 months ago

From: Dave Abrahams @.***> Date: Fri, 12 Jan 2024 17:51:53 -0800

Do you never use the customize UI at all?

I use it for testing purposes, such as to make sure that the :type I create is correct. Otherwise no. I prefer to find customisation options by looking at their source code. For example, I start with M-x find-library and then will do M-x occur (or M-s o with the default keys) for defcustom. If it is a big package, I will run a directory-wide grep. The upside of this method is that I get to see the default value and how the variable is used, because sometimes the documentation string is not sufficiently informative.

Then I wonder what you would do about this: there are several projects I visit often that want to do a whole bunch of directory-local configuration that emacs considers unsafe. I don't want those configurations and I don't want to be bothered about them either. If I accept emacs' prompt to "always ignore", it writes the ignored-local-variable-values into the custom file. I don't see ignored-local-variable-values in your dotfiles, so presumably you've never encountered this problem…?

I normally reject all buffer-local variables. The ones I define myself are treated as safe with this:

(add-to-list 'safe-local-variable-values '(org-hide-leading-stars . t)) (add-to-list 'safe-local-variable-values '(org-hide-macro-markers . t))

-- Protesilaos Stavrou https://protesilaos.com

dabrahams commented 9 months ago

Sure, but:

protesilaos commented 9 months ago

From: Dave Abrahams @.***> Date: Tue, 16 Jan 2024 08:55:04 -0800

Sure, but:

  • do you really mean buffer-local? Or just directory-local?

Maybe this distinction is meaningful in this context, though in me experience I only get prompted when I have a file in a buffer.

  • do you reject them manually? Or is there a general setting I don't know about that will keep emacs from pestering me?

Yes, I do it manually. It is infrequent so it does not bother me. I am not aware of a setting to reject them for good. If the Custom UI does that, then you can find the variable it appends to its list and use it in your init.el.

-- Protesilaos Stavrou https://protesilaos.com