sorin-ionescu / prezto

The configuration framework for Zsh
MIT License
13.99k stars 4.49k forks source link

Change the way Prezto configuration is done #253

Closed ColinHebert closed 12 years ago

ColinHebert commented 12 years ago

Recently (in #250) a user did some configuration for Prezto in the zshrc file. Specifically in the Customize to your needs section.

Unfortunately, this section is executed after Prezto has been initialised, meaning that any customisation done there won't impact Prezto at all.

There are a few ways to fix that (some of them are really bad):

Create a second zshrc like file with some prezto configuration (customisation) loaded by zshrc before sourcing init.zsh I don't like this idea, because having a prezto configuration split in two files doesn't make sense and create more confusion than anything.

Create a second zshrc like file containing the actual customisation, loaded after prezto has been initialised Again not really a good solution. I think the zshrc file should always be customisable.

Add a new section Prezto customisation before the initialisation of prezto This would work, I don't think that's the best way to fix the problem, even if having a section just for that will clearly solve the initial problem.

Create a ~/.preztorc file This is really close the the first solution, but a bit more extreme, everything related to prezto is moved in another file. It is by far my favourite solution, the file name should be changed, or we should maybe have the prezto project in .prezto.d and the configuration in .prezto; anyway, this would make a clear separation between prezto and "other custom configurations for zsh".

If the .prezto config file is loaded by init.zsh then the only thing left to do is change .zshrc to init prezto, and voilà!

Currently the configuration file I use for prezto contains about 40 lines (including comments), maybe a separate file seems to be sensible, and it would allow us to put examples of configuration (commented) for some modules without polluting the .zshrc file.

The down-side of this solution is that you have now more files to maintain, but as I said, maybe Prezto could benefit from not being to tied to the main ZSH configuration file.


Obviously none of these solutions cause any backward compatibility issue, previous users won't see any difference, and new users should benefit from the advantage of a clean separation for the configuration.

swsnr commented 12 years ago

@ColinHebert I'm dislike the idea of another, separate file for prezto configuration, for the following reasons:

Confusion of users I doubt that adding another configuration file is going to help people who are already confused by the various configuration files of Zsh itself and the proper order of options in these files. It might just as well only increase confusion among users and actually lead to more errors due to misplaced configuration options. The more, since .zshrc will seem to have no apparent use for some users, because if all prezto options are moved to a separate file, .zshrc will only contain a single line to load prezto.

.zshrc is .preztorc I think that .zshrc is .preztorc really if prezto is being used. I doubt that .zshrc contains anything else than prezto options for most prezto users, and imho this is really how it should look like if prezto is used: Just prezto configuration and prezto loading. Anything beyond that should be moved into a custom prezto module. @sorin-ionescu has repeatedly stated that prezto is intended for in-place modification. Hence, putting as much as possible into prezto modules seems to be the really intended way to keep .zshrc uncluttered. This would also allow for configuration to be contributed to prezto itself for the profit of all users.

Where is the problem, actually? Generally I fail to see the problem you're trying to solve. #250 is the only case I'm aware of in which an error was introduced by screwing up the order of options in .zshrc. I'd consider it obvious actually that prezto options must be set before prezto is loaded, and apparently most users do so to, or the tracker of this project would have much more issues like #250. Also, the provided .zshrc template places prezto options before prezto loading, and so already suggests that prezto options have to be placed first. If anything is to be done, adding comment explaining this to the .zshrc template should really be sufficient. After all, users can be expected to read documentation.

ColinHebert commented 12 years ago

Confusion for users The point of this is to get prezto out of zshrc which is often use for other things than just prezto. Yes, zshrc could only contain one line loading prezto. What is the problem with that? That will make prezto easier to disable (just comment that one line) if there is any problem. That makes prezto less invasive; if I want to add some custom config later, I can do that easily without having to look through the prezto config to check where exactly I should put my custom code.

.zshrc is .preztorc It's basically the same argument you used in the first paragraph, yes .zshrc could only contain a line to load prezto. But if you have some custom configuration (aliases and functions very specific to the user, code to run when the shell started, additional zstyle settings, configuration for one specific server/machine etc.) you may not want to share or have in a module because not everything should be in a prezto module, or even under version control, because it's not a part of "prezto" but a specific configuration for only one specific machine.

I can appreciate that you really like prezto and want absolutely everything handled by prezto, but I think that prezto is a tool useful to load "community modules" and shouldn't go too far beyond that, and especially shouldn't have a "custom things" module where I would put my configuration for my serverY which shouldn't be used on serverX or personnalMachineZ.

To me prezto is an addon for Zsh, and isn't (and shouldn't) be too invasive, especially shouldn't force the user to always use prezto.

