Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Move parts or all of the core into plugins #23

Closed
giddie opened this Issue · 63 comments

6 participants

@giddie

I'd like to suggest that the "utility" functions be moved into a plugin, so that it's not mandatory to have those functions in the namespace. I tend to either write my own set of utility functions or write proper scripts as needed. The built-in utilities are interesting to read for reference, but I don't think I'd ever actually remember to use them.

@sorin-ionescu

The only way to remember those utility functions, both in utility.zsh and the ones in the functions directory is to use them. You still won't remember them if they are moved into a plugin if you don't use them.

@giddie

Yes, absolutely. I don't think I expressed myself very well. Basically, I'm porting my setup to your fork, and I will be removing / disabling utility.zsh, because I'm pretty confident that:

1) None of those functions represent things that I would want to do regularly.
2) I'd probably be just as happy running through the required steps manually.
3) If I wouldn't, I'd probably throw together my own function or script to do the job in a matter of minutes anyway.

They just don't fulfill a core need for me, whereas the whole of the rest of OMZ provides core functionality, except for the plugins. It feels to me like the utilities shouldn't be mandatory, hence the suggestion to move them into a plugin.

@sorin-ionescu

You could say the same about alias.zsh. @nicoulaj suggested that aliases should be in a plugin as well. @robbyrussell would probably disagree because it needs to be amazingly simple to get going. Though, utility functions and plugins could be loaded by default in the zshrc template.

In any case, my fork is intended to be modified in place, not to be bloated with unused code. So, you can just delete what you don't want.

@sorin-ionescu
@giddie

Well, I've done some culling in aliash.zsh as well, but there are plenty of things in there that are pretty core (nocorrects and noglobs, etc...)

Yeah, I would do something similar to the archive plugin and have it loaded by default, but with an option to easily remove it from the zshrc. Never mind, though.

Thanks for the reminder to grep; I hadn't considered that some of the utilities might be used elsewhere.

@sorin-ionescu

I'm going to bring in @ColinHebert into this discussion.

@ColinHebert

I agree with @giddie, utilities shouldn't be "forced" for every user. Right now there is not many things in it, but if it's turned into a plugin, it could be a nice "omz-miscellaneous/functions" enabled by default (in the template) [to 'keep it simple'] and can be disabled easily (to have a faster OMZ).

I'm thinking about some functions that don't really deserve their own plugin, but should still be a part of OMZ, having utility changed into a plugin could be the way to add those functions (enabled by default).

Regarding alias.sh I think it has to be changed (and why not integrated in utility?). Right now there are many things in alias that aren't 'simple' aliases (the ls colouring system, setopt CORRECT, diff and wdiff), some of the aliases should be grouped (everything related to correct for example to easily disable entirely correct).

@sorin-ionescu

I doubt utility, alias, and the functions directory will be extended much beyond what they are now. Some sane defaults, especially for ls are necessary. Pull requests are welcome, but any change needs to respect the walls of text in #377.

@giddie

I made significant changes to alias in my fork, because I'm used to my own set of aliases. I'm not relishing the idea of merging these with upstream changes to the more "core" aliases in future. I agree that it would be a good idea to split core aliases from aliases that might cause more division in preference.

Everyone has their own aliases and functions for productivity; we probably should make it as easy as possible for people to modify these "shortcuts" for their own use, without them needing to grok the core alias stuff. Maybe there's even a niche for "shortcut themes"?

@ColinHebert