Where is the problem, actually? Okay, I can understand that you see that as obvious, being a user of prezto/omz for a few months now (maybe more ?), but it isn't obvious for someone using zsh for the first time.

It's not like there is any indication saying "customisation of prezto goes here", "other customisation goes there". You were using the confusion of users as your first argument. I think that this is way more confusing that having two files, one saying "prezto-config" and the other one saying "zsh-config", even if the only thing your zsh config does for now is loading prezto.

And no, I don't think reading the default configuration should be enough to consider that a user knows how prezto works. Absolutely nothing says what the source part does, or even why it's there.

If anything is to be done, adding comment explaining this to the .zshrc template should really be sufficient Yes, as I said it would work, I'm just not sure that's wise. If there is a clear separation between the prezto configuration and "other configuration for zsh", it seems to be an obvious answer to have a separation made by configuration files, and not by comments in the ZSH configuration.

The big advantage of the .prezto file is that everything is set up there, and it's only about configuration. It doesn't load any other file or do anything weird, it's as simple as it could be.

haplesshero13 commented 12 years ago

I definitely agree with @ColinHebert that prezto could use a pre-defined and well-documented location(s) for custom config and environment, and for me especially, functions like prompt themes and other plugins. This allows people not to have to fork the code just to add something small like a prompt theme. I'm wondering if you've looked into that? It might be as simple as adding a /custom directory and adding it to the $fpath.

pbrisbin commented 12 years ago

FWIW (just throwing another end-user opinion in here), I agree with this:

"@sorin-ionescu has repeatedly stated that prezto is intended for in-place modification"

Personally I have no need to customize prezto and customize zsh. Prezto is my zsh customization and anything additional I want is done via my fork thereof.

To @haplesshero13 's point, prompt themes might be a special case and maybe they deserve their own consideration here?

I very much dislike yet-another-config file, personally. Though, to be fair, I wouldn't have to use it just because it's the direction you guys take on this.

ColinHebert commented 12 years ago

@haplesshero13 I do appreciate the support, unfortunately, I disagree with you on the reasons.

If you want to create a custom theme you can just add the prompt_yourtheme_setup in any directory accessible through fpath (same with functions). You talk about plugins, and I'm not sure that I follow you, if you have the notion of plugin (or module) then it should probably be a part of prezto.

@pbrisbin Yes, he said that (though I disagree with him on that point), it doesn't mean that prezto should be too invasive. Yes you like prezto, this is great I do too, and yes you are in the case where prezto is just the perfect match (you don't need more configuration) which is good for you too. But even if prezto is really nice, prezto is not ZSH, and I do think that prezto shouldn't completely take over zsh. Even if there are people for whom the prezto settings are enough.

You say you don't like a "yet another config file". It's not yet another config file, it's better than that, you said the prezto configuration was enough for you, that you didn't have to modify it at all (or some custom configuration)? Great, that mean that you won't have to bother at all with zshrc then, you can do all you want to do in this .prezto file. And if someday you decide to play more with zsh, you can simply do that by adding stuff to your .zshrc without having any impact on your prezto configuration.

pbrisbin commented 12 years ago

@ColinHebert I guess you missed my point. I'm not in a case where prezto is just the perfect match, my fork has my own module with aliases and functions and a prompt theme. I've also edited the git module (remember, git-info-fast) and I used to have to make modifications to some of the environment stuff (before that was moved out to a zshenv template).

My point is that this (current) method of in-place customization is what I'd vote for against any of your suggestions. I suppose additional documentation in the zshrc template is never a bad thing, though the current template makes things very clear for me.

swsnr commented 12 years ago

@ColinHebert Apparently we've different ways of using prezto and zsh :) I've more or less two aims for my shell configuration: I want my shell to be the same on all systems that I use, and I want a clean, understandable and maintainable configuration that gives me a comfortable, powerful shell without requiring too much effort.

prezto let's me reach these aims: By putting configuration into modules I can break down my configuration into small, understandable and maintainable pieces, clean of machine specific stuff. By making a habit of putting any configuration into a module, I'm forced to think about it with regards to what it should do, and where it really belongs, make it generic and maintainable, care for code quality, document it and so on.

Hence I go with @pbrisbin: To me prezto is not merely an addon, it is my configuration. And I like it this way. I'm glad that I “invaded” my Zsh, for I still remember the 1k LoC .zshrc mess I had before, where I'd waste hours of debugging totally unimportant things that I never really needed anyway ;)

It doesn't need to be a “perfect match”, because I can simply fork it, and edit it in place if needed. And as far as I've understood @sorin-ionescu that seems to be his aim with prezto.

I agree with you that the default template could need some improvements in its documentation and comments, clarifying the order of options and modules and the like. But I've the strong opinion that this project should expect its users to read documentation and code. If one doesn't understand what the source line does, he should read the documentation of source and the code of init.zsh. Zsh is not a tool for people not reading documentation and code, so neither is prezto.

@haplesshero13 I've looked into that, but I obviously fail to see what you have seen. Where's the problem with people forking prezto? The whole point of Github is forking and pulling changes from other people. And contributing back to upstream: If you've modifications to prezto, always consider if these are worth a pull request to have them merged into upstream. They might be useful to other people, too.

Prompt themes are a different thing, because these are just ordinary functions. No dedicated support in prezto is needed, you don't even need to fork the repository. Just put your theme into an arbitrary directory, and add this directory to $fpath at the beginning of your .zshrc. This isn't even related to prezto, it's how prompt themes have always worked right in Zsh itself. And yes, that's documented. Read the Zsh documentation, it's really useful.

ColinHebert commented 12 years ago