@giddie I think that if you need to create your own aliases, you should put them in another configuration file, such as .zlogin or .zshenv (be careful if you're a mac user).

It's the same thing with custom functions. I'm all for an OMZ with a lot of pre-written functions/plugins but when it starts to get too much about personal choices (color, what parameters are used by default with the alias, etc.), I think you should put your configuration out of OMZ itself.

I know that @sorin-ionescu made OMZ2 so you can modify things in place, but I really think that if you have customisations it should be done out of OMZ. It's easier to merge with upstream and your .dotfiles can handle your custom files.

For example in my .zlogin I currently have a block named aliases containing alias l='ls -la' because I'm used to my own version of l.

As .zlogin is loaded after .zshrc, my alias prevail.

@sorin-ionescu
@giddie

I modified my fork to load a local.zsh file, which is in .gitignore. That way, I can add stuff that I want to keep local to the machine. However, I run several Linux servers and occasionally have various VMs for testing and experimentation, and I like to have a familiar command-line on all of them. My usecase for OMZ has always included making my CLI easy to install and sync between multiple machines.

Having said all this, I've realised that most of my modifications to alias.zsh are largely cosmetic, and I have in fact placed most of my own aliases in separate plugins. I think this setup is fine, so you can ignore these ramblings :)

@sorin-ionescu
@ColinHebert

@sorin-ionescu indeed, maybe @giddie solution is better, having another .zsh file loaded instead of .zlogin/.zshenv like a .pre.zshrc and .post.zshrc (this really sounds like the preflight/postflight scripts) called from within the .zshrc file.

@giddie Your solution would be a bit better if you put your local.zsh in ~ and are able to version it as a part of a dotfiles project.


@sorin-ionescu I'm not sure that's a good idea to have multiple versions of OMZ2 everywhere with next to no history in common (if two different persons start their own branch and have their own commits id etc.), it would be a nightmare to do clean pull requests. That's why currently my master branch is still a copy of upstream/master. And most of my patches are created on master so I can easily push them here.

I always have an "alternative_master" branch, but this branch is everything but stable (lots of rebase, etc.) this is why I don't push it on github (and if I did I would certainly not push it under the name of master).

@sorin-ionescu
@ColinHebert

I think that we need custom files that aren't in OMZ. One of the most basic reason is consistency. If someone as an issue because he "customised" one file that he shouldn't have modified we (as developers) have no way to know what's wrong. Whereas if there are two "customisation files" that you can disable easily, the first step to find a bug would be "disable your custom files" and from there we would have all the exact same OMZ content.

Regarding the way a repository should be maintained I am not convinced that's the best solution either. I'll stick to my unstable local alternative-master and my git-rerere-fu for my theme.

@sorin-ionescu
@ColinHebert

I must say I don't really understand. Disabling two files loaded by a zshrc would need two modification (adding a # before the source) whereas disabling commits implies to handle each commit/possible conflicts, etc.

What I'm talking about is not against the licence, everybody is still free to do their modifications (and are responsible of any problem due to these modifications). I'm saying that we should limit the need of a modification of OMZ.

I'm talking for the "newbie" who wants some custom things (copied from an obscure blog somewhere). I don't want to see these users complaining everywhere because "they told me it's ok to modify directly OMZ" or opening issues because "it doesn't work" and it takes ages to figure out what is the issue (because they're not on the upstream version anymore, they have their custom stuff inside OMZ). You were talking about that in another issue, in @robbyrussell's repo, #zsh full of people complaining of OMZ not working. I can't even start to imagine what would be the result if everyone starts to do such modifications to the "OMZ-core".

Obviously for developers it's even encouraged to do such modifications (and push them later to upstream) but not for "everybody".

And yes, I think that we should give a way for those users to play around OMZ without touching the OMZ core or risking any border effect they couldn't know about, because let's face it they're new and just want to do some basic customisation.

It could be so much easier to have these pre/post "sandboxes", which once disabled allows us to say that the problem doesn't come from ZSH but from their code.

@sorin-ionescu
@giddie

I'm not too bothered about pre and post files, or even getting my local.zsh tweak merged; most people will probably be happy dropping their local stuff in .zshrc, and that seems generally OK to me, although I personally prefer sourcing a separate file. I actually source local.zsh in .zshrc anyway. (It's a symlink to .oh-my-zsh/templates/zshrc.zsh on my setup.)

However, I'm still keen on moving the utilities into a plugin. By closing this, are you rejecting that proposal?

@sorin-ionescu
@giddie

I'm not talking about /functions and alias.zsh. I'm only talking about utility.zsh, which offers some convenience functions that are very much like those found in existing plugins, but unlike plugins there's no easy way to disable them when you don't want them. I don't think there's any way those convenience functions could be considered part of the "core".

@sorin-ionescu
@sorin-ionescu sorin-ionescu reopened this
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu

You might be getting your wish after all.

@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu

The zshrc is no longer compatible. That said, it feels slightly slower.

Current OMZ.

zsh -i -c 'exit'  0.44s user 0.22s system 111% cpu 0.590 total

Modularised OMZ

zsh -i -c 'exit'  0.43s user 0.23s system 104% cpu 0.632 total
@sorin-ionescu

You need to have something like bellow in zshrc to load the modules. This is subject to change.

zstyle ':omz:module' enable \
  'environment' \
  'terminal' \
  'keyboard' \
  'completion' \
  'history' \
  'directory' \
  'alias' \
  'spectrum' \
  'utility' \
  'archive' \
  'git' \
  'osx' \
  'perl' \
  'python' \
  'ruby' \
  'z' \
  'node' \
  'history-substring-search' \
  'gnu-utils'
@giddie

Huh; this is an interesting development. Well done for being willing to explore quite a major change!

Some initial thoughts: will things not break if one of the important modules is disabled? At first glance, this seems like it might be taking it a little too far: it becomes difficult to tell what is essential and what isn't. If you want everything as a module, I'd suggest having a disable list for core modules (for power users that don't want to just remove the file from git, I guess?), and keep optional plugins separate.

I don't know, though. I think it still makes sense to have a core that power users modify directly in git, with anything non-core in plugins. The core needs to setup the really essential stuff, and is pretty much always required. Things like aliases are not quite so essential, I guess. I wonder if some of the aliases should go in the .zshrc template, so that users can modify or add to them. Users can become pretty attached to their own aliases.

@giddie

I like the idea of the term "modules" instead of "plugins" though; that communicates an idea of them being first-class citizens, instead of an afterthought.

@ColinHebert

Yes OMZ can break if you don't provide the right modules. Right now @sorin-ionescu is working on a mini "dependency" declaration, which should simplify things.
I think that at some point there will be a "core" module depending on other important modules. (so if someone doesn't really like how the core module work, it will be easy to create a custom version of 'core' or a module that does the same thing)

Another detail is that some modules have to be loaded in a certain order. This too should be taken care of by a dependency system.

Regarding the aliases, I'm fine with the idea of keeping "common aliases" that almost everybody end up having (ie, ls aliases).

For any other alias they shouldn't be a part of any plugin (once again except if they're considered as "aliases that everybody use anyway") but instead be put in the .zshrc file.

@giddie

The dependency idea sounds good, so long as it doesn't slow things down too much. Won't having all this core stuff in separate modules make the source tree more complicated, though? I like the simplicity of having the core files right there together.

I agree with what you say about aliases that are currently in core. I don't think it's a problem for plugins (modules?) to define additional aliases, though (e.g. git). I'm not really sure how we could get around that anyway, other than maybe defining a mechanism for enabling or disabling aliases provided by a plugin. (That could be pretty cool, actually.)

@ColinHebert

The thing is, this could be a slippery slope toward a "real" dependency-management system with a lot of configuration. Maybe it could be a good thing but I don't think that's the best way to go right now, and probably not in directly in OMZ.

I can already smell the ideas of "OMZ-modules" repositories to automatically download specific versions of OMZ modules or different variants of these modules doing the same this except for a few aliases. I'm not saying that's a bad idea but it's really far from the idea of OMZ (keeping things simple).

Even the idea of dependencies (which we will actually if we use modules) is a big step in the "meta" world, because it means that we somehow have to give some meta definition of a module before it's even loaded.


Regarding the aliases, I've been recently on OMZ1 repo, and there are so many aliases defined with idiotic names (here someone created an alias named ett in a plugin for an editor to interact with ruby environments, if that isn't completely screwed up!).

I absolutely don't want to see that in OMZ2. Either the alias is commonly used or you should put it in your plugin documentation ("Hey look at the smart alias you could use") so people put it in their .zshrc.

Anything beyond that starts to be too complicated.

@giddie

Yes, I totally agree with what you have to say about aliases. I'm very wary of a polluted alias space. When I type alias, I want to be able to scroll through that list and think "Yes, I know what each one of those does." Some aliases really only make sense for personal use. For instance, I use gg for git status, which I find quick & easy to type, but I wouldn't say it's a "sensible" alias, so I wouldn't suggest it should be included. That's one of those that is personal to the user.

@sorin-ionescu
@giddie

Crossed wires :D I wasn't criticising your aliases; I've actually started using them instead of my own old ones because they make a lot of sense. Thank you for your work on them!

gg is my own alias that I've added to the default git aliases you've provided. What I'm saying is that I wouldn't impose gg on anyone else, because it's a rather obscure alias (not very descriptive). I was simply agreeing with @ColinHebert's point that some aliases simply shouldn't be accepted into OMZ, because they're too obscure to act as a standard. Those ones belong in .zshrc, and should never be accepted as part of a pull request.

@sorin-ionescu

I agree that now it's hard to spot what is essential and what is optional, but what is a core? My idea of a core is not your idea of a core.

However, there are a couple of ways to fix this.

  1. Have a wiki page that lists each module and what it does, for the user to know what to enable without reading the source code.
  2. Enable all essential modules that used to be the core in zshrc by default.
  3. Prefix all the essential modules with core- and have a core-all meta-module that loads all of them. This gives you the flexibility of either loading the entire core zstyle ':omz:module' enable 'core-all' 'archive' 'git' 'osx' or just parts zstyle ':omz:module' enable 'core-alias' 'core-utility' 'archive' 'git' 'osx'.
  4. Group all essential modules under a core directory in the modules directory. This gives you the flexibility of loading the entire core with zstyle ':omz:module' enable 'core' 'archive' 'git' 'osx' or just parts zstyle ':omz:module' enable 'core/alias' 'core/utility' 'archive' 'git' 'osx'. This may lead to the grouping of other modules, for example, package-managers/dpkg and package-managers/pacman.
  5. Add a core meta-module than in turn will load environment, terminal, keyboard, completion, history, directory, alias, spectrum, utility. This gives you the flexibility of loading the entire core with zstyle ':omz:module' enable 'core' 'archive' 'git' 'osx' or just parts zstyle ':omz:module' enable 'alias' 'utility' 'archive' 'git' 'osx'

There will be no dependency tracking system. The loading function works similarly to the C #ifdef MACRO. If a module is already loaded, it will return immediately, otherwise, it will load it. Modules can call the load function. For example, modules/git/alias.zsh requires compinit. At the top of the file, I can add omz-load-module 'completion'. If the user has added completion in zshrc, it will not be loaded twice, but if he hasn't, it will be loaded.

@ColinHebert

What is the difference between 3 and 5 (except the naming convention)?

@sorin-ionescu

There is no difference expect the naming convention, no prefixes. Again, my idea of a core may not be your idea of a core.

@giddie

I like 4 best, but I'm still not sold on the modular core. Could you maybe explain what your idea of core is then?

To me, core means something akin to a reset stylesheet for CSS: setting up a set of sane defaults, on which you can then begin to build your own environment. I see plugins (or modules) as pre-made building blocks for that environment. Some of them should be enabled by default, to allow new users to experience some default awesomeness beyond the core, but it should be possible to disable them. Anything that isn't already available in a plugin (e.g. custom aliases or functions), can just go in .zshrc.

That's what I'd like to see.

@sorin-ionescu
@giddie

Submodules? There will be submodules? I already have my reservations about the completions; I wouldn't want to see any more submodules.

Maybe my brain's not in gear today, but I'm not sure I follow what you're saying about 3 and 4. Why will they involve moving or renaming?

@sorin-ionescu

There are 3 submodules, only one is core: completion. The other submodules are zsh-history-substring-search and zsh-syntax-highlighting. If you don't think completion should be in the core, under 3, you'd rename 'core-completion' to 'completion', and under 4, you would move it out of the core directory.

@giddie

I don't really get what feature this adds. Completion is something that is almost always wanted. If it isn't, it's not unreasonable to remove it manually from a fork, because that would be so rare.

I reckon that utility, and some parts of alias and keyboard are what people will be interested in rewriting or disabling. Those bits shouldn't be in core, in my opinion. Everything else is really pretty essential, and even power-users are going to at most do some minor tweaking to the rest. I don't think anyone would ever want to remove anything else completely, although I could maybe see an argument for combining directory and history into an options file. I don't see any need to split these core things into separate modules; what use case does that cater to?

@ColinHebert

I like the idea of 3. It tells clearly what is considered as "essential". If you don't like the idea of the core used in 3, you can always create my-core with things that you think are really the core (you can, but this is somewhat pointless) or just manually set which modules you want to load.

I don't think that you need to rename these modules, except for the naming convention they're exactly the same as any modules. They're just named like this because they're considered as important.


I really don't like the idea of 4, because it means that if you want to create your custom core, either you modify the core module directly (and its content) or you have to create a new one from scratch where the solution 3 allows you to just modify the init.zsh of your core module to redefine its dependencies.


I have nothing against 5, even if I prefer the naming convention of 3 which will indicate to new users "don't mess with that module unless you know what you're doing." but in the end it's the same.

And for what it worth I think that 1 & 2 should be applied anyway

@meh

I really like 4 instead, grouping sounds like a good idea to me.

@ColinHebert if you want to create your custom core you can make a my-core directory with your changed core files or load core/whatever from your my-core, it sounds cleaner to me.

I agree with @ColinHebert about 1 and 2.

@sorin-ionescu

Most likely, it's going to be 1,2, 5.

@giddie

Usecase: A power-user discovers OMZ. He clones the repo and has a look at what's inside. He notices that there's not very much at all in the root directory, but loads of modules in separate directories. Unsure of what is actually getting loaded, he:

  • Follows the flow of execution through init.zsh.
  • Guesses that omodload is probably what loads the modules.
  • Looks it up in helpers.zsh.
  • Realises that the enabled modules are actually passed in as a parameter.
  • He looks in .zshrc to find enabled modules, notices `core'.
  • Looks in the core module.
  • Realises that it sources other modules.
  • Opens each relevant directory to find the init.zsh file with the relevant code.

This seems like it massively raises the barrier to entry and complicates the layout, and what do we gain? Seriously, noone wants to disable terminal or spectrum, and most of the rest will be built on, not completely rewritten or removed.

Regarding option 5, when it comes to modifying the modules, how is this better than just modifying the core files in the current OMZ layout? It's not significantly easier to remove a module, because in both situations you need to delete a source line (and optionally delete the unused files to clean up). In the modular layout, it's more difficult to find the relevant file in order to disable it, and modifying the files in-place is more difficult for the same reason.

Honestly, keep the core files in the root directory. It's so much cleaner. If you're keen on making it easy to disable one of them, add a blacklist to .zshrc that stops that file from being sourced.

@ColinHebert

@giddie One of the advantages of the modular core is that you can easily remove some parts of the core you don't like without having to actually modify the core.

I think we won't reach an agreement regarding what has to be in the core or not. @sorin-ionescu being the maintainer I'll give him the last word. I myself don't agree with utility and alias as being a part of the core. And you don't seem to like the idea of having utility in the core but keeping alias makes sense to you (unless I misunderstood).
Three persons three different opinions (and there is many more possibilities).

So instead of trying to find a solution there, on a subject that probably doesn't have a solution, creating modules for everything solve the original issue. With every module entirely independent (mostly, because there is some dependencies left) everybody can choose their own definition of what is loaded or not (but there will be a standard core defined by @sorin-ionescu).

The option 4 tends to add some difficulties because once again there is core module loading every "submodule" in it, so to create your own version of the "core" you would have to either copy/paste the old one (and every submodule) and modify it or you can do in place modification but I don't really consider that as a nice solution.


With the solution 5 (which as @sorin-ionescu said will be most likely the one used here) if you're not satisfied with the default settings (and a user who reach this step isn't really a newbie anymore) you can create a folder named "my-core", with one file "init.zsh" containing one line (the dependencies). Or if this doesn't suit you, you can manually declare each module from the zshrc.

In both cases it's a one line modification (actually two if you're using the init.zsh solution).


I think the best way to see that is by using the current issue-23 branch and create a "core" directory in modules, with a init.zsh file containing one line: omodload 'environment' 'terminal' 'keyboard' 'completion' 'history' 'directory' 'spectrum' 'alias' 'utility'

If you don't like this core, you just remove the 'utility' part and here you go.

Obviously don't forget to add core to your modules list :)


Regarding the blacklist, I think that's a really bad idea. I prefer to say what I want to load instead of saying what I don't want to load.

@giddie

@ColinHebert I think that some of 'alias.zsh' should be in core. In particular, ls colouring, some nocorrects and noglobs (only for standard system tools).

I take your point that we're not in agreement, but I'm not sure the solution is to try to please everyone by making OMZ completely modular at the cost of simplicity. We can maintain our own forks, after all. I've already removed utility.zsh and modified alias.zsh in my fork, and I'm OK with that solution for my own needs. My interest is in making this a better tool for everyone.

The idea of creating a my-core directory is not appealing to me. It feels like a hack. What if a new file is added to the core module in future, and you miss it because git does a trivial merge? If you edit the core in-place, you're far more likely to notice the change when you merge it. I also don't like these core files being hidden away in a subdirectory (2 levels deep, in fact). That's something that immediately struck me as better about OMZ-Sorin: in OMZ1, the core files are in /lib. With the files in the root, they're more discoverable, and more hackable.

@ColinHebert

I think you misinterpreted what the solution 4 and 5 do.

The solution 4 would imply the duplication of the old core and by so would create the situation of the missing new file, etc.

The solution 5 implies to create a my-core directory containing one file which says "actually if you want to load this module, what you really want is loading these modules", nothing more. So if core modules get updated you use this updated version automagically (because you're pointing to the same module).


I'll concede you the "hidden" part, but if everything (or mostly everything) goes in modules, there are not so many places to look. And one of the reasons I like solution 3, is that if also fixes the problem of not finding what are the core modules, because they're named "core-XXX".

@sorin-ionescu

Discoverability is fixed by documentation.

Don't create your own core meta-modules. Edit core/init.zsh in place to load what you want. Or, if you like verbosity, ignore core and load everything in zshrc.

This is modules/core/init.zsh.

omz-load-module \
  'environment' \
  'terminal' \
  'keyboard' \
  'completion' \
  'history' \
  'directory' \
  'spectrum' \
  'alias' \
  'utility'
@giddie

@ColinHebert In 3, 4, and 5, if you create a new directory, you have to maintain a fresh list of which core modules will get loaded. What happens when one of the core modules is renamed, or a new one is added, or they're generally rearranged? Your setup breaks without any merge conflict. I think the current system is safer.

@sorin-ionescu You make a good point about editing the core module in-place. That would be OK, but I don't see how this is an improvement over the current situation. It is in fact more obscure, because the list is more hidden.

If utility, alias, and keyboard are pared down to the essentials, and the convenience stuff is moved into a plugin, I don't think anyone is likely to want to remove any of the core. It's not something that would be useful, and it would just make it more difficult for devs to update the core. I would in fact prefer to keep everything as it is and make those modifications in my own fork, rather than go with the modular approach.

@sorin-ionescu I don't buy that discoverability is fixed by documentation. To me, that sounds like papering over a usability issue. Both are necessary. In this instance, I don't see how the loss in usability provides a significant gain in functionality.

@ColinHebert

@giddie If one module is renamed it will blow up because when you start your shell one module can't be found (the renamed one).
If a new one is added, and you created your own core, it means that you're on your own. You will have the exact same behaviour as before. If someone create his own core, he is responsible for it, I don't see any issue with that. If you want to, you can do in place modifications, but it's not the way I recommend (but this is not really the issue here).


Regarding the hidden part, not being in the root doesn't mean you can't find it anymore. The root will only contain the loading system, everything else is in modules. There is no more to that. It's like saying "I can't find my personal files because they're not in the root of my system"; it's not because there is a hierarchy (which is pretty clear) that nobody will know where to find things. I would even argue that it's exactly the opposite.


I really don't get the last point. What do you mean? If you're used to the old structure, of course it will be easier for you to find the things you were looking for. But having something different doesn't mean that's more complicated than before. And if someone could read the code before, he will be able to continue to do that (seriously nothing changes except for some files moving into folders). It's not a loss in usability, it's just different (barely).

What it brings is more flexibility, as you can load only what you want using the same system for everything ("core modules or classic modules"), it's more consistent. Instead of having some files sourced in init.zsh, they're declared like every other modules in the zshrc. I don't get how this is a loss in usability or readability.

@giddie

@ColinHebert The situation currently is that you can remove or edit files in core, and if a new one is added, or an old one is renamed, it'll crop up in the merge, and you'll either get the new file that is sourced automatically, or a merge conflict. This seems more straight-forward and safer, to me. Anyway, as @sorin-ionescu already mentioned, it would be possible to modify the core in-place, and I'm more OK with that, so maybe this is more of a personal preference thing.


I didn't say the file couldn't be found any more, I said that it was more difficult to find. The current layout has all the relevant files right there when you open the repository. The ones you want to look at are in front of you, straight away. After that, you can maybe start to explore what plugins are available etc... The module system mixes core with plugins, and you end up not really being sure what's loaded by default and what isn't without expending quite some effort. You can't assume that people are going to read the documentation carefully or discover templates/zshrc.zsh before diving in, and they might just be checking out the Github repo to see what the fuss is about.

The problem isn't so much that there's a hierarchy (although I do think it's superfluous), it's that the hierarchy mixes the "important" stuff with the "optional" stuff in a gratuitous way.


In my view, the loss of usability is caused by the mixing of core and plugins to the point where everything is lumped into a big nondescript pool together, and you're left wondering what's important and what isn't. People didn't need to follow the flow of execution previously to figure out which files were loaded; it was obvious that the files in the root are important. Less time grokking init.zsh means more time checking out the code that matters. I know that if I load all the .zsh files in the root, that's pretty much all the important stuff in OMZ. That's not possible with the module layout. I don't think most people that want to tweak OMZ are interested in serious shell coding; they just want to see what it does and maybe tweak things here and there. The old layout made that easy.

I see that this idea is tempting because of the uniformity it adds to the implementation, but I don't think it's a win for the users; I really don't.

@ColinHebert

If a new user who doesn't know how it works and doesn't know how to use ZSH (we're talking about this kind of users right?) start to use that without reading the basic documentation it will never work (unless they're good enough to know that the zshrc in templates is what they will need).

If we're talking about entry level developers, reading the zshrc will be enough to understand that one of the loaded modules is core and this is a really nice hint regarding where the "important stuff" can be.

And I'm quoting the "important stuff" part because once again, as @sorin-ionescu said, it really depends on what you want to do. If you just want to have the completion you can just load the completion. There is not really any module more important than any other. There is just these modules that were the core of OMZ before which can now be loaded with the "core" meta-module but if you only want aliases, you can go ahead and load only aliases.

The thing is, OMZ with the current layout gives more importance to some parts that they actually need, and this was why you opened this issue in the first place. In your configuration utility didn't have its place in the "core" part of OMZ. But it was only for your case. @sorin-ionescu disagreed with that in the first place, because in his configuration utility are a part of the "must have" of OMZ.

Now this modularity solves this situation because in the end there are no parts "more important" than any other, it only depends on what you intend to do.

@sorin-ionescu
@giddie

Oh man, we're just not going to agree on this, are we?

What makes OMZ great is that it provides a simple framework for tweaking aliases, functions, keyboard bindings, environment variables, options, etc... I want to be able to tweak these things, but I don't see why anyone would want to disable them. What would be the point? There's always going to be a replacement. If I disable alias.zsh, it's almost certainly because I want to use my own set of basic aliases, and where will I put those? Why not just replace the ones in the original alias.zsh? The same goes for all the basic core files, pretty much. OMZ provides a great set of categories for the basic configuration of ZSH. Why would I want to disable any of it? (I think utility is a special case, because it doesn't contain anything to do with basic configuration.)

In setting up my OMZ, I always have in the back of my mind: "Could someone else clone my fork and make this their own?". That way, I can set friends up with my OMZ setup without too much stuff that's unique to me. That's why I tweak basic stuff in OMZ, and keep things unique to me either in .zshrc (or local.zsh in my setup), or in a plugin. For instance, I have added correct_all to my alias.zsh, because I like ZSH to correct command arguments, but I've placed correct dvorak in my local.zsh, because I know that I'm unusual for using a Dvorak keyboard layout. My intention is, as I've mentioned before, to have something akin to a CSS reset, with some ready-made bits of awesomeness ready to throw in if I want them. That's what a framework should be.

The idea of modules breaks down this utopia for me. Categories of configuration disappear into a mire of plugins.

Maybe I'm not articulating it well, and maybe I haven't even completely figured out what upsets me about this so much, but as stupid as it sounds, it really doesn't smell right to me.

@sorin-ionescu

@giddie,

You are myopic by your own use case and ignoring others. I was as well. You are
asking, 'Why this?' and 'Why that?' I have asked those questions myself. I do not
know why. People's brains are wired differently. I have had private whining about
different parts of the core for months.

You are advocating convention over configuration, which works until it doesn't, at
which point it becomes a nightmare. It's short term profit over long term benefit.

Instead of asking why would someone want to disable it, whatever it may be, ask why
would someone want to enable it.

There is no real separation between configuration, utility functions, and aliases for
a particular tool or use case. Some plugins are configuration because they change the
environment. Perl, Python, and Ruby are a good example.

What is a plugin to you or me may be essential to someone else. dpkg is essential
to a Debian user. pacman is essential to an Arch Linux user. rails is essential
to a Rails user.

A modular approach is superior.

@stephenmckinney

I really like direction of branch issue-23. The configuration is explicit and code is much more browsable. You can take one look at .zshrc and follow what module you're including. Also customizing a "core module" is now just as easier as customizing a plugin. Each module becomes a first class citizen, while still being opinionated with the core meta module: +1 for 1, 2, 5.

Personally I'd favor a well written README explaining modules rather than a wiki, since the README can be tracked along with the code. That way it's easy to see what code introduced what changes in usage. But that's all a matter of personal taste.

@sorin-ionescu

@poorlilrichboy Yes, documentation is lacking. @ColinHebert has written a README for tmux and is in the process of writing one for git. I'd appreciate if people would write documentation for the plugins they use. It frees me to focus on the code and in-code documentation for contributors.

@giddie

OK, I concede defeat. I'm not happy, but maybe it'll grow on me.

@jedahan

Is ls ~/.oh-my-zsh more transparent than cat ~/.oh-my-zsh/modules/core/init.zsh? I agree with @giddie that adding this layer of abstraction does make OMZ more complicated, but the benefits seem to outweigh the negatives:

+ Modularization benefits power users by making core modifications simple and safe.
= Any user who only modifies ~/.zshrc should be unaffected.
- It is harder for new contributors to know what they can depend upon when developing modules

Putting core in the same list as other modules indicates that module authors cannot depend on anything loaded by core. This should be included in the appropriate documentation, either under contributing or module authoring.

There is a chance this is already the case, or that core will eventually be so small that no sane module would require any functionality defined in core. In that case any documentation would not need to be as explicit, and could just describe modules as vanilla zsh scripts.

@sorin-ionescu

@jedahan, the idea behind core is not to provide features, but to act as a meta-module to turn the following

zstyle ':omz:load' omodule \
  'environment' \
  'terminal' \
  'keyboard' \
  'completion' \
  'history' \
  'directory' \
  'spectrum' \
  'alias' \
  'utility' \
  'archive' \
  'git'

into

zstyle ':omz:load' omodule \
  'core' \
  'archive' \
  'git'

Perhaps not having core and being more explicit about what is being loaded is not such a bad thing because my idea of a core may not your idea of a core, and it clearly isn't with some people.

@jedahan

Perhaps I was not explicit in my last comment - the current implementation being pursued for core as a meta-module is a good compromise for users, power users, and contributors. It allows those who disagree with what your idea of a core to modify it easily, while making regular users happy with a simple and safe default config. In fact having the core abstracted away from normal users is an extra layer of safety - they do not have to worry about module loading order, except 'core first'.

In short, I prefer core implemented as it is in this branch for the reasons listed above. My discussion point regarding documentation is outside the scope of this issue and muddled the message of '+1'.

I appreciate the time you have taken to provide clear and explicit responses.

@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu closed this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@sorin-ionescu sorin-ionescu referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Rename plugins to modules 383b9ff
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Convert utility into a module c41bac8
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Convert alias into a module d44b479
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Convert spectrum into a module e0b8612
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Convert directory into a module e8bbf8f
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Convert history into a module b9bf2b9
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Convert completion into a module d3ace13
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Convert editor into a module 8421a36
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Convert terminal into a module aaa1c53
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Convert environment into a module 7509528
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Add a module loading function 99d09ac
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Rename keymap indicator zstyles b159b49
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [#23] Remove unnecessary compdef calls 09b9a48
@lildude lildude referenced this issue from a commit in lildude/prezto
@sorin-ionescu [Fix #23] Ensure dependencies are loaded 5119c3d
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23: Add github gem completion 80dc170
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: github is aliased to gh too 7a24c5f
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: remove unused variables ac42847
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: rewrite using arguments (properly sets context and allow …
…extension)
307ce5a
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: prepare completion of subcommands 3c3b9f6
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'browse' command 8603aea
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'clone' command 7dd0aac
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'config' command ba5e2cc
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'create' command 626ee84
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'create-from-local' command d38b8a2
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'fork' command c501c18
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'ignore' command 335ff28
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'issues' command d1c1be3
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'network' command 4e117ea
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'open' command faa9a91
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'pull' command beef59c
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'pull-request' command 6fd7fee
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'search' command 8ce3432
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete 'track' command 7224ce9
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: add license header 14e4055
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete networks commits 85451a7
@jeffcox jeffcox referenced this issue from a commit in jeffcox/prezto
@nicoulaj nicoulaj #23 github: complete users using _users too 022f30b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.