@lunaryorn I understand your use case, and I find it great that you can have prezto "clean of machine specific stuff". This is exactly my goal. To me prezto should be generic as possible (and this is one of the reasons why I'm not really a fan of inline modification, but this is another discussion).

But the question I ask here is "what happen if I need machine specific stuff", because sometimes it just works like that, I need some stuff specific for my machine, and to be honest I would like to put it in .zshrc because that's where it's supposed to be (do you agree with me so far ?).

What I propose here, is to split that in two, where you have your .prezto file which will always stay clean/generic and should never (ever ever) contain anything specific.

This is good because it shouldn't bother someone who currently only uses prezto. Sure there will be two configuration files, but if they only use prezto, they will never have to even look at .zshrc

And if for some reason someone does need some machine specific code (which shouldn't happen but technically it can and will happen) well, that person can just put that in .zshrc which contains nothing (yet) except the initialisation of prezto.


At the same time you keep prezto's configuration away from bad modifications that could happen in the zshrc file (#250 is in a way, one of those bad thing that could but shouldn't happen), and you avoid the possibility of a newbie mixing an already existing "1k LoC" configuration with the clean configuration of prezto.

Even better, your prezto configuration is auto-loaded. It is not your configuration file which will have to load prezto, now it's prezto which loads your configuration file (this is exactly how it should always work IMHO).

Your .prezto file only contains pure generic prezto configuration. Absolutely nothing more!


In the end (and this is why I am surprised to see so little support for this idea), if you only use prezto, it won't affect you at all except that you will now edit .prezto instead of .zshrc (which kind of make sense, because .zshrc is ZSH specific, not prezto specific) but if you need some customisation, well you can do it like everybody do (and should do if you need some customisation) by modifying your .zshrc (without breaking prezto).


Just to finish there is another advantage that people in favor to do inline modification will actually love (if you're in that kind of thing :P ).

Right now when you install prezto you have to run this:

for rcfile in ~/.oh-my-zsh/runcoms/z{shenv,shrc,login,logout}; do
    cp -f $rcfile ~/.$rcfile:t
done

This means that the .zshrc file is just copied into your HOME folder. With that .prezto file you could have one more line in the install process:

ln -s ~/.oh-my-zsh/runcoms/prezto ~/.prezto

So now your prezto configuration is under version control (and it should be), but it's under version control in the prezto project, which means that if for some reason the configuration is modified upstream (we had to do that when modules were introduced, and now that omz is rebranded as prezto) you will have to merge it (or even better it will merge itself without any issue). This means that when you do an update of prezto you are automatically alerted (if there is an issue) that the configuration file for prezto has been (or should be) modified.

swsnr commented 12 years ago

@ColinHebert Sorry, but no, I don't agree with you so far ;) See, if I'd allow machine-specific configuration in my Zsh configuration, I'd actually put these into prezto modules, in my own fork of prezto of course. I'd probably write a hostconfig module that loads host-specific files from .zsh.d/modules/hostconfig/hosts/${HOSTNAME}, or something the like of. I can see a number of advantages in this approach over just dumping such configuration in .zshrc:

This is exactly what I meant with that prezto forces me to think about my configuration, make it understandable, maintainable, clear, and of good quality, and so on.

I'd do this for other special situations, too. If I ever had to maintain a HP-UX server :scream:, I'd put its shell configuration into a separate module and not into a special .zshrc I'd only use on this server, or even worse, into my general .zshrc, guarded by ifs to keep it away from other systems.

That said, I also have to admit that you're getting me :) I agree that prezto loading its configuration itself instead of being provided with it by .zshrc is really preferable, and closer to how configuration files work in other programs, with in turn can really prevent confusion of users. Also, the ability to just link the prezto configuration file to the prezto fork and modify it in-place is nice, I didn't think of this.

And you're right, it would really not at all affect the way I'm using prezto right now, I can just continue as before. So I don't stand against ~/.preztorc anymore.

So, let's wait for @sorin-ionescu to jump in :)

ColinHebert commented 12 years ago

@lunaryorn I guess you're right to some extent for the modules for specific hosts, but I have some aliases that are specific enough to not deserve to be there or even being under version control.

Typically it will be an alias to read a specific file in a certain way (yay pre grepped content) or to scp a specific file from a specific server. Those aliases are most of the time temporary (I need them for one week or two depending on what I'm working one) and going through the steps of creating an actual module or going through every folder to quickly edit that config file is more a PITA than anything else.

I think you're right with the fact that the .zshrc file shouldn't contain if and tricks for each different machine, mostly because right now it contains the prezto configuration that should be (more or less) the same everywhere. But when you separate the configuration in two parts, you don't really have to keep your .zshrc generic (or under version control) for the sake of prezto (note, I'm not saying that it's always a good idea to have custom .zshrc everywhere, but it some cases it's just way easier).

sorin-ionescu commented 12 years ago

Prezto configuration is done in zshrc because it is a fork of Oh My Zsh, which has its configuration done in zshrc. Secondly, Prezto is interactive, and interactive configuration goes in zshrc. It has never crossed my mind to put it in a separate file.

People are already confused by the various runcoms used by Zsh, which are populated by Prezto, especially zshenv, not just zshrc. Adding yet another file, preztorc, must be carefully considered.

Like @lunaryorn, I have never thought of Prezto as an add-on. You may have not noticed, but Prezto is described as the configuration framework for Zsh, not a configuration framework for Zsh. The article change was deliberate. This further led me to choose zsh.d instead of prezto.d, akin to emacs.d, as the directory name in #197.

I can see, however, that in the case of Emacs, whatever configuration framework you choose, Emacs Starter Kit or Prelude, the configuration directory is still emacs.d; so, it's not easy to switch between frameworks.

I am inviting @skwp in this conversation since this will affect his YADR project.

swsnr commented 12 years ago

@ColinHebert I tend to write scripts and Makefiles in such situations, i.e. if I'm working on a specific project for some time or so.

But again, if I had to put such quick and dirty aliases into my shell configuration, I'd write a module (i.e. quickndirty ;) ) that sources a ~/.zshrc.dirty in a nifty way, accompanied by a function to quickly reload this file, and another function to quickly edit the file with $EDITOR (and probably an extension to editor to execute these functions on certain key presses). Again, understandable, maintainable, generic, and keeping .zshrc clean ;)

As said, I tend to structure my shell configuration around prezto, and let prezto do as much as possible, and I really like it so far.

sorin-ionescu commented 12 years ago

I see how preztorc and a source one liner in zshrc is compatible with the modules philosophy — use it if you like it; do not use it if you do not like it. It allows for adding and removing Prezto to an existing configuration with minimal friction. A variable storing the path to Prezto is still needed though. Right now, it's in zshenv, but Prezto's main init.zsh can define it on its own for even less friction.

pablox-cl commented 12 years ago

Being the one that filed #250, it would be enough for me to have a note in the Readme telling me that I should write zstyle configurations before prezto is loaded, at least for me that would solve the issue. I mean if I read "Customize to your needs" I understand that I have to write my stuff there.

Am I stupid? I don't think so. I'm using Prezto (zsh really) for the first time (I used to work on bash for years), I don't see why (or how) I'm supposed to know that they HAVE to go before.

sorin-ionescu commented 12 years ago

@haplesshero13 What you are trying to do with themes is not relevant to this issue. Put your theme in modules/prompt/functions. Please stay on topic.

sorin-ionescu commented 12 years ago

Would it be easier to browse the zshrc/preztorc if the zstyles were sorted alphabetically?

Comments removed.

zstyle ':prezto:*:*' case-sensitive 'no'
zstyle ':prezto:*:*' color 'yes'
zstyle ':prezto:load' pmodule 'environment' 'terminal'
zstyle ':prezto:load' zfunction 'zargs' 'zmv'
zstyle ':prezto:load' zmodule 'attr' 'stat'
zstyle ':prezto:module:editor' dot-expansion 'no'
zstyle ':prezto:module:editor' keymap 'emacs'
zstyle ':prezto:module:prompt' theme 'sorin'
zstyle ':prezto:module:terminal' auto-title 'yes'
sorin-ionescu commented 12 years ago

While we are on this subject, should this file contain all the zstyles from all the modules that come with Prezto instead of having people copy/paste from the README's to enable or disable functionality?

sorin-ionescu commented 12 years ago

Have a look https://github.com/sorin-ionescu/prezto/tree/issue-253.

ColinHebert commented 12 years ago

@sorin-ionescu that seems reasonable. I think there are some tiny mistakes (sometimes the folder is named .prezto, sometimes .prezto.d)

The installation process could be slightly modified to incorporate the a symlink to .preztorc instead of copying it.


I have two other objections (they're not really specific to this issue), they apply even more if we go (and we should) with a gist script to install everything.

The cp of config files should not be forced, if someone does that an important file could be erased, it would be better to copy every file one by one and explicitly show a red blinking ALERT if one copy failed.

Sometimes the config files are searched in $ZDOTDIR and some other times in $HOME (or ~), this should be consistent, either $ZDOTDIR or $HOME or the two of them every time (and we remove the $ZDOTDIR initialisation).

sorin-ionescu commented 12 years ago

@ColinHebert, stay on topic. You should cut that and paste in the installation script issue. I'll answer it there.

sorin-ionescu commented 12 years ago

Why should we use symbolic links instead of copying? It will cause merges to fail.

ColinHebert commented 12 years ago

That's the point, if a merge fail it means that a modification has been done on the original configuration that is in conflict with the current configuration. The main reasons for this kind of conflict (not solved automatically) are changes in modules/zstyle names, but it could also be something slightly different.

Doing that will force the user, when an upgrade is done, to check what went wrong during the merge and what's new in the configuration file.

sorin-ionescu commented 12 years ago

Here's an easy way to test this.

zsh -f -d
mkdir issue-253
cd issue-253
export ZDOTDIR="$PWD"
export PREZTO="$ZDOTDIR/.prezto.d"
git clone --branch issue-253 --recursive https://github.com/sorin-ionescu/prezto.git "$PREZTO"
setopt EXTENDED_GLOB
for rcfile in "$PREZTO"/runcoms/^README.md(.N); do
  ln -s "$rcfile" "$ZDOTDIR/.${rcfile:t}"
done
zsh -l

You should see.

$ ls -1A
.prezto.d/
.preztorc
.zcompdump
.zhistory
.zlogin
.zlogout
.zprofile
.zshenv
.zshrc
sorin-ionescu commented 12 years ago

I am not too fond of the naming scheme. It seems separate from Zsh. Maybe the Prezto stuff should also be prefixed with z.

ColinHebert commented 12 years ago

Wouldn't that be redundant? After all if preZto has a Z it's for Zsh.

One thing that could be changed would be .preztorc into .prezto (it's not a technical choice but an aesthetic one [for which I have no strong opinion])

sorin-ionescu commented 12 years ago

Nothing here is set in stone.

There has not been feedback from @lunaryorn and others yet.

sorin-ionescu commented 12 years ago

@lunaryorn, have you got anything more to say on this one?

swsnr commented 12 years ago

@sorin-ionescu Silent consent for my part :) I have no objections.

I'm not too fond of renaming the prezto directory again, but only because submodule renames are PITA. If we have .preztorc, we should definitely use .prezto.d/, too, to have a consistent naming scheme for prezto-related files and directories.

ColinHebert commented 12 years ago

@lunaryorn I'm not sure I understand, renaming the directory should not have any impact on anything, except the installation procedure.

sorin-ionescu commented 12 years ago

I only advise people to use the master branch; so, people whining that folders are getting renamed is not my concern.

@lunaryorn, actually, adding dot d to the directory name is a bad idea since .d directories are supposed to store configuration files that are combined, and Prezto has README and other files. I have never seen READMEs, for example, in /etc dot d directories.

swsnr commented 12 years ago

@ColinHebert You are right, of course. It's just that I'm using prezto as submodule of my dotfile repository. If prezto changes the directory, I have to rename the submodule, and that's not fun to do in Git :) But this is nothing of importance at all, as said I don't have any objections, and actually think that changing the directory is reasonable.

sorin-ionescu commented 12 years ago

I prefer consistency over anything else.

swsnr commented 12 years ago

@sorin-ionescu I don't care about a .d prefix, I just think that the directory should have prezto in its name, if we use .preztorc :) Given your examples, I'd vote for those on the lower row, because with these naming schemes ls -d .z* will catch all Zsh configuration. I don't mind whether you choose the one with .d suffix or without.

jjungnickel commented 12 years ago

Debian drops README in various *.d directories in /etc, albeit only into those where the files also have to adhere to a naming scheme.

Regarding to the four variants: I'm with the first since it clearly denotes that while zsh and prezto have a strong, one-sided relation the are two separate products.

sorin-ionescu commented 12 years ago

Debian does a lot of complicated stuff for no good reason.

jjungnickel commented 12 years ago

That aside, in the end there's no clear standard, so it's just a matter of style - and I'm fine with whatever you decide